Есть идеи, почему echo
оператор выполняется в обоих сценариях?
Выходы it worked
:
#!/bin/bash
rizwan=''
if [ -n $rizwan ]; then
echo "it worked"
fi
Замените -n
на -z
, и он выведет, it worked
хотя не ожидает никакого вывода:
#!/bin/bash
rizwan=''
if [ -z $rizwan ]; then
echo "it worked"
fi
решение1
Вы можете знать это или нет, но давайте проясним: [
не является частью синтаксиса if
. Я имею в виду, if [ …
ведет себя как if true
, if false
или if any_command
, где [
, true
, false
и any_command
являются командами. Они возвращают статус выхода, и это то, что важно для if
.
Даже если [
это встроенная команда (и она есть в Bash), она ведет себя как обычная команда. Есть даже отдельный [
исполняемый файл (например /usr/bin/[
), потому что это требуется POSIX.
Это означает, [ -n whatever ]
что это просто [
команда с несколькими аргументами. Да, ]
это просто аргумент, это не разделитель или что-то в этом роде. Названная команда [
просто требует ]
, чтобы это был ее последний аргумент. Таким образом, код более разборчив, ]
не служит никакой другой цели.
Команда test
эквивалентна [
. Единственное отличие — test
не требует ]
.
[ -n whatever ]
эквивалентна test -n whatever
.
Если оболочка расширяется $rizwan
до пустой строки, фрагменты [ -n $rizwan ]
и [ -z $rizwan ]
становятся [ -n ]
и [ -z ]
соответственно. [
Команда не знает, что между -n
(или -z
) и ]
в вашем коде что-то было, она получает ровно два аргумента. Оба теста рассматриваются как синтаксис, [ STRING ]
где STRING
есть либо -n
или -z
. Этот синтаксис проверяет, STRING
не пусто ли. Ваши тесты всегда завершаются успешно, потому что ни то, ни -n
другое не -z
является пустой строкой.
Чтобы заставить фрагменты работать как [ -n STRING ]
или [ -z STRING ]
, вам нужно заключить переменную в двойные кавычки. Оболочка после расширения [ -z "$rizwan" ]
передаст точнотриаргументы для [
. Это будут -z
, развернутое значение переменной (даже если это пустая строка) и ]
. Инструмент получит все аргументы, которые вы хотели получить.
Если $rizwan
в ваших примерах без кавычек развернуто более чем на одно слово, то [
будет получено более трех аргументов. В общем, конечный результат будет зависеть от содержимого переменной и реализации [
.
СравниватьПочему мой скрипт оболочки тормозит пробелы и другие специальные символы?.
Примечание [[
в Bash отличается. Это ключевое слово, оно интегрировано с парсером оболочки, оно изменяет некоторые правила, оно на самом деле знает о переменных и кавычках между [[
и ]]
. Если вы использовали [[
вместо [
(и, следовательно, ]]
вместо ]
), то ваш код будет работать так, как вы ожидали. Смотритеэтот ответ.
[
является портативным.
решение2
Поскольку переменная rizwan
пуста, ваша if
команда становится такой:
if [ -n ]
Синтаксис [ STRING ]
проверяет, является ли строка пустой (нет символов). Так что в вашем случае [ -n ]
строка, -n
очевидно, непустая.