Что означает «пока:;»?

27

Я знаю, что такое whileпетля. Тем не менее, я видел только это работает с:

while [condition]
while ![condition]
while TRUE (infinite loop)

Где утверждение whileдолжно быть либо TRUEили FALSE.

Существует встроенная команда оболочки с именем :. Это описывается как фиктивная команда, которая ничего не делает, но я не знаю, является ли она здесь такой же, даже если это может быть TRUEили FALSE. Может быть, это что-то другое, но что?

sharkant
источник
4
Команда :ничего не делает, но всегда завершается с кодом возврата 0. Таким образом, то же самое было while true(при условии, что ваша система имеет trueисполняемый файл).
Джон1024
@ John1024 Возвращает ноль, если оценка его аргументов не вызывает ошибку, например, путем присвоения значения переменной только для чтения.
Кусалананда
3
@Kusalananda Да, если :команда никогда не будет выполнена, она не вернет 0. Это, на мой взгляд, слишком педантично.
HVd

Ответы:

50

Синтаксис:

while
  first list of commands
do
  second list of commands
done

который запускает второй список команд в цикле, пока первый список команд (то есть последний запуск в этом списке) является успешным.

В этом первом списке команд вы можете использовать [команду для выполнения различных видов тестов, или вы можете использовать команду :null, которая ничего не делает и возвращает успех, или любую другую команду.

while :; do cmd; done

Работает cmdснова и снова навсегда, как :всегда, возвращает успех. Это вечная петля. trueВместо этого вы можете использовать команду, чтобы сделать ее более разборчивой:

while true; do cmd; done

Люди предпочитали, :как :всегда было встроено, в то время как trueне было (давным-давно; большинство оболочек построено в настоящее trueвремя) ¹.

Другие варианты, которые вы можете увидеть:

while [ 1 ];  do cmd; done

Выше мы вызываем [команду, чтобы проверить, не является ли строка «1» непустой (так всегда всегда верно)

while ((1)); do cmd; done

Использование ((...))синтаксиса Korn / bash / zsh для имитации while(1) { ...; }C.

Или более запутанные, как until false; do cmd; done, until ! true...

Те иногда псевдонимы как:

alias forever='while :; do'

Таким образом, вы можете сделать что-то вроде:

forever cmd; done

Мало кто понимает, что условие - это список команд. Например, вы видите людей, пишущих:

while :; do
  cmd1
  cmd2 || break
  cmd3
done

Когда они могли написать:

while
  cmd1
  cmd2
do
  cmd3
done

Для этого имеет смысл быть списком, так как вы часто хотите делать такие вещи, как while cmd1 && cmd2; do...; doneсписки команд.

В любом случае, обратите внимание, что [это команда, как и любая другая (хотя она встроена в современные оболочки типа Борна), ее не нужно использовать исключительно в списках условий if/ while/ until, и эти списки условий не имеют использовать эту команду больше, чем любую другую команду.


Also :также короче и принимает аргументы (которые он игнорирует). Пока поведение trueили falseне указано, если вы передаете ему какой-либо аргумент. Так, например, можно сделать:

while : you wait; do
  something
done

Но поведение:

until false is true; do
  something
done

не определено (хотя это будет работать в большинстве оболочек / falseреализаций).

Стефан Шазелас
источник
12

while :это бесконечный цикл. :просто ничего не делает (успешно).

Так что если вы хотите, чтобы ваша оболочка зависала вечно, ничего не делая, вы можете написать

while :
do
    :
done

Или в одной строке ;вместо новых строк:while :; do :; done

while :обычно используется, если вы хотите сделать что-то несколько раз без специальных условий. Вы можете использовать continue, breakоператор внутри цикла , чтобы контролировать его или переместить условие в конец цикла , как do ... whileконструкция.

frostschutz
источник
12

как бы то ни было, утверждение через некоторое время должно быть ИСТИНА или ЛОЖЬ.

Нет, команда в части условия может быть любой командой (*) . Все команды оболочки имеют некоторое возвращаемое значение, и whileцикл (как и ifусловный) принимает нулевые возвращаемые значения как «true», а все остальные как «false». (* или список из нескольких команд, последняя считается)

Что касается :, руководство в Bash ясно говорит , что статус возврата , который:

: [arguments]
Ничего не делайте, кроме расширения аргументов и выполнения перенаправлений. Статус возврата равен нулю.

helpВстроенная еще более ясно:

 $ help :
 [...]
 No effect; the command does nothing
 Exit Status:
 Always succeeds.
ilkkachu
источник
s/any command/any sequence of commands/Стефан ясно дает понять.
Тоби Спейт