Ответы:
Одиночные квадратные скобки в оболочке являются синонимом test(либо отдельной команды, либо встроенной оболочки), что [ 0 ]означает то же самое, что и test 0. testпредназначен для сравнения и тестирования атрибутов файлов, о чем вы можете прочитать на его man-странице. Если ему не дано выражение, которое выглядит как сравнение, проверка файла или одна из других операций, которые он может выполнить, он вместо этого проверит наличие аргумента и непустую строку. Ни то, 0ни другое не 1являются подходящими входными данными для теста, и, поскольку проверка непустых строк просто завершается успешно, ваш цикл while зацикливается вечно.
Вы можете попробовать вместо
while false; do
echo "hello"
done
возможно замена falseна true. Или, может быть, вы хотите использовать (( )):
while (( 0 )); do
echo "hello"
done
Который будет вести себя как большинство языков, где 0 означает сбой / ложь, а 1 означает успех / истина.
0и 1не являются пустыми строками. Новые программисты оболочки часто пишут if [ 1=2 ]вместо if [ 1 = 2 ]и задаются вопросом, почему первое всегда верно. Это правда, потому что это один аргумент, а не пустая строка.
Здесь значение 0 действует не как числовая константа, а как строка символов. Все эти тесты эквивалентны по своему действию при получении успешного завершения статуса:
[ A ]
[ "XYZ" ]
[ 0 ]
они производят неудавшийся статус завершения:
[ ]
[ "" ]
есть непустой аргумент, который оценивается как логическое истина. Это позволяет вам делать такие вещи, как:
if [ $UNDER_NUCLEAR_ATTACK ] ; then
launch-missiles -a $DRY_RUN # $DRY_RUN set to "-n" during testing
fi
Переменная UNDER_NUCLEAR_ATTACKустановлена в любое непустое значение, чтобы указать истину, или не установлена или пуста, чтобы указать ложь.
Мы можем применить !оператор, чтобы изменить логику:
[ ! a ] # fails: a is nonblank so true; and not true is false.
[ ! ] # succeeds: blank is false, not blank is true.
Чтобы оценить числовое условие, вы должны использовать числовые тестовые операторы:
while [ $A -gt $B ] ; do ...
Если Aи Bсодержат строки, которые выглядят как десятичные целые числа, они сравниваются как числа, и если Aбольше чем B, цикл выполняется. Итак, предположим, что UNDER_NUCLEAR_ATTACKэто не строковый логический тип, который является пустым или непустым, а фактически числовой логический тип, который имеет значение 0(false) или какое-то другое значение (true). В этом случае мы бы написали тест следующим образом:
if [ $UNDER_NUCLEAR_ATTACK -ne 0 ] ; then ...
Конструкция if / then проверяет, равно ли 0 состоянию завершения списка команд (поскольку 0 означает «успех» по соглашению UNIX), и, если это так, выполняет одну или несколько команд.
Короче говоря, вы возвращаете нулевой результат теста.
[получает только один аргумент (исключая ], конечно), он выходит со статусом ноль, если аргумент не пустой, ненулевой, если это так. Так, например, [ 1 ]также вернет код выхода 0.
Значение 0 считается истинным для цикла while, поэтому условие для цикла while является истинным и, следовательно, оно непрерывно, чтобы показать бесконечный цикл. Значение true, если мы заменим 0 на 1, так как любое целое число, которое мы записываем между условием, вернет true
[ ](без аргумента) и[ "" ](с одним пустым аргументом) не удастся.