Тестовое условие в команде if

Тестовое условие в команде if

Есть идеи, почему 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очевидно, непустая.

Связанный контент