Повторять команду каждые x интервалов времени в терминале?

107

Как я могу повторять команду каждый промежуток времени, чтобы она позволяла мне запускать команды для проверки или мониторинга каталогов?

Нет необходимости в скрипте, мне нужна простая команда для выполнения в терминале.

    
задан muru 06.03.2014 в 16:52
источник

8 ответов

163

Вы можете использовать команду watch , смотреть используется для выполнения любой назначенной команды через регулярные промежутки времени.

Откройте терминал и введите:

watch -n x <your command>

измените x на время в секундах, которое вы хотите.

Для получения дополнительной помощи с помощью команды watch и ее параметров запустите man watch или посетите ссылку .

Например: следующее перечисляет, каждый 60s , на том же Терминале, содержимое каталога рабочего стола, чтобы вы могли узнать, произошли ли какие-либо изменения:

watch -n 60 ls -l ~/Desktop
    
ответ дан nux 06.03.2014 в 16:54
63

Вы также можете использовать эту команду в терминале, кроме ответа nux:

while true; do <your_command>; sleep <interval_in_seconds>; done

Пример

while true; do ls; sleep 2; done

Эта команда будет печатать выходные данные ls с интервалом в 2 секунды.

Используйте Ctrl + C , чтобы остановить процесс.

Есть несколько недостатков watch

  • Он не может использовать любые команды с псевдонимом.
  • Если вывод любой команды довольно длинный, прокрутка не работает должным образом.
  • Есть некоторые проблемы с установкой максимального интервала времени за пределами определенного значения.
  • watch интерпретирует цветовые последовательности ANSI, передающие escape-символы, используя опцию -c или --color . Например, выход pygmentize будет работать, но он будет терпеть неудачу для ls --color=auto .

В приведенных выше обстоятельствах это может показаться лучшим вариантом.

    
ответ дан souravc 06.03.2014 в 17:00
28

Просто хотел перейти к souravc и nux :

  1. Пока watch отлично работает на Ubuntu, вы можете избежать этого, если хотите, чтобы ваш «Unix-fu» был чистым - например, на FreeBSD, наблюдать за командой «snoop on another tty line».
  2. while true; do command; sleep SECONDS; done также имеет оговорку - ваша команда может быть сложнее убить, используя CTR + C . Вы можете предпочесть while sleep SECONDS; do command; done - он не только короче, но и проще прерывать. Предостережение состоит в том, что он сначала сгорит, а затем запустит вашу команду, поэтому вам нужно будет подождать некоторое количество SECONDS до того, как произойдет первое вхождение команды.
ответ дан d33tah 08.03.2014 в 16:51
10

Звучит как идеальная задача для демона cron , который позволяет запускать периодические команды. Запустите команду crontab -e , чтобы начать редактирование конфигурации вашего пользователя cron. Его формат документирован в crontab (5) . В принципе, у вас есть пять связанных по времени полей, разделенных пробелами, а затем команда:

The time and date fields are:

       field          allowed values
       -----          --------------
       minute         0-59
       hour           0-23
       day of month   1-31
       month          1-12 (or names, see below)
       day of week    0-7 (0 or 7 is Sunday, or use names)

Например, если вы хотите запустить скрипт Python во вторник, 11:00:

0 11 * * 1 python ~/yourscript.py

Существуют также специальные имена, которые заменяют время, например @reboot . Очень полезно, если вам нужно создать временную директорию. Из моего crontab (указан в crontab -l ):

# Creates a temporary directory for ~/.distcc at boot
@reboot ln -sfn "$(mktemp -d "/tmp/distcc.XXXXXXXX")" "$HOME/.distcc"
    
ответ дан Lekensteyn 07.03.2014 в 19:54
3

Если вы контролируете файловую систему, то inotifywait является блестящим и, конечно же, добавляет меньше нагрузки на вашу систему.

Пример:

В терминале 1st введите следующую команду:

$ inotifywait .

Затем в терминале 2nd любая команда, которая влияет на текущий каталог,

$ touch newfile

Затем в исходном терминале inotifywait будет просыпаться и сообщать о событии

./ CREATE newfile2

Или в цикле

$ while true ; do inotifywait . ; done
Setting up watches.  
Watches established.
./ OPEN newfile2
Setting up watches.  
Watches established.
./ OPEN newfile2
Setting up watches.  
Watches established.
./ DELETE newfile
Setting up watches.  
Watches established.
./ CREATE,ISDIR newdir
Setting up watches.  
Watches established.
    
ответ дан X Tian 06.03.2014 в 17:35
3

Вы можете создать свою собственную команду repeat , выполнив следующие шаги; кредиты здесь :

Сначала откройте файл .bash_aliases :

$ xdg-open ~/.bash-aliases

Во-вторых, вставьте эти строки в нижней части файла и сохраните:

repeat() {
n=
shift
while [ $(( n -= 1 )) -ge 0 ]
do
    "[email protected]"
done
}

В-третьих, либо закройте и снова откройте свой терминал, либо введите:

$ source ~/.bash_aliases

Et voilà! Теперь вы можете использовать его следующим образом:

$ repeat 5 echo Hello World !!!

или

$ repeat 5 ./myscript.sh
    
ответ дан Blufter 08.08.2014 в 21:38
3

вы можете использовать crontab. запустите команду crontab -e и откройте ее с помощью предпочтительного текстового редактора, затем добавьте эту строку

*/10 * * * *  /path-to-your-command

Это запустит вашу команду каждые 10 минут

* */4 * * *  /path-to-your-command

Это будет выполнять вашу команду каждые 4 часа

Другое возможное решение

$ ..some command...; for i in $(seq X); do $cmd; sleep Y; done

X количество повторений.

Y время ожидания для повторения.

Пример:

$ echo; for i in $(seq 5); do $cmd "This is echo number: $i"; sleep 1;done
    
ответ дан Maythux 07.03.2014 в 06:57
0

Еще одна проблема с предложенным выше принципом «смотреть» заключается в том, что он отображает результат только тогда, когда процесс выполняется. «date; sleep 58; date» будет отображать 2 даты только через 59 секунд ... Если вы запустите что-то, работающее в течение 4 минут, которое медленно отображает несколько страниц содержимого, вы его действительно не увидите.

С другой стороны, озабоченность «пока» заключается в том, что она не учитывает продолжительность задачи.

while true; do script_that_take_between_10s_to_50s.sh; sleep 50; done

С этим скрипт будет запускаться когда-нибудь каждую минуту, иногда может занять 1m40. Поэтому, даже если cron сможет запускать его каждую минуту, здесь он не будет.

Итак, чтобы увидеть вывод на оболочке по мере ее создания и дождаться точного времени запроса, вам нужно посмотреть время до, и после, и цикл с while.

Что-то вроде:

while ( true ); do
  echo Date starting 'date'
  before='date +%s'
  sleep 'echo $(( ( RANDOM % 30 )  + 1 ))'
  echo Before waiting 'date'
  after='date +%s'
  DELAY='echo "60-($after-$before)" | bc'
  sleep $DELAY
  echo Done waiting 'date'
done

Это выведет это:

Как вы можете видеть, команда запускается каждую минуту:

Date starting Mon Dec 14 15:49:34 EST 2015
Before waiting Mon Dec 14 15:49:52 EST 2015
Done waiting Mon Dec 14 15:50:34 EST 2015

Date starting Mon Dec 14 15:50:34 EST 2015
Before waiting Mon Dec 14 15:50:39 EST 2015
Done waiting Mon Dec 14 15:51:34 EST 2015

Итак, просто замените команду «sleep echo $(( ( RANDOM % 30 ) + 1 )) » тем, что вы хотите, и которая будет выполняться на терминале / оболочке ровно каждую минуту. Если вы хотите другое расписание, просто измените «60 секунд» на то, что вам нужно.

Более короткая версия без строк отладки:

while ( true ); do
  before='date +%s'
  sleep 'echo $(( ( RANDOM % 30 )  + 1 ))' # Place you command here
  after='date +%s'
  DELAY='echo "60-($after-$before)" | bc'
  sleep $DELAY
done
    
ответ дан jmspaggi 14.12.2015 в 21:56