Гнук делает важное замечание, не подчеркивая его:
всякий раз, когда вы ссылаетесь на переменную оболочки ( $ идентификатор
, например, $ futur
)
или позиционный параметр ( $ цифра
, например, $ 1
),
вы должны заключить его в двойные кавычки
(например, "$ 1"
), если у вас нет веской причины не
и вы совершенно уверены, что знаете, что делаете.
Постоянные строки без специальных символов (например, A
, foo
или bar
)
цитировать не нужно, но это не повредит.
Строки в кавычках можно объединять и комбинировать;
например, «foo» «bar»
эквивалентно «foobar»
,
и «$ 1»
эквивалентно «A» «$ 1»
и, следовательно, «A $ 1»
.
Цитаты сохраняют существование пустых строк. Как объясняет Гноук, если в вашем скрипте указано
if ($ 1 == "")
и вы вызываете его без аргументов,
СПИСОК
или с явным аргументом пустой строки,
LIST ""
, тогда оператор if
будет «развернут» как
if (== "")
, что вызывает синтаксическую ошибку.
Кавычки сохраняют целостность строк с пробелами или специальными символами. Если вы вызываете свой скрипт с аргументом, содержащим пробел,
LIST "foo bar"
, то оператор if
( if (A $ 1 == A)
) будет расширен как
if (Afoo bar == A)
, что вызывает синтаксическую ошибку. Аналогичные результаты будут, если вы вызовете свой скрипт с аргументом, содержащим подстановочный знак в кавычках:
LIST "foo *"
Но никто не объяснил, почему сценарий не просто говорит
if ( "$1" == "" )
В предыдущих версиях csh
, если вы вызываете свой сценарий с этим аргументом,
LIST ==
тогда Оператор if
будет расширен как
if ( "==" == "" )
, что также вызвало синтаксическую ошибку.
Люди писали свои if
операторы с защитой позиционных параметров.
(и, при необходимости, переменные оболочки / переменные среды),
например A $ 1
или «A $ 1»
, чтобы аргументы (операнды) не выглядели как операторы
(в частности, /
, также +
, -
и *
), что приводит к путанице анализатора.
Кажется, это было исправлено (по крайней мере, в некоторых версиях csh
/ tcsh
).
Я только что попробовал это в своей (Cygwin) версии tcsh
:
$ if ( == == "" ) echo yes if: Expression Syntax. $ if ( == == == ) echo yes if: Expression Syntax. $ if ( "==" == "" ) echo yes <--- (no output) $ if ( "==" == "==" ) echo yes yes $ if ( / == / ) echo yes Division by 0. $ if ( "/" == "/" ) echo yes yes
так,
if
в tcsh
, что аргумент это операнд
а не оператор. Убедитесь, что $1
- это не пустая строка. Если $1
пустая строка, то если условие:
( A == A )
оценивается как истинное. Это обходной путь, чтобы убедиться, что у вас нет синтаксической ошибки. Если просто сделать:
if ( $1 == "" )
Когда $1
пустая строка, то это выражение становится ( == "" )
и приводит к синтаксической ошибке.
Как минимум в bsd-csh
, tcsh
, ( $1 == "" )
работает. С оригинальным csh
следует использовать:
if ( "A$1" == "A" )
Заметку о том, что Вы всегда должны заключать в кавычки двойную переменную, см. объяснение здесь. В csh
, если переменная $a
содержит newline, то "$a"
не сработает, Вам нужно $a:q
.
В этой строке проверяется, пуст ли 1
. $1
- это первый параметр, переданный пользователем скрипту при выполнении скрипта в командной строке. Если $1
пустой, то к букве A
ничего не добавляется и A == A
истинно.
Я считаю, что цикл if
используется как способ проверить, переданы ли аргументы сценарию или нет. Хотя технически это цель цикла if
, я думаю, было бы более уместно сказать, что он используется для проверки, является ли $ 1
пустым или нет. Например, я скопировал сценарий и вызвал его как,
script "some_argument"
Как и ожидалось, он не входит в цикл if
. Теперь, если я вызываю его без каких-либо параметров как,
script
, я получаю вывод как LIST
Итак, я добавил оператор echo
непосредственно перед циклом if, чтобы проверить аргументы, переданные в сценарий. Итак, если я вызову сценарий без аргументов, он войдет в цикл if
.
Кроме того, A $ 1 == A
- это просто то, что нужно для проверки, является ли $ 1 пустым или нет. Даже если у вас есть что-то вроде, somethingvalid $ 1 == somethingvalid
и вы вызываете сценарий как script
, он все равно попадет в цикл if
и распечатает результат.