Синтаксис для однострочного Bash бесконечного цикла while
У меня возникают проблемы с правильным сочетанием точек с запятой и / или фигурных скобок. Я хотел бы сделать это, но в качестве одной строки из командной строки:
while [ 1 ]
do
foo
sleep 2
done
15 ответов
while true; do foo; sleep 2; done
Кстати, если вы наберете это как многострочное (как вы показываете) в командной строке, а затем вызовете историю со стрелкой вверх, вы получите ее в одной строке, правильно пунктуированной.
$ while true
> do
> echo "hello"
> sleep 2
> done
hello
hello
hello
^C
$ <arrow up> while true; do echo "hello"; sleep 2; done
Также возможно использовать команду сна в состоянии while. Делая однострочник более чистым imho.
while sleep 2; do echo thinking; done
Вы можете использовать точки с запятой для разделения операторов:
$ while [ 1 ]; do foo; sleep 2; done
Вы также можете использовать until
команда:
until ((0)); do foo; sleep 2; done
Обратите внимание, что в отличие от while
, until
будет выполнять команды внутри цикла до тех пор, пока условие теста имеет статус выхода, который не равен нулю.
Используя while
цикл:
while read i; do foo; sleep 2; done < /dev/urandom
Используя for
цикл:
for ((;;)); do foo; sleep 2; done
Еще один способ использования until
:
until [ ]; do foo; sleep 2; done
С помощью while
:
while true; do echo 'while'; sleep 2s; done
С помощью for
Loop:
for ((;;)); do echo 'forloop'; sleep 2; done
С помощью Recursion
(немного отличается от описанного выше, прерывание клавиатуры не остановит его)
list(){ echo 'recursion'; sleep 2; list; } && list;
Очень простой бесконечный цикл..:)
while true ; do continue ; done
Для вашего вопроса это будет:
while true; do foo ; sleep 2 ; done
Для простого наблюдения за процессом использования watch
вместо
Мне нравится использовать точки с запятой только для оператора WHILE, а оператор &&, чтобы цикл делал больше, чем одно...
Поэтому я всегда так делаю
while true ; do echo Launching Spaceship into orbit && sleep 5s && /usr/bin/launch-mechanism && echo Launching in T-5 && sleep 1s && echo T-4 && sleep 1s && echo T-3 && sleep 1s && echo T-2 && sleep 1s && echo T-1 && sleep 1s && echo liftoff ; done
Если вы хотите, чтобы цикл while останавливался после некоторого условия, а ваш foo
Команда возвращает ненулевое значение, когда это условие выполнено, тогда вы можете разорвать цикл следующим образом:
while foo; do echo 'sleeping...'; sleep 5; done;
Например, если foo
Команда удаляет вещи в пакетном режиме и возвращает 1, когда нечего удалять.
Это хорошо работает, если у вас есть собственный скрипт, который должен выполнять команду много раз, пока не произойдет какое-либо условие. Вы пишете сценарий для выхода с 1
когда условие выполнено и выйти с 0
когда он должен быть запущен снова.
Например, скажем, у вас есть скрипт на Python batch_update.py
который обновляет 100 строк в базе данных и возвращает 0
если есть еще для обновления и 1
если больше нет Следующая команда позволит вам обновлять строки 100 за один раз с перерывами на 5 секунд между обновлениями:
while batch_update.py; do echo 'sleeping...'; sleep 5; done;
Вам даже не нужно использовать
do
и
done
. Для бесконечных циклов мне удобнее использовать
for
с фигурными скобками. Например:
for ((;;)) { date ; sleep 1 ; }
Это работает в
bash
и
zsh
. Не работает в
sh
.
Если я могу привести два практических примера (с небольшим количеством "эмоций").
Это записывает имя всех файлов, оканчивающихся на ".jpg" в папке "img":
for f in *; do if [ "${f#*.}" == 'jpg' ]; then echo $f; fi; done
Это удаляет их:
for f in *; do if [ "${f#*.}" == 'jpg' ]; then rm -r $f; fi; done
Просто пытаюсь внести свой вклад.
Вы можете попробовать это тоже ВНИМАНИЕ: этого делать не следует, но поскольку вопрос заключается в бесконечном цикле без конца... это то, как вы можете это сделать.
while [[ 0 -ne 1 ]]; do echo "it's looping"; sleep 2; done
Вы также можете поместить этот цикл в фоновый режим (например, когда вам нужно отключиться от удаленного компьютера)
nohup bash -c "while true; do aws s3 sync xml s3://bucket-name/xml --profile=s3-profile-name; sleep 3600; done &"
вbash 5
(или, возможно, даже раньше), вы также можете изменить роль, выполнив все критерии цикла, но вместо этого используя в теле цикла:
while ( gdate +"%c ( %s.%-N )" && sleep 0.71 ) do :; done # discards side-effects
while { gdate +"%c ( %s.%-N )" && sleep 0.71; } do :; done # no sub-shell needed
+ gdate '+%c ( %s.%-N )'
Sun Apr 30 12:38:25 2023 ( 1682872705.498728 )
+ sleep 0.71
+ :
+ gdate '+%c ( %s.%-N )'
Sun Apr 30 12:38:26 2023 ( 1682872706.218152 )
+ sleep 0.71
...
тем временемzsh
еще более снисходителен и готов к зацикливанию даже без:
while; do gdate +'%c ( %s.%-N )' && sleep 0.31 ; done
Sun Apr 30 12:46:09 2023 ( 1682873169.469092 )
Sun Apr 30 12:46:09 2023 ( 1682873169.789560 )
Sun Apr 30 12:46:10 2023 ( 1682873170.105635 )
Sun Apr 30 12:46:10 2023 ( 1682873170.424766 )