В том сабреддите хорошо смотрелась бы команда [ -z $var ]
.
Это — конструкция, которая используется в bash для проверки того, является ли переменная пустой. Но тут не хватает кавычек (её более правильный вариант выглядел бы как [ -z «$var» ]
). Это, при работе с переменными, которые могут быть пустыми, часто приводит к неприятностям.
Рассмотрим обратное выражение — [ -n $var ]
, которое проверяет переменную на то, что она является непустой. Та же проблема с кавычками делает её полностью бесполезной:
Причиной возникновения этих проблем является комбинация разделения слов и того факта, что открывающая квадратная скобка,
[
, это не часть синтаксической конструкции командной оболочки, а всего лишь внешняя команда с необычным именем. Я уже об этом писал.
Нахождение результатов работы команды [
зависит от количества аргументов. Значения аргументов гораздо слабее влияют на результат. Вот упрощённая выдержка из описания POSIX-команды test, составляя которую, я не обращал внимания на отрицание:
Если это учесть — становится понятным то, почему команда
[ -n $var ]
в двух случаях ведёт себя неправильно:
- Когда переменная является пустой и при этом не заключена в кавычки, она удаляется, и мы передаём команде 1 аргумент — литеральную строку
-n
. Так как-n
не является пустой строкой — команда выдаётTrue
, а должна была бы выдатьFalse
. - Когда переменная содержит
foo bar
и не заключена в кавычки, она разделяется на два аргумента, в результате мы передаём команде 3 аргумента:-n
,foo
иbar
. Так какfoo
— это не бинарный оператор, результатом работы команды являетсяFalse
(с выдачей сообщения об ошибке), а, на самом деле, результатом должно бытьTrue
.
А теперь посмотрим на то, как работает
[ -z $var ]
:Эта команда выполняет совершенно неправильные и неожиданные действия, обрабатывая пустые строки и те случаи, которые расцениваются как передача нескольких аргументов. Но в обоих случаях ошибки приводят к получению правильных результатов.
Другими словами, [ -z $var ]
работает гораздо лучше, чем этого можно ожидать.
Конечно, это не значит, что я призываю всех отказаться от кавычек. Для “foo bar”
[ -z $var ]
вернёт правильный код выхода, но при этом выведет некрасивое сообщение об ошибке. Для ” ”
(это — строка, в которой имеются только пробелы) вернёт True
, хотя должна вернуть False
, так как соответствующий аргумент удаляется так, как если бы он был пустым. Bash, кроме того, что неправильно, при попытке воспользоваться механизмом внедрения кода, пропустит конструкцию var="foo -o x"
, так как она будет нормально воспринята командой test
.
Какова мораль сей басни? Она такая же, как и всегда: не забывайте о кавычках. Даже тогда, когда кажется, что и без них всё работает как надо.
Утилита ShellCheck знает об этих особенностях. Тут можно проверить код, о котором мы говорили. А именно, анализируя конструкцию [ -n $var ]
, программа разразится гневным сообщением красного цвета, а рассматривая конструкцию [ -z $var ]
— всего лишь покажет обычное зелёное предупреждение об отсутствии кавычек.
Сталкивались ли, при работе в bash, с проблемами, связанными с кавычками?
Комментариев нет:
Отправить комментарий