Кажется, здесь есть некоторое недопонимание относительно встроенной функции 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!!! Пожалуйста, прочитайте ответ Майка Холта ниже. (Это один из примеров, когда высоко оцененный и принятый ответ ИМХО сбивает с толку и затеняет проницательный контент в менее проголосовавших ответах)