Тут, мабуть, є деякі непорозуміння щодо вбудованого Bash true, а точніше, щодо того, як Bash розширює та інтерпретує вирази всередині дужок.
Код у відповіді miku абсолютно не має нічого спільного з вбудованим Bash true, а /bin/trueтакож будь-яким іншим ароматом trueкоманди. У цьому випадку trueце не що інше, як звичайна символьна рядок, і жоден виклик trueкоманди / вбудованого не робиться ні за призначенням змінної, ні за допомогою оцінки умовного виразу.
Наступний код функціонально ідентичний коду у відповіді miku:
the_world_is_flat=yeah
if [ "$the_world_is_flat" = yeah ]; then
echo 'Be careful not to fall off!'
fi
Тільки різниця полягає в тому , що чотири символи порівнюваних «у», «е», «а» і «ч» замість «т», «г», «і», і «е». Це воно. Немає спроб викликати команду чи вбудовану назву yeah, а також немає (на прикладі Міку) ніяких спеціальних операцій, коли Bash розбирає маркер true. Це просто рядок і зовсім довільний.
Оновлення (19.02.2014): Після переходу за посиланням у відповіді Міку, тепер я бачу, звідки йде певна плутанина. У відповіді Міку використовуються одинарні дужки, але фрагмент коду, на який він посилається, не використовує дужки. Це просто:
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").
Крім того, хоча вони =і ==взаємозамінні, ви повинні мати на увазі, що те, як працюють ці тести , залежить від того, використовуєте ви його всередині, [ ]або [[ ]], а також від того, цитуються операнди чи ні. Докладніше про це можна прочитати в Посібнику з розширеного сценарію Bash: 7.3 Інші оператори порівняння (прокрутіть до обговорення =та ==).
trueіfalseв контексті більшість фрагментів нижче тільки прості рядки, а НЕ тоbash built-ins!!! Будь ласка, прочитайте відповідь Майка Хольта нижче. (Це один із прикладів, коли відповідь, що отримала високу оцінку і прийнята, - ІМХО заплутаний і затьмарює проникливий зміст у менших проголосованих відповідях)