Русский
Русский
English
Статистика
Реклама

Перевод О неоправданно хорошей работе -z var

Есть такой сабреддит /r/nononoyes, где публикуют видео, в которых происходит что-то такое, что, на первый взгляд, кажется ужасно неправильным, идущим к катастрофе. Но в конце всё, чудесным образом, заканчивается хорошо.

В том сабреддите хорошо смотрелась бы команда [ -z $var ].



Это конструкция, которая используется в bash для проверки того, является ли переменная пустой. Но тут не хватает кавычек (её более правильный вариант выглядел бы как [ -z $var ]). Это, при работе с переменными, которые могут быть пустыми, часто приводит к неприятностям.

Рассмотрим обратное выражение [ -n $var ], которое проверяет переменную на то, что она является непустой. Та же проблема с кавычками делает её полностью бесполезной:

Входные данные Ожидаемый результат [ -n $var ]
""
False
True!
"foo"
True
True
"foo bar"
True
False!

Причиной возникновения этих проблем является комбинация разделения слов и того факта, что открывающая квадратная скобка, [, это не часть синтаксической конструкции командной оболочки, а всего лишь внешняя команда с необычным именем. Я уже об этом писал.

Нахождение результатов работы команды [ зависит от количества аргументов. Значения аргументов гораздо слабее влияют на результат. Вот упрощённая выдержка из описания POSIX-команды test, составляя которую, я не обращал внимания на отрицание:

Количество аргументов Действие Типичный пример
0 Возврат False.
[ ]
1 Возврат True, если аргумент $1 не является пустым.
[ "$var" ]
2 Применение унарного оператора $1 к $2.
[ -x "/bin/ls" ]
3 Применение бинарного оператора $2 к $1 и к $3.
[ 1 -lt 2 ]

Если это учесть становится понятным то, почему команда [ -n $var ] в двух случаях ведёт себя неправильно:

  • Когда переменная является пустой и при этом не заключена в кавычки, она удаляется, и мы передаём команде 1 аргумент литеральную строку -n. Так как -n не является пустой строкой команда выдаёт True, а должна была бы выдать False.
  • Когда переменная содержит foo bar и не заключена в кавычки, она разделяется на два аргумента, в результате мы передаём команде 3 аргумента: -n, foo и bar. Так как foo это не бинарный оператор, результатом работы команды является False (с выдачей сообщения об ошибке), а, на самом деле, результатом должно быть True.

А теперь посмотрим на то, как работает [ -z $var ]:

Входные данные Ожидаемый результат [ -z $var ] Команда test
""
True: пустая переменная
True
1 аргумент: проверка того, является ли -z непустой переменной
"foo"
False: непустая переменная
False
2 аргумента: применение -z к foo
"foo bar"
False: непустая переменная False (ошибка) 3 аргумента: применение foo к -z и bar

Эта команда выполняет совершенно неправильные и неожиданные действия, обрабатывая пустые строки и те случаи, которые расцениваются как передача нескольких аргументов. Но в обоих случаях ошибки приводят к получению правильных результатов.

Другими словами, [ -z $var ] работает гораздо лучше, чем этого можно ожидать.

Конечно, это не значит, что я призываю всех отказаться от кавычек. Для foo bar [ -z $var ] вернёт правильный код выхода, но при этом выведет некрасивое сообщение об ошибке. Для (это строка, в которой имеются только пробелы) вернёт True, хотя должна вернуть False, так как соответствующий аргумент удаляется так, как если бы он был пустым. Bash, кроме того, что неправильно, при попытке воспользоваться механизмом внедрения кода, пропустит конструкцию var="foo -o x", так как она будет нормально воспринята командой test.

Какова мораль сей басни? Она такая же, как и всегда: не забывайте о кавычках. Даже тогда, когда кажется, что и без них всё работает как надо.

Утилита ShellCheck знает об этих особенностях. Тут можно проверить код, о котором мы говорили. А именно, анализируя конструкцию [ -n $var ], программа разразится гневным сообщением красного цвета, а рассматривая конструкцию [ -z $var ] всего лишь покажет обычное зелёное предупреждение об отсутствии кавычек.

Сталкивались ли, при работе в bash, с проблемами, связанными с кавычками?


Источник: habr.com
К списку статей
Опубликовано: 30.05.2021 18:13:46
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Блог компании ruvds.com

Системное администрирование

*nix

Linux

Ruvds_переводы

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru