Синтаксис для однострочного 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 :; do foo; sleep 2; 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 )
Другие вопросы по тегам