Кажется, здесь есть некоторое недопонимание относительно встроенной функции Bash true
, а более конкретно, о том, как Bash расширяет и интерпретирует выражения в квадратных скобках.
Код в ответе miku не имеет ничего общего ни со встроенной системой Bash true
, /bin/true
ни с каким-либо другим видом true
команды. В этом случае true
это не что иное, как простая символьная строка, и никакой вызов true
команды / встроенной функции никогда не выполняется ни с помощью присваивания переменной, ни с помощью вычисления условного выражения.
Следующий код функционально идентичен коду в ответе мику:
the_world_is_flat=yeah
if [ "$the_world_is_flat" = yeah ]; then
echo 'Be careful not to fall off!'
fi
Только разница состоит в том , что четыре символа сравниваемых «у», «е», «а» и «ч» вместо «т», «г», «и», и «е». Вот и все. Не было предпринято никаких попыток вызвать команду или встроенный объект named yeah
, а также (в примере miku) никакой особой обработки не происходит, когда Bash анализирует токен true
. Это просто строка, причем совершенно произвольная.
Обновление (2014-02-19): после перехода по ссылке в ответе мику, теперь я вижу, откуда происходит некоторая путаница. В ответе Мику используются одиночные скобки, но фрагмент кода, на который он ссылается, не использует скобки. Это просто:
the_world_is_flat=true
if $the_world_is_flat; then
echo 'Be careful not to fall off!'
fi
Оба фрагмента кода будут вести себя одинаково, но скобки полностью изменят то, что происходит под капотом.
Вот что Bash делает в каждом случае:
Без скобок:
- Разверните переменную
$the_world_is_flat
до строки "true"
.
- Попытайтесь проанализировать строку
"true"
как команду.
- Найдите и запустите
true
команду (встроенную или /bin/true
, в зависимости от версии Bash).
- Сравните код завершения
true
команды (который всегда равен 0) с 0. Напомним, что в большинстве оболочек код выхода 0 указывает на успех, а все остальное указывает на сбой.
- Так как код выхода был 0 (успех), выполнить в
if
заявлении , в then
положение
Скобки:
- Разверните переменную
$the_world_is_flat
до строки "true"
.
- Разберите теперь полностью расширенное условное выражение, которое имеет форму
string1 = string2
. =
Оператор в Bash сравнения строк оператора. Так...
- Сделайте сравнение строк на
"true"
и "true"
.
- Да, две строки были одинаковыми, поэтому значение условного выражения истинно.
- Выполнить предложение
if
оператора then
.
Код без скобок работает, потому что true
команда возвращает код завершения 0, который указывает на успех. Код в квадратных скобках работает, потому что значение $the_world_is_flat
идентично строковому литералу true
в правой части =
.
Просто чтобы понять суть, рассмотрим следующие два фрагмента кода:
Этот код (если он запускается с правами root) перезагрузит ваш компьютер:
var=reboot
if $var; then
echo 'Muahahaha! You are going down!'
fi
Этот код просто печатает "Хорошая попытка". Команда перезагрузки не вызывается.
var=reboot
if [ $var ]; then
echo 'Nice try.'
fi
Обновление (2014-04-14) Чтобы ответить на вопрос в комментариях относительно разницы между =
и ==
: AFAIK, нет никакой разницы. ==
Оператор является Bash-специфический синоним =
, и, насколько я видел, они работают точно так же во всех контекстах.
Заметьте, однако, что я специально говорю об операторах сравнения =
и и ==
строк, используемых в тестах [ ]
или [[ ]]
. Я не утверждаю , что =
и ==
являются взаимозаменяемыми везде в Баш.
Например, вы, очевидно, не можете выполнять присваивание переменных ==
, например var=="foo"
(технически вы можете сделать это, но значение var
будет "=foo"
, потому что Bash не видит ==
здесь оператора, он видит оператор =
(присваивания), за которым следует буквальное значение ="foo"
, которое просто становится "=foo"
).
Кроме того, хотя =
и ==
являются взаимозаменяемыми, вы должны иметь в виду, что как эти тесты работают , зависит от того, используете ли вы его внутри [ ]
или [[ ]]
, а также от того, заключены ли в кавычки операнды. Вы можете прочитать больше об этом в Advanced Bash Scripting Guide: 7.3 Другие операторы сравнения (прокрутите вниз до обсуждения =
и ==
).
true
иfalse
в контексте большинство фрагментов ниже только простые строки, а не тоbash built-ins
!!! Пожалуйста, прочитайте ответ Майка Холта ниже. (Это один из примеров, когда высоко оцененный и принятый ответ ИМХО сбивает с толку и затеняет проницательный контент в менее проголосовавших ответах)