Shell: возможно ли отложить команду без использования `sleep`?
21
Есть ли заменители, альтернативы или хитрости для задержки команд без использования sleep? Например, выполнив приведенную ниже команду без использования sleep:
Там нет реальной причины, кроме любопытства. Я подумал, что было бы интересно узнать некоторые альтернативные решения. Я думаю, что atможет быть один, но я не мог найти примеры использования.
user321697
1
@ user321697 «at» предназначен для планирования отдельных заданий. они выполняются службой atd, поэтому они не будут останавливать ваш сценарий оболочки. Один из вариантов использования at - это сделать что-то в указанное время (асинхронно) и создать файл маркера после его завершения, пока ваш скрипт ожидает появления этого файла в цикле while. Вы можете добиться аналогичного эффекта, запланировав задание на отправку сценария SIGCONT, а затем заморозив сценарий, отправив себе SIGSTOP.
Грега Бремец
1
Я пришел сюда, ожидая, что все предложат спинлок. Я приятно удивлен всеми ответами.
Даан ван Хук
3
Re: «Любопытство» - в unix.stackexchange.com/help/dont-ask обратите внимание на требование: «Вы должны задавать только практические, отвечающие на вопросы вопросы, основанные на реальных проблемах, с которыми вы сталкиваетесь », - что это было хорошо получил, несмотря на противоречие, что руководство делает его довольно редким исключением.
Чарльз Даффи
Ответы:
17
У вас есть альтернативы sleep: они есть atи cron. В противоположность sleepэтому вам необходимо указать время, в которое вы должны их запустить.
Убедитесь, что atdслужба работает, выполнивservice atd status .
Теперь давайте скажем, что дата 11:17 UTC; если вам нужно выполнить команду в 11:25 UTC, синтаксис: echo "This is a test" | at 11:25.
Имейте в виду, что atdпо умолчанию не будет регистрироваться завершение заданий. Для более подробной информации обратитесь по этой ссылке . Лучше, чтобы у вашего приложения была собственная регистрация.
Вы можете запланировать работу в cron, для более подробной информации: man cronчтобы увидеть его параметры или crontab -eдобавить новые работы. /var/log/cronможно проверить информацию о выполнении на рабочих местах.
FYI sleep system call приостанавливает текущее выполнение и планирует его с аргументом, переданным ему.
РЕДАКТИРОВАТЬ:
Как упомянул @Gaius, вы также можете добавить минутное время к atкоманде. Но скажем, время есть, 12:30:30и теперь вы запустили планировщик с помощью now +1 minutes. Хотя была указана 1 минута, что соответствует 60 секундам, на atсамом деле12:31:30 выполнения задания, а выполняет ее в 12:31:00. Единицы времени могут быть minutes, hours, days, or weeks. Для более подробной информацииman at
Это неправда, вы можете запланировать на работе, скажем, сейчас +1 минуту, чтобы запустить в течение минут
Гай
29
Со bashвстроенными вы можете сделать:
coproc read -t 10&& wait "$!"|| true
Спать 10 секунд без использования sleep. Нужно coprocсделать так, чтобы readstdin - это труба, из которой ничего не выйдет. || trueэто потому чтоwait с тем, что состояние выхода будет отражать доставку SIGALRM, что приведет к выходу оболочки, если эта errexitопция установлена.
В других оболочках:
mkshи ksh93естьsleep встроенный, нет смысла использовать что-либо еще там (хотя они оба также поддерживают read -t).
zshтакже поддерживает read -t, но также имеет встроенную оболочку вокругselect() , так что вы также можете использовать:
@JeffSchaller Я бы этого избегал, потому что это занятый цикл.
Стефан Шазелас
@ StéphaneChazelas Я бы не ожидал, что это будет занятый цикл - я ожидаю, что любая оболочка readбудет реализована с использованием select (2) или чего-то подобного (подразумевая, что чтение с тайм-аутом будет хорошим ответом на этот вопрос). Я выражаю удивление, а не противоречу вам, но можете ли вы указать на дальнейшее обсуждение этого?
Норман Грей,
5
@NormanGray, /dev/zeroэто файл, который содержит бесконечное количество данных (байтов NUL). Так readчто прочитайте столько, сколько сможете за эти 10 секунд. К счастью, в случае, bashкогда не поддерживается сохранение байтов NUL в своих переменных, это не израсходует никакой памяти, но при этом все равно увеличивает ресурсы процессора.
Стефан Шазелас
1
@NormanGray, если он запускается из терминала, /dev/stdoutбудет устройством tty, поэтому у него будут побочные эффекты (например, остановка сценария, если он работает в фоновом режиме), и он будет возвращаться, если пользователь нажимает, например, enter. read -t 10 /dev/stdout | :будет работать на Linux, но только на Linux, хотя coprocдолжен работать независимо от ОС.
Стефан Шазелас
7
Некоторые другие идеи.
top -d10 -n2 >/dev/null
vmstat 102>/dev/null
sar 101>/dev/null
timeout 10s tail -f /dev/null
Это фактически приведет к паузе в течение периода времени , начиная где - то между 9 и 10 секунд , хотя (из - за ошибки вbash , zshи mkshбыли подобные проблемы , но были установлены так)
Stéphane Chazelas
7
Хороший способ сделать тепло.
Ctrl-Alt-Delor
6
меня не обвинят в том, что я полон горячего воздуха! :)
Это не будет, если процесс должен быть запущен без взаимодействия или в фоновом режиме, верно?
ss_iwe
Правильно: Но это не было одним из требований ОП согласно первоначальному вопросу, поэтому все еще действительный ответ ... ;-)> :-)
Fabby
1
ОП конкретно приводит пример (с sleep) и просит эквивалентную альтернативу без. Так readчто не разбираюсь, извините. ;)
AnoE
@AnoE Ответ Стефана, конечно, самый лучший, мой только самый старый --- press «enter» to continue --- ;-)
Fabby
4
В те времена, когда микрокомпьютеры работали с BASIC, задержки обычно заканчивались пустым циклом:
FOR I = 1 TO 10000:NEXT
Тот же принцип можно использовать для вставки задержки в сценарий оболочки:
COUNTER=0; while [ $COUNTER -lt 10000 ]; do :; let COUNTER=COUNTER+1; done
Конечно, проблема с этим подходом состоит в том, что длина задержки будет варьироваться от машины к машине в зависимости от скорости процессора (или даже на одной и той же машине при разных нагрузках). В отличие от этого sleep, он, вероятно, будет также максимально использовать ваш процессор (или одно из его ядер).
Циклы задержки - ужасная идея для всего, кроме самого короткого из снов (пара наносекунд или тактовых циклов в драйвере устройства) на любом современном процессоре, который может работать под Unix-подобной ОС. т. е. такой короткий сон, что ЦП не может с пользой делать что-либо еще во время ожидания, например, планировать другой процесс или переходить в режим ожидания с низким энергопотреблением, прежде чем проснуться от прерывания по таймеру. Динамическая частота ЦП делает невозможным даже калибровку контура задержки для отсчетов в секунду, за исключением минимальной задержки, которая потенциально может спать намного дольше на низких тактовых частотах до увеличения.
Питер Кордес
У древних компьютеров энергопотребление было намного меньше в зависимости от рабочей нагрузки. Современным процессорам необходимо максимально динамически отключать различные части чипа, чтобы не расплавить (например, отключить части исполнительных блоков FPU или SIMD, пока выполняется только целочисленный код, или, по крайней мере, передать синхросигнал частям чипа это не должно быть переключением). И переход в спящий режим с низким энергопотреблением во время простоя (вместо вращения в бесконечном цикле ожидания прерываний по таймеру) также более поздний, чем у древних компьютеров, о которых вы упоминали.
Питер Кордес
Для получения дополнительной информации об истории процессоров см. Руководство по современным микропроцессорам за 90 минут! - lighterra.com/papers/modernmicroprocessors .
Питер Кордес
3
Там нет встроенного, который делает так же, как sleep (если sleepне встроен). Однако есть некоторые другие команды, которые будут ждать.
Некоторые включают.
atи cron: используется для планирования задач в определенное время.
inotifywait: используется для ожидания файла или файлов, которые будут изменены / удалены / добавлены / и т. д.
Извините, что вернули ваше редактирование в вопрос: вы изменили основную цель вопроса ОП, которая лишает законной силы самый простой ответ из всех ... ¯ \ _ (ツ) _ / ¯
Fabby
3
Классика из Страны окон и партий:
ping -c 11 localhost >/dev/null && echo "This is a test"
Неправильная настройка брандмауэра или системы имен может привести к значительной дополнительной задержке.
спектры
1
127.0.0.1 ... @spectras
AnoE
1
К счастью, больше не нужен, так как Windows теперь поддерживает режим сна.
Baldrickk
1
@AnoE> решает часть системы имен, а не часть брандмауэра. Хотя это и не распространено, его можно настроить так, чтобы он отбрасывал пинг на локальном интерфейсе. Это заставит пинг ждать намного дольше.
спектры
+1 за «теплые» воспоминания
AC
0
Если вы хотите в интерактивном режиме ждать новую строку в файле, то
tail -f
,
Ожидание изменения в файловой системе? Затем используйте, например,
inotify / inoticoming
,
И есть другие варианты, в зависимости от того, что вы подразумеваете под «ждать».
sleep
?at
может быть один, но я не мог найти примеры использования.Ответы:
У вас есть альтернативы
sleep
: они естьat
иcron
. В противоположностьsleep
этому вам необходимо указать время, в которое вы должны их запустить.Убедитесь, что
atd
служба работает, выполнивservice atd status
.Теперь давайте скажем, что дата 11:17 UTC; если вам нужно выполнить команду в 11:25 UTC, синтаксис:
echo "This is a test" | at 11:25
.Имейте в виду, что
atd
по умолчанию не будет регистрироваться завершение заданий. Для более подробной информации обратитесь по этой ссылке . Лучше, чтобы у вашего приложения была собственная регистрация.Вы можете запланировать работу в
cron
, для более подробной информации:man cron
чтобы увидеть его параметры илиcrontab -e
добавить новые работы./var/log/cron
можно проверить информацию о выполнении на рабочих местах.FYI
sleep system call
приостанавливает текущее выполнение и планирует его с аргументом, переданным ему.РЕДАКТИРОВАТЬ:
Как упомянул @Gaius, вы также можете добавить минутное время к
at
команде. Но скажем, время есть,12:30:30
и теперь вы запустили планировщик с помощьюnow +1 minutes
. Хотя была указана 1 минута, что соответствует 60 секундам, наat
самом деле12:31:30
выполнения задания, а выполняет ее в12:31:00
. Единицы времени могут бытьminutes, hours, days, or weeks
. Для более подробной информацииman at
например:
echo "ls" | at now +1 minutes
источник
Со
bash
встроенными вы можете сделать:Спать 10 секунд без использования
sleep
. Нужноcoproc
сделать так, чтобыread
stdin - это труба, из которой ничего не выйдет.|| true
это потому чтоwait
с тем, что состояние выхода будет отражать доставку SIGALRM, что приведет к выходу оболочки, если этаerrexit
опция установлена.В других оболочках:
mksh
иksh93
естьsleep
встроенный, нет смысла использовать что-либо еще там (хотя они оба также поддерживаютread -t
).zsh
также поддерживаетread -t
, но также имеет встроенную оболочку вокругselect()
, так что вы также можете использовать:Если вам нужно запланировать запуск вещей из сеанса интерактивной оболочки, см. Также
zsh/sched
модуль вzsh
.источник
read -t 10 < /dev/zero || true
?read
будет реализована с использованием select (2) или чего-то подобного (подразумевая, что чтение с тайм-аутом будет хорошим ответом на этот вопрос). Я выражаю удивление, а не противоречу вам, но можете ли вы указать на дальнейшее обсуждение этого?/dev/zero
это файл, который содержит бесконечное количество данных (байтов NUL). Такread
что прочитайте столько, сколько сможете за эти 10 секунд. К счастью, в случае,bash
когда не поддерживается сохранение байтов NUL в своих переменных, это не израсходует никакой памяти, но при этом все равно увеличивает ресурсы процессора./dev/stdout
будет устройством tty, поэтому у него будут побочные эффекты (например, остановка сценария, если он работает в фоновом режиме), и он будет возвращаться, если пользователь нажимает, например, enter.read -t 10 /dev/stdout | :
будет работать на Linux, но только на Linux, хотяcoproc
должен работать независимо от ОС.Некоторые другие идеи.
источник
Поскольку есть ответы, которые предлагают использовать нестандартную
-t delay
опциюread
, вот способ сделать тайм-аут чтения в стандартной оболочке:Аргумент к
stty time
находится в десятых долях секунды.источник
Использование встроенной переменной bash
$SECONDS
и цикла занятости:источник
bash
,zsh
иmksh
были подобные проблемы , но были установлены так)самый старый трюк в книге:
Просто нажмите, Enterи это будет продолжаться!
источник
sleep
) и просит эквивалентную альтернативу без. Такread
что не разбираюсь, извините. ;)--- press «enter» to continue ---
;-)В те времена, когда микрокомпьютеры работали с BASIC, задержки обычно заканчивались пустым циклом:
FOR I = 1 TO 10000:NEXT
Тот же принцип можно использовать для вставки задержки в сценарий оболочки:
COUNTER=0; while [ $COUNTER -lt 10000 ]; do :; let COUNTER=COUNTER+1; done
Конечно, проблема с этим подходом состоит в том, что длина задержки будет варьироваться от машины к машине в зависимости от скорости процессора (или даже на одной и той же машине при разных нагрузках). В отличие от этого
sleep
, он, вероятно, будет также максимально использовать ваш процессор (или одно из его ядер).источник
Там нет встроенного, который делает так же, как
sleep
(еслиsleep
не встроен). Однако есть некоторые другие команды, которые будут ждать.Некоторые включают.
at
иcron
: используется для планирования задач в определенное время.inotifywait
: используется для ожидания файла или файлов, которые будут изменены / удалены / добавлены / и т. д.источник
at
?cron
хранить задачи вcrontab
, верно? Гдеat
хранятся запланированные данные?Классика из Страны окон и партий:
источник
Если вы хотите в интерактивном режиме ждать новую строку в файле, то
,Ожидание изменения в файловой системе? Затем используйте, например,
,И есть другие варианты, в зависимости от того, что вы подразумеваете под «ждать».
источник