Как я могу определить, что файл старше 30 минут из / bin / sh? - PullRequest
38 голосов
/ 05 января 2010

Как мне написать скрипт для определения, если файл старше 30 минут в / bin / sh?

К сожалению, в системе нет статистики. Это старая система Unix, http://en.wikipedia.org/wiki/Interactive_Unix

К сожалению, Perl не установлен в системе, и клиент не хочет его устанавливать, и ничего больше.

Ответы [ 11 ]

67 голосов
/ 05 января 2010

Вот один из способов использования find.

if test "`find file -mmin +30`"

Команда find должна быть заключена в кавычки, если рассматриваемый файл содержит пробелы или специальные символы.

28 голосов
/ 05 января 2010

Следующее дает вам возраст файла в секундах:

echo $(( `date +%s` - `stat -L --format %Y $filename` ))

, что означает, что это должно давать значение true / false (1/0) для файлов старше 30 минут:

echo $(( (`date +%s` - `stat -L --format %Y $filename`) > (30*60) ))

30*60 - 60 секунд в минуту, не пересчитывайте, пусть процессор сделает всю работу за вас!

16 голосов
/ 05 января 2010

Если вы пишете скрипт sh, самый полезный способ - использовать test с уже упомянутым трюком статистики:

if [ `stat --format=%Y $file` -le $(( `date +%s` - 1800 )) ]; then 
    do stuff with your 30-minutes-old $file
fi

Обратите внимание, что [ является символической ссылкой (или иным образом эквивалентной) на test; см. man test, но имейте в виду, что test и [ также являются встроенными в bash и поэтому могут вести себя несколько иначе. (Также обратите внимание на составную команду [[ bash).

9 голосов
/ 05 января 2010

Хорошо, нет статистики и искалеченная находка. Вот ваши альтернативы:

Скомпилируйте GNU coreutils , чтобы получить приличную находку (и множество других удобных команд). Возможно, у вас уже есть gfind.

Может быть, вы можете использовать date, чтобы получить время изменения файла, если -r работает?

(`date +%s` - `date -r $file +%s`) > (30*60)

В качестве альтернативы, используйте сравнение -nt, чтобы выбрать, какой файл более новый, проблема заключается в создании файла со временем модификации 30 минут назад. touch обычно может сделать это, но все ставки на то, что доступно, отключены.

touch -d '30 minutes ago' 30_minutes_ago
if [ your_file -ot 30_minutes_ago ]; then
    ...do stuff...
fi

И, наконец, посмотрите, доступен ли Perl, а не борется с тем, кто знает, какие версии утилит оболочки.

use File::stat;
print "Yes" if (time - stat("yourfile")->mtime) > 60*30;
5 голосов
/ 25 февраля 2015

Для таких, как я, которым не нравятся обратные галочки, основываясь на ответе @slebetman:

echo $(( $(date +%s) - $(stat -L --format %Y $filename) > (30*60) ))
4 голосов
/ 05 января 2010

Вы можете сделать это, сравнив созданный вами эталонный файл с отметкой времени 30 минут назад.

Сначала создайте файл сравнения, введя

touch -t YYYYMMDDhhmm.ss /tmp/thirty_minutes_ago

замена отметки времени значением тридцать минут назад. Вы можете автоматизировать этот шаг с тривиальным вкладышем в Perl.

Затем используйте оператор поиска новее, чтобы найти файлы старше, отрицая оператор поиска

find . \! -newer /tmp/thirty_minutes_ago -print
2 голосов
/ 13 октября 2017

Вы можете использовать команду поиска.
Например, для поиска файлов в текущем каталоге старше 30 минут:

find . -type f -mmin +30 

Вы можете прочитать о найти команда ЗДЕСЬ

2 голосов
/ 07 июня 2011
#!/usr/bin/ksh
## this script creates a new timer file every minute and renames all the previously created timer files and then executes whatever script you need which can now use the timer files to compare against with a find.  The script is designed to always be running on the server.  The first time the script is executed it will remove the timer files and it will take an hour to rebuild them (assuming you want 60 minutes of timer files)

set -x

# if the server is rebooted for any reason or this scripts stops we must rebuild the timer files from scratch
find /yourpath/timer -type f -exec rm {} \;

while [ 1 ]
do
COUNTER=60
COUNTER2=60
cd /yourpath/timer
while [ COUNTER -gt 1 ]
do
  COUNTER2=`expr $COUNTER - 1`
  echo COUNTER=$COUNTER
  echo COUNTER2=$COUNTER2
  if [  -f timer-minutes-$COUNTER2 ]
    then
       mv timer-minutes-$COUNTER2 timer-minutes-$COUNTER
       COUNTER=`expr $COUNTER - 1`
  else
     touch timer-minutes-$COUNTER2
  fi
done

touch timer-minutes-1
sleep 60

#this will check to see if the files have been fully updated after a server restart
COUNT=`find . ! -newer timer-minutes-30 -type f | wc -l | awk '{print $1}'`
if [ $COUNT -eq 1  ]
   then
     # execute whatever scripts at this point
fi

done
2 голосов
/ 05 января 2010

Что вы подразумеваете под старше 30 минут : изменено более 30 минут назад или создано более 30 минут назад ? Надеюсь, что это первое, так как ответы пока верны для этой интерпретации. В последнем случае у вас есть проблемы, поскольку файловые системы Unix не отслеживают время создания файла. (Атрибут файла ctime записывает, когда содержимое inode изменилось в последний раз, то есть произошло что-то вроде chmod или chown).

Если вам действительно необходимо знать, был ли файл создан более 30 минут назад, вам придется либо сканировать соответствующую часть файловой системы несколько раз с помощью чего-то вроде find, либо использовать что-то зависящее от платформы, например, linux Inotify .

0 голосов
/ 02 марта 2018

Вот мой вариант find:

if [ `find cache/nodes.csv -mmin +10 | egrep '.*'` ]

Поиск всегда возвращает код состояния 0, если не происходит сбой; однако egrep возвращает 1, если совпадений не найдено`. Таким образом, эта комбинация проходит, если этот файл старше 10 минут.

Попробуйте:

touch /tmp/foo; sleep 61; 
find /tmp/foo -mmin +1  | egrep '.*'; echo $?
find /tmp/foo -mmin +10 | egrep '.*'; echo $?

Должен печатать 0, а затем 1 после пути к файлу.

Моя функция, использующая это:

##  Usage: if isFileOlderThanMinutes "$NODES_FILE_RAW" $NODES_INFO_EXPIRY; then ...
function isFileOlderThanMinutes {
  if [ "" == "$1" ] ; then serr "isFileOlderThanMinutes() usage: isFileOlderThanMinutes <file> <minutes>"; exit; fi
  if [ "" == "$2" ] ; then serr "isFileOlderThanMinutes() usage: isFileOlderThanMinutes <file> <minutes>"; exit; fi
  ##  Does not exist -> "older"
  if [ ! -f "$1" ] ; then return 0; fi
  ##  The file older than $2 is found...
  find "$1" -mmin +$2 | egrep '.*'  > /dev/null 2>&1;
  if [ $? == 0 ] ; then return 0; fi  ## So it is older.
  return 1;  ## Else it not older.
}
...