Я читаю скрипт bash Я не понимаю, что там происходит.
#!/bin/sh
[ x$1 = x ]
Что происходит на второй линии и что [ x$1 = x ]
значит?
Это проверяет, что $1
пусто, хотя оно должно быть заключено в кавычки (идентично [ -z "$1" ]
). Некоторые очень старые оболочки не обрабатывали пустые строки должным образом, поэтому разработчики переносимых сценариев приняли этот стиль проверки. В течение десятилетий в этом не было необходимости, но люди все еще так делают, потому что люди все еще так делают.
[ x$1 = x ]
все еще неверно, но[ "x$1" = x ]
будет для оболочек, у которых есть проблема, где$1
есть!
или(
или-n
....[ "" = "$1" ]
иcase $1 in "")
также будет в порядке, хотя.[ -z "$1" ]
и[ "$1" = "" ]
до сих пор не работает с / bin / sh Solaris 10, первый с dash-0.5.4.[ "$1" = "" ]
до сих пор не работает с ней/bin/sh
(хотя вы бы хотели использовать ее/usr/xpg4/bin/sh
там, а не/bin/sh
). черта была исправлена в этом отношении в январе 2009 года.Квадратные скобки указывают на тест , поэтому
[ x$1 = x]
безif
или что-то подобное бессмысленно, хотя синтаксически нормально.Он предназначен для оценки true, если
x$1
расширяется доx
, и false в противном случае, но, поскольку он не заключен в кавычки, если$1
(например) "hey x", оболочка увидитx = x
, поэтому эта конструкция все еще небезопасна.Цель
x = x
проверки - определить, является ли переменная пустой. Более распространенный способ сделать это - просто использовать кавычки:Операторы тестирования Bash
-z
и-n
также могут быть использованы, но они менее переносимые на другие типы оболочек. 1Причина кавычек, или, в том
x$1
, что левая часть не расширяется ни к чему, что было бы синтаксической ошибкой:1. На самом деле
test
может быть автономной утилитой, но большинство оболочек реализуют ее как встроенную; проверьте разницу междуwhich test
иtype test
. В GNU / Linuxman test
утверждается, что он ссылается на встроенный, но если вы вызываете (например)/usr/bin/test
, эта утилита, кажется, реализует функции, описанные на странице руководства, включая-z
и-n
.источник
[ x$1 = x ]
также оценивается как истинное, если,$1
например" -o x"
. Попробуйsh -xc '[ x$1 = x ] && echo yes' sh ' -o x'
.[ x$1 = x ]
неправильно и не имеет смысла.if
to usetest
, you can use it before&&
,||
or afterwhile
or examine the result using$?
Имеет смысл только в
zsh
. Это сравнивает конкатенациюx
с первым аргументом скрипта сx
. Таким образом,[
команда возвращает true, если$1
она пуста или не указана.Не будет работать , потому что, в
zsh
когда пустая переменная не указаны в списке контекстов, он расширяется без аргумента вообще вместо пустого аргумента, так что, если$1
было задано или пустой, то[
команда получит только в качестве аргументов[
,=
пустая строка и из]
которого это не могло иметь смысла.[ -z "$1" ]
или[ "$1" = "" ]
было бы хорошо, хотя, как в оболочках POSIX.В Bourne-подобных оболочках / POSIX,
[ x$1 = x ]
не имеет смысла. Это оператор split + glob, каким-то образом примененный к конкатенацииx
и первому аргументу скрипта, в надежде получить результат и=
иx
, и]
составить правильное тестовое выражение для[
команды.Например, если сценарий был передан один
" = x -o x ="
аргумент,[
получат эти аргументы:[
,x
,=
,x
,-o
,x
,=
,x
,]
, что[
бы понять , как сравнениеx
сx
иx
сx
и возвращает истину.Если бы
$1
были"* *"
, то оболочка передала бы[
команде список файлов в текущем каталоге, имя которого начинается сx
(расширение globx*
), тогда список не скрытых файлов (расширение*
) ... что[
вряд ли сможет иметь какой-либо смысл из. Единственные случаи, когда это могло бы сделать что-нибудь разумное, это если$1
они не содержат подстановочных знаков или пустых символов.Теперь, что вы иногда находите, это код:
Это используется для проверки, если
$1
он пуст или не установлен.Обычный способ проверить пустую или неустановленную переменную:
Но это не работает для некоторых значений
$1
подобно=
в некоторых (не POSIX)[
реализациях, таких как встроенная в оболочку Bourne, как в/bin/sh
Solaris 10 и ранее, или в некоторых старых версияхdash
(до 0.5.4) илиsh
некоторых BSD.Это потому , что
[
видит[
,-z
,=
,]
и жалуется на отсутствующие аргументы=
бинарного оператора вместо понимания его как-z
унарный оператор применяется к=
строке.Точно так же,
[ "$1" = "" ]
терпит неудачу для некоторых реализаций[
if$1
is!
или(
.В этих оболочках /
[
реализациях:всегда является действительным тестом независимо от значения
$1
, поэтому:а также:
а также
Конечно, если вы хотите проверить, что аргумент не предоставлен, вы должны сделать:
То есть вы проверяете количество аргументов, переданных скрипту.
Обратите внимание, что в настоящее время
[ -z "$var" ]
он четко определен POSIX и не может дать сбой в совместимых[
реализациях (аbash
это[
есть и было на протяжении десятилетий). Так что вы должны быть в состоянии положиться на него в POSIX sh илиbash
скриптах.источник
x$1
объединяет две строкиx
и,$1
если $ 1 пусто, x $ 1 равно x, и в результате [x $ 1 = x] будет истинным.x = y
используется для сравнения строки в shисточник
x$1
не указано, поэтому для них выполняется разбиение и подстановка.[ x$1 = x ]
Истинно, если$1
не установлено / пусто / пусто или нет.Попробуйте себя с:
TEST= ;[ x$TEST = x] && echo "TEST is unset"
и
TEST=lolz ;[ x$TEST = x ] && echo "TEST is unset"
источник
[ x$1 = x ]
также верно, если,$1
например" -o x"
. Попробуйsh -xc '[ x$1 = x ] && echo yes' sh ' -o x'
.[ x$1 = x ]
неправильно и не имеет смысла.