Моя проблема может быть упрощена до выполнения следующей работы скрипта (который принимает 1 аргумент командной строки):
#!/bin/bash
if ["$1" == "0"]; then
echo "good"
else
echo "bad"
fi
Это должно хорошо печатать, когда я запускаю скрипт 0, но я не могу его получить. Я пробовал различные комбинации котировок вокруг чисел, и я пробовал =, == и -eq. Итак... bash, как это работает?
Ответ 1
[
самом деле это команда. Сделайте ls/bin/[
или ls/usr/bin/[
. Вы увидите, что это фактически исполняемый файл.
[...]
из старых дней оболочки Борна. Команда if
выполняет оператор, и если код выхода этого оператора равен нулю, оператор считается истинным и выполняется условие if. Если код выхода не равен нулю, выполняется условие else (если оно присутствует).
Попробуйте эти:
$ date
Fri May 18 00:04:03 EDT 2012
echo $? #Prints the exit code of the date command
0
$ date -Q #Shouldn't work, I hope...
date: illegal option -- q
usage: date [-jnu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ...
[-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
$ echo $? #Exit code for the date command
1
Вы можете видеть, что эта date
является допустимой командой и возвращает код выхода 0 (значение $?
), Но date -Q
недопустима и возвращает код выхода из 1.
Теперь попробуйте их в выражении if
:
if date
then
echo "I've successfully printed out the date!"
else
echo "I made a mistake in the command"
fi
Теперь попробуйте следующее:
if date -q
then
echo "I've successfully printed out the date!"
else
echo "I made a mistake in the command"
fi
Первоначально [...]
был псевдонимом для команды test
. Следующие эквиваленты:
if test -f /bin/ls #Does a file called /bin/ls exist?
then
echo "There a /bin/ls file"
fi
а также
if [ -f /bin/ls ]
then
echo "There a /bin/ls file"
fi
Вот почему очень важно размещать пробелы вокруг [
и ]
. Потому что это на самом деле команды. В BASH встроены в оболочку, но они являются командами. Это также объясняет, почему все параметры теста (такие как -f
, -z
и -eq
) имеют префикс тире. Они были исходными параметрами для команды test
.
Ответ 2
Используйте пробел между скобкой и аргументом
$ cat x
#!/bin/bash
if [ "$1" == "0" ]; then
echo "good"
else
echo "bad"
fi
$ bash x 0
good
Ответ 3
Используйте двойные скобки для арифметических сравнений, тогда вам не нужно беспокоиться о котировках и расстояниях, например:
#!/bin/bash
if (($1 == 0)); then
echo "good"
else
echo "bad"
fi
Общее правило: используйте (( ))
для арифметики и [[ ]]
для текста и шаблонов.
Как говорили другие, [старый синтаксис оболочки Bourne, и есть несколько причин для его использования.