Скрипты помогают найти команду через вывод времени в несколько файлов
Вот сценарий, который я написал, с которым мне нужна помощь. в скрипте я делаю поиск для любого файла, к которому не было доступа более 30 дней, 60, 90, 180, 270 и 365 дней.
Это работает просто отлично. однако для завершения 30-дневной части требуется несколько дней. это сканирование NAS. (миллионы и миллионы файлов), как вы видите, информация за 30 дней действительно содержит все данные, необходимые для остальных сценариев. часть скрипта 60, 90 и т. д. просто повторяет те же усилия, что и 30-дневная часть, за исключением продленного периода времени. в этом случае было бы сэкономлено несколько недель на повторное сканирование, если бы некоторые части 60, 90 180 и т. д. могли просто получить свои данные из 30-дневного вывода.
это где я прошу помощи. вывод аналогичен команде ls -l. и вы также можете видеть из результатов ниже, есть несколько лет в этом результате. скрипт прилагается и распечатывается ниже.
total 24
-rw-r--r-- 1 root bin 60 Apr 12 13:07 config_file
-rw-r--r-- 1 root bin 9 Apr 12 13:07 config_file.InProgress
-rw-r--r-- 1 root bin 0 Apr 12 13:07 config_file.sids
-rw-r--r-- 1 root bin 1284 Apr 19 10:41 rpt_file
-rw-r--r-- 1 16074 5003 20083 Apr 26 2002 /nas/quota/slot_2/CR_APP002/eb_ora_bin1/sun8/product/9.2s/oem_webstage/oracle/sysman/qtour/console/dat1_01.gif
-rw-r--r-- 1 16074 5003 20088 Apr 26 2002 /nas/quota/slot_2/CR_APP002/eb_ora_bin1/sun8/product/9.2s/oem_webstage/oracle/sysman/qtour/console/set1_04.gif
-rw-r--r-- 1 16074 5003 2008 Apr 26 2002 /nas/quota/slot_2/CR_APP002/eb_ora_bin1/sun8/product/9.2s/oem_webstage/oracle/sysman/qtour/oapps/get2_03.htm
-rw-r--r-- 1 16074 5003 20083 Apr 26 2002 /nas/quota/slot_2/CR_APP002/eb_ora_bin1/sun8/product/9.2s/oem_webstage/oracle/sysman/qtour/oapps/per1_01.gif
любая помощь приветствуется. Это дистрибутивы Linux, так что я уверен, что Perl там, если нужно..
#!/bin/ksh
############################################
# search shares for files #
# that have not been accessed #
# for a certain time. #
# NOTE: #
# $IN = input search #
# $OUT = output directory for text file #
##########################################################
# TESTS #
# Numeric arguments can be specified as #
# #
# +n for greater than n, #
# -n for less than n, #
# n for exactly n. #
# #
# -atime n #
# File was last accessed n*24 hours ago. #
# #
##########################################################
IN1=/nas/quota/slot_2/CR*
IN2=/nas/quota/slot_3/CR*
IN3=/nas/quota/slot_4/CR*
IN4=/nas/quota/slot_5/CR*
OUT=/nas/quota/slot_3/CR_PRJ144/steve
mkdir ${OUT}
for dir in ${IN1}; do find $dir -atime +30 -exec ls -l '{}' \; >>${OUT}/30days.txt; done
for dir in ${IN2}; do find $dir -atime +30 -exec ls -l '{}' \; >>${OUT}/30days.txt; done
for dir in ${IN3}; do find $dir -atime +30 -exec ls -l '{}' \; >>${OUT}/30days.txt; done
for dir in ${IN4}; do find $dir -atime +30 -exec ls -l '{}' \; >>${OUT}/30days.txt; done
for dir in ${IN1}; do find $dir -atime +60 -exec ls -l '{}' \; >>${OUT}/60days.txt; done
for dir in ${IN2}; do find $dir -atime +60 -exec ls -l '{}' \; >>${OUT}/60days.txt; done
for dir in ${IN3}; do find $dir -atime +60 -exec ls -l '{}' \; >>${OUT}/60days.txt; done
for dir in ${IN4}; do find $dir -atime +60 -exec ls -l '{}' \; >>${OUT}/60days.txt; done
for dir in ${IN1}; do find $dir -atime +90 -exec ls -l '{}' \; >>${OUT}/90days.txt; done
for dir in ${IN2}; do find $dir -atime +90 -exec ls -l '{}' \; >>${OUT}/90days.txt; done
for dir in ${IN3}; do find $dir -atime +90 -exec ls -l '{}' \; >>${OUT}/90days.txt; done
for dir in ${IN4}; do find $dir -atime +90 -exec ls -l '{}' \; >>${OUT}/90days.txt; done
for dir in ${IN1}; do find $dir -atime +180 -exec ls -l '{}' \; >>${OUT}/180days.txt; done
for dir in ${IN2}; do find $dir -atime +180 -exec ls -l '{}' \; >>${OUT}/180days.txt; done
for dir in ${IN3}; do find $dir -atime +180 -exec ls -l '{}' \; >>${OUT}/180days.txt; done
for dir in ${IN4}; do find $dir -atime +180 -exec ls -l '{}' \; >>${OUT}/180days.txt; done
for dir in ${IN1}; do find $dir -atime +270 -exec ls -l '{}' \; >>${OUT}/270days.txt; done
for dir in ${IN2}; do find $dir -atime +270 -exec ls -l '{}' \; >>${OUT}/270days.txt; done
for dir in ${IN3}; do find $dir -atime +270 -exec ls -l '{}' \; >>${OUT}/270days.txt; done
for dir in ${IN4}; do find $dir -atime +270 -exec ls -l '{}' \; >>${OUT}/270days.txt; done
for dir in ${IN1}; do find $dir -atime +365 -exec ls -l '{}' \; >>${OUT}/365days.txt; done
for dir in ${IN2}; do find $dir -atime +365 -exec ls -l '{}' \; >>${OUT}/365days.txt; done
for dir in ${IN3}; do find $dir -atime +365 -exec ls -l '{}' \; >>${OUT}/365days.txt; done
for dir in ${IN4}; do find $dir -atime +365 -exec ls -l '{}' \; >>${OUT}/365days.txt; done
3 ответа
Вам нужен фундаментальный редизайн. Вы должны выполнить команду find только один раз для всей системы и создать файл индекса, содержащий что-то вроде 'file: atime'. Вы можете сделать это с помощью -printf
аргумент для поиска, чтобы напечатать atime с именем файла (см. man find
). Затем вы можете выполнять свои операции на основе этого индекса. Причина в том, что самым большим штрафом будет указание каждого файла на диске, так что вы хотите сделать это только один раз. Это идея команд locate и updatedb в Linux. В основном вы хотите воссоздать те с добавлением atime.
Я также думаю, что цикл по ls - это дерьмо, вы, вероятно, хотите циклически проходить по индексу построчно с циклом while. Вам придется повторить истину тех времен в "х дней назад". Самый простой способ, вероятно, будет использовать эпоху. Таким образом, вы получите что-то вроде:
find ~/scrap -printf "%p:%A@%\n" > index;
while read -d':' name date; do
if ...between dates using $date...; then
do something to $name
fi
done < index
Если вы хотите вместо вышеупомянутого, у вас есть команда pipe к циклу while и вы перенаправляете в разные файлы на основе операторов if. Кроме того, имейте в виду: это плохой разделитель, если он может использоваться в имени файла.
Возможно, вы захотите сгенерировать индекс в SQL, если вы хотите стать более любопытным.
Есть несколько проблем со сценарием, которые заставляют его работать так медленно. Прежде всего, ваш цикл for не нужен в том виде, в котором он написан, поскольку каждая переменная имеет только одно значение, чтобы использовать его по своему усмотрению, вы бы изменили структуру на что-то вроде:
IN_PATH="
/nas/quota/slot_2/CR*
/nas/quota/slot_3/CR*
/nas/quota/slot_4/CR*
/nas/quota/slot_5/CR*
"
OUT=/nas/quota/slot_3/CR_PRJ144/steve
mkdir ${OUT}
for dir in ${IN_PATH}; do find $dir +atime 30
for dir in ${IN_PATH}; do find $dir +atime 60
for dir in ${IN_PATH}; do find $dir +atime 90
так далее..
Но это все еще заставляет цикл поиска по всей файловой системе NAS заявлять о каждом файле... МЕДЛЕННО! Так как мы проверяем время, мы должны проверить файлы, но почему бы не сделать это только один раз? Предполагая, что у вас есть Linux-машина со стандартным GNU, вы можете сделать что-то вроде этого:
find /nas/quota/ \(+atime 365 -fls /root/365.txt\), \(+atime 180 -fls /root/180.txt\), etc...
Сейчас я делаю это из памяти, поэтому может потребоваться немного доработать, чтобы все работало правильно, протестировать его в корневом веб-каталоге или в домашней директории, что быстро работает, чтобы помочь устранить неполадки. Find будет принимать несколько выражений, и если вы прочитаете предыдущие разделы справочной страницы, вы можете сделать некоторые изящные вещи. в зависимости от того, что вы хотите сделать с этой информацией, вы также можете добавить ограничения к проверке времени, например:
\(+atime 180 -a -atime 364 -fls /root/more_than_180_but_less_than_365.txt \)
Если для завершения части поиска требуются дни, это означает, что ваш сценарий зацикливается где-то, чего не должно быть. Кроме того, вы снова и снова делаете рекурсивный поиск.....
Также попробуйте отформатировать свой пост. Это выглядит как нечитаемый блок текста прямо сейчас.