скрипт bash [x $ 1 = x]

Я читаю скрипт bash. Я не понимаю, что там происходит.

#!/bin/sh
[ x$1 = x ] 

Что происходит во второй строке и что означает [ x$1 = x ]?

16 голосов | спросил Bob 11 J0000006Europe/Moscow 2014, 21:43:51

3 ответа


21

Это проверяет, что $1 пуст, хотя он должен быть указан (идентичен [ -z "$1" ]). Некоторые очень старые оболочки не обрабатывали пустые строки правильно, поэтому авторы переносимых скриптов приняли этот стиль проверки. Это не было необходимо десятилетиями, но люди все еще так поступают, потому что люди все еще так поступают.

ответил Kevin 11 J0000006Europe/Moscow 2014, 22:01:09
4
[ x$1 = x ]

Имеет смысл только в zsh. Это сравнивает конкатенацию x с первым аргументом скрипта на x. Поэтому команда [ возвращает true, если $1 пуст или не предоставляется.

[ $1 = "" ]

Не работает, потому что в zsh, когда пустая переменная не цитируется в контекстах списка, она вообще не расширяет аргумент вместо пустого аргумента, поэтому, если $1 были сброшены или пусты, [ будет принимать только в качестве аргументов [, =, пустая строка и ], из которой она не может быть понятна. [ -z "$1" ] или [ "$1" = "" ] будет нормально, хотя вроде в оболочках POSIX.

В Bourne-like /POSIX-оболочках [ x$1 = x ] не имеет смысла. Это оператор split + glob каким-то образом применяется к конкатенации x и первому аргументу скрипта, надеясь, что результат и = и x и ] составляют действительное тестовое выражение для команды [.

Например, если скрипт был передан один " = x -o x =", [ получит следующие аргументы: [, x, =, x, -o, x, =, x, ], который [ будет понимать как сравнение x с помощью x и x с помощью x и вернуть true.

Если $1 были "* *", то оболочка передаст команду [ список файлов в текущем каталоге, имя которого начинается с x (расширение glob x*), затем список не скрытых файлы (расширение *) ... который [ вряд ли сможет сделать какой-либо смысл. Единственные случаи, когда это могло бы сделать что-либо разумное, - это если $1 не содержит подстановочные или пустые символы.

Теперь, что вы иногда находите, это код вроде:

[ "x$1" = x ]

Это используется для проверки, если $1 пуст или не установлен.

Обычным способом проверки пустой или неустановленной переменной является:

[ -z "$1" ]

Но это не удается для некоторых значений $1, например = в некоторых (не-POSIX) [ реализациях, таких как встроенный в оболочку Bourne, как /bin/sh в Solaris 10 и раньше или несколько старых версий dash (до 0.5.4) или sh некоторых BSD.

Это потому, что [ видит [ , -z, =, ] и жалуется на отсутствие аргументов для двоичного оператора = вместо того, чтобы понимать его как унарный оператор -z, примененный к =.

Аналогично, [ "$1" = "" ] не работает для некоторых реализаций [, если $1 есть ! или (.

В этой оболочке /[Реализации:

[ "x$1" = x ]

всегда является действительным тестом независимо от значения $1, а именно:

[ "" = "$1" ]

и

[ -z "${1:+x}" ]

и

case $1 in "") ...; esac

Конечно, если вы хотите проверить, что аргумент не предоставлен, вы должны:

[ "$#" -eq 0 ]

То есть вы проверяете количество аргументов, переданных скрипту.

Обратите внимание, что в настоящее время [ -z "$var" ] явно указывается POSIX и не может не работать в соответствии с кодом [bash '[ есть и был на протяжении десятилетий). Таким образом, вы должны быть в состоянии полагаться на него в сценариях POSIX sh или bash.

ответил Stéphane Chazelas 17 J0000006Europe/Moscow 2014, 02:18:43
0

x$1 объединяет две строки x и $1, а если $ 1 пуст, x $ 1 равно x, а в результате будет [x $ 1 = x]. x = y используется для сравнения строки в sh

ответил harish.venkat 11 J0000006Europe/Moscow 2014, 22:01:17

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132