2009-08-17 3 views
449

У меня возникают проблемы с правильной комбинацией точек с запятой и/или фигурными скобками. Я хотел бы сделать это, но, как однострочник из командной строки:Синтаксис для однострочного бесконечного цикла Bash

while [ 1 ] 
do 
    foo 
    sleep 2 
done 
+4

заменить новые строки точкой с запятой. То же самое работает для петель. – Tom

+19

@ Тома: это не всегда работает. после этого вы должны иметь первую команду, а не точку с запятой –

ответ

835
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 
+230

+1 для метра и рифмы. Это отличная мнемоника: «while * true * do * foo * sleep * too * la di da»: D – Shabbyrobe

+1

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

+0

@ VincentScheib, проверьте опцию 'cmdhist', если вы используете bash? –

23

Вы можете использовать точку с запятой для разделения операторов:

$ while [ 1 ]; do foo; sleep 2; done 
+0

Мне нравится этот ответ, потому что он объясняет, когда и почему; (точка с запятой). –

6

Мне нравится использовать точку с запятой только для 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 
+1

Ну, использование '&&' в цикле такое же, как и в любое другое время, на самом деле это не так. Вам нужно, чтобы второе произошло, только если первое произойдет, а затем используйте '&&' else ';' достаточно. Действительно, вы хотите сохранить содержимое этого цикла коротким и простым, в идеале одной командой, поэтому функцией или скриптом. – thecoshman

1

Если я могу привести два практических примера (с небольшим количеством «эмоций»).

Об этом пишет название всех файлов закончилось ".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 

Просто пытаюсь внести свой вклад.

+3

Легче сказать: '' 'for f in * .jpg; do echo $ f; done''' – JKnight

+1

@JKnight - для этих примеров вы бы просто не делали ** 'ls -1 * .jpg' ** и **' rm * .jpg' ** –

+2

Оба не являются бесконечными циклами, а не во время петли. – Marian

126

Также можно использовать команду sleep в состоянии while. Сделать однострочный слой более чистым imho.

while sleep 2; do echo thinking; done 
+1

Полезно знать !! –

+5

Ну, это не просто изменение синтаксиса - он выполнит команду * после * сна. В предыдущем ответе команда выполняется сразу.Просто что-то отметить. – DanGordon

55

Colon всегда "правда":

while :; do foo; sleep 2; done 
+11

Почему двоеточие всегда верно? – Michelle

+5

@ Ананас под морю: Из справочной страницы bash: (в разделе SHELL BUILTIN COMMANDS) ': [arguments]' Отсутствие эффекта; команда ничего не делает за пределами расширения аргументов и выполнения любых заданных перенаправлений. Возвращается нулевой код возврата. –

+2

этот синтаксис рекомендуется как: является частью самой оболочки. I.e: является встроенной оболочкой. – avner

18

Вы также можете использовать 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 
+4

+1 для альтернативного решения. – glen3b

5

Очень простой бесконечный цикл ..:)

while true ; do continue ; done 

Fr Ваш вопрос было бы:

while true; do foo ; sleep 2 ; done 
2

Для простого процесса, наблюдая использование watch вместо

0

Вы можете попробовать это тоже ВНИМАНИЕ: это вы не должны делать, но так как вопрос требует бесконечного цикла без конца ... вот как вы могли это сделать.

while [[ 0 -ne 1 ]]; do echo "it's looping"; sleep 2; done 
+0

Зачем вам это делать? –

+1

, потому что Брайан Дикон, который разместил вопрос, хотел как петля infinte. Это более чем один способ обмануть кошку, вот и все: –

1

Если вы хотите, чтобы цикл в то время, чтобы остановить после некоторого условия, и ваша команда foo возвращает ненулевое значение, если это условие выполнено, то вы можете получить петлю сломать так:

while foo; do echo 'sleeping...'; sleep 5; done; 

Например, если команда foo удаляет файлы партиями и возвращает 1, когда ничего не остается удалить.

Это хорошо работает, если у вас есть собственный скрипт, который должен выполнять команду много раз до некоторого состояния. Вы пишете сценарий для выхода с 1, когда условие выполнено и выйдите с 0, когда он должен быть запущен снова.

Например, у вас есть питон скрипт batch_update.py который обновляет 100 строк в базе данных и возвращает 0 если не больше, чтобы обновить и 1, если больше нет. Следующая команда позволит вам обновлять строки 100 за один раз спящим в течение 5 секунд между обновлениями:

while batch_update.py; do echo 'sleeping...'; sleep 5; done; 
+0

и как вы выйдете? –

+0

Вы делаете команду 'foo' командой с кодом' 1', когда хотите, чтобы цикл while прерывался. Я обновил свой ответ на примере. –