2013-05-30 4 views
-1

Я пытаюсь понять, что именно представляет собой код bash, упомянутый ниже, чтобы попытаться сделать, особенно часть [-z $M ]. здесь M является переменной со значениемBash Script Понимание

if [ -z $M ] ; then 
    can not find module directory 
    exit 1 
+0

Сделайте текстовый поиск [здесь] (http://www.gnu.org/software/bash/manual/html_node/Bash-Conditional-Expressions.html) для '-z'. – ajp15243

ответ

7
  1. man testВведите
  2. пресс /-гВведите

Вы видите:

-z STRING 
       the length of STRING is zero 

Ваш скрипт делает, если $M длина == 0, то выход с кодом состояния 1

+0

Итак, правильный перевод Python для этого должен быть примерно таким: if $ M == 0: print "Not Valid" close() - это правильный Kent? – Nick

+1

Возможно, 'man [' будет в этом случае? –

+3

Это был самый добрый способ сказать RTFM, который я когда-либо видел: D –

0

Он проверяет содержание переменной M ли пустая строка.

Проверить это link

1

[ фактически стандартная команда Unix (возможно реализован внутри в Bash, но доступны независимо от оболочки вы используете). Он является псевдонимом для команды test, поэтому его ввод вручную можно найти, набрав man test. Вот an online copy of that manual page.

При вызове в качестве [, test обычно ожидают его последний аргумент, чтобы быть ], просто для хорошего внешнего вида, так [ -z $M ] эквивалентно test -z $M.

В этом случае аргумент -z вызывает test, чтобы возвращать значение true, если следующий аргумент представляет собой строку с длиной нуля. Переменная $M, определенная далее по сценарию, может быть проверена на допустимое значение.

3

Как говорили другие, используется команда test (aka [), чтобы проверить, является ли строка пустой. По крайней мере, это то, что он пытается сделать; потому что строка ($M) не имеет двойных кавычек, она на самом деле делает что-то немного другое. Без двойных кавычек значение $M претерпевает расщепление слов и расширение подстановочных знаков после его замены, поэтому его нельзя рассматривать как простую строку (с которой работает оператор -z) с ... потенциально неожиданными последствиями. Позвольте мне бежать через некоторые из возможностей:

  • Если значение $M это одно слово (не пустой) без масок (* и ?), все работает, как ожидалось.
  • Если значение $M имеет нулевую длину (пробел), команда test видит только один аргумент (-z); когда для теста задан только один аргумент, он просто проверяет, является ли он пустым - это не так, поэтому он оценивает значение true.

    Это ожидаемый результат в этом случае, но это просто по совпадению, и со многими другими операторами это не будет правильным результатом.Например, [ -n $M ] (похоже, что он должен проверить, является ли $M * незаполненным), [ -e $M ] (похоже, что он должен проверить, является ли $M - имя файла/каталога) и т. Д. Все будут оцениваться как true, если $M пуст.

  • Если значение $M полностью состоит из пробелов (но не пусто), оно устраняется до того, как test видит его, а test оценивает true (см. Предыдущий случай). Это может быть или не быть тем, что имел в виду сценарист.
  • Если значение $M имеет несколько слов, test попытается оценить его как (часть) выражения. Вероятно, это не будет допустимым выражением, и в этом случае test напечатает ошибку и вернет false (что правильно ... вроде).

    С другой стороны, если это допустимое выражение ... Предположим, например, у вас было M='= -z; test оценил бы выражение -z = -z, которое было бы истинным, совсем не то, что имел в виду скриптер.

  • Если значение $M имеет любые подстановочные знаки, оболочка будет пытаться сопоставить их с файлами и передать test список совпадений; он попытается оценить их как выражение (см. предыдущий случай), возможно, выдает ошибку и возвращает false (опять же, вроде как правильно).

    Учтите, что если вы установили опцию оболочки nullglob и подстановочный знак не соответствует никаким файлам, оболочка заменит его на нуль, и скрипт будет действовать так, как будто «u * n * m * a * t * c * h * e * d "- пустая строка.

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

+0

вы также можете использовать двойные квадратные скобки [[]] для предотвращения подстановочных махинаций (если вы человек bash/ksh, более старые оболочки, вероятно, взорвутся) – stringy05

+1

@ stringy05: Да, '[[]]' очищает много острых краев в синтаксисе '[]' s, но есть еще несколько случаев, когда вопрос о двойных кавычках. Например, '[[$ a = $ b]]' будет обрабатывать '$ b' как шаблон (если он содержит подстановочные знаки), тогда как' [["$ a" = "$ b"]] 'выполняет прямое равенство сравнение. –

+0

Хорошая точка @GordonDavisson, я, кажется, помню, что двойные скобки хороши при использовании '==', а не '='. Когда я писал сценарии оболочки все время, я был совершенно параноидальным. Я бы это сделал: '[[" $ {a} "==" $ {b} "]]' – stringy05