Заключить в кавычки переменную в сценарии «if»

9

например

if [ "$FOO" = "true" ]; then

против

if [ $FOO = "true" ]; then

Чем отличается? Кажется, оба заявления также работают.

Райан
источник
В Bash используйте двойные квадратные скобки, и вам не нужны кавычки, и вы получите дополнительные преимущества .
Приостановлено до дальнейшего уведомления.
@DennisWilliamson Не совсем, вам нужны кавычки в правой части (в) операторов равенства и сопоставления с образцом.
Жиль "ТАК - перестань быть злым"
@ Жиль: Иногда нет. Для текстовых строк , содержащих пробелы или для текстовых строк или переменных , которые содержат Глоб символы , которые вы хотите , чтобы в буквальном смысле , правая сторона должна быть указана: a='foo bar'; [[ $a == "foo bar" ]]. Однако, переменная , которая не содержит Глоб символы не должны быть: [[ $a == $a ]]. Расширение слова не выполняется в двойных квадратных скобках. А для сопоставления с регулярным выражением шаблон с правой стороны не должен заключаться в кавычки, иначе он будет восприниматься как буквальная строка: [[ $a =~ .*oo.*r ]](однако шаблон должен быть в переменной без кавычек, вместо этого ...
Приостановлено до дальнейшего уведомления.
в буквальном смысле, как здесь). Для Глоб стиля сопоставления с образцом, символы GLOB не должны быть заключены в кавычки, то ли буквальный или в переменной: [[ $a == foo* ]]. Можете ли вы предоставить какие-либо дополнительные примеры требования для цитирования помимо моего примера с литеральной строкой?
Приостановлено до дальнейшего уведомления.

Ответы:

6

Если значение $FOOпредставляет собой одно слово, которое не содержит подстановочный знак \[*?, тогда оба идентичных.

Если $FOOне назначено, или пусто, или более чем одно слово (то есть содержит пробел или $IFS), то версия без кавычек является синтаксической ошибкой. Если это просто правильная последовательность слов (например, 0 -eq 0 -o false), результат может быть произвольным. Поэтому рекомендуется всегда заключать в кавычки переменные в сценариях оболочки.

Кстати, "true"цитировать не нужно.

200_success
источник
3

Чтобы проиллюстрировать, какие проблемы это может вызвать, приведу несколько примеров.

Допустим, у нас есть две переменные следующим образом:

FOO="some value"
BAR="some value"

Теперь у нас есть две переменные, содержащие точно одну строку / значение. Если мы сделали несколько операторов if для проверки результата, в вашем случае:

if [ $FOO = "$BAR" ]; then echo "match"; else echo "no match"; fi

В этот момент вы получите bash: [: too many arguments. $ FOO без кавычек теперь имеет три значения, а именно '[ , some , value'. [Ключевое слово test не знает, что выполнять, поскольку ожидает, что первый или второй аргумент будет оператором.

Когда мы заключаем в кавычки «$ FOO», мы явно говорим, ifчтобы посмотреть на правильные значения, где не происходит разбиение слов.

Другой пример:

my_file="A random file.txt"
  • делать rm $my_fileозначает удалить 'A' 'random' 'file.txt', что делает его тремя файлами.
  • при этом rm "$my_file"будет удален «Случайный файл.txt», который создает один файл.

Надеюсь, я не перепутал вас с этими примерами.

Валентин Байрами
источник
0

В этом конкретном случае нет никакой разницы.

Однако, если он $FOOсодержит пробел или некоторые специальные символы, у вас возникнут проблемы.

В этом "$FOO"случае, он будет использовать переменную в целом, чтобы сделать совпадение, защищающее вас от проблемы пространства.

Однако, если вы используете $FOOи есть особый случай, это повлияет на оператор if.

Якорь,
источник