Насправді програми "if" і "then"


15

Я читав, що крапка з комою використовується для розділення програм:

$ echo 3; ls -la

Це означає це if, thenі чи elseє тут окремі програми?

$ if [ $VARIABLE == abcdef ] ; then echo yes ; else echo no ; fi

Це питання не про крапки з комою.



1
@StephenRauch Насправді не дублікат. Більше того, це розумний ріст від цього Q, як спроба подальшого розуміння.
користувач207673

Більше програмно- [ $variable == abcdef ] && echo yes || echo no
ю

2
@HagenvonEitzen, що не є абсолютно рівнозначним, якщо оператор у першій гілці виходить з ладу, другий також виконає.
Морген

Відповіді:


26

У ;Розділяє висловлювання (грубо кажучи). (Майже) завжди можливо замінити ;новим рядком.

Сказати, що ;розділяє дві програми, отже, ifіthen повинна бути «програмою» є занадто спрощеним , як заява може бути зроблено з зарезервованих слів, оболонки функцій, вбудовані утиліти і зовнішніх інженерних мереж, а також комбінації цих з використанням труб і логічними операторами і т.д. тощо.

Обидва ifі thenє зарезервованими словами в оболонці граматики , а не "програми". Тут вони використовуються для складання того, що технічно називається складною командою .

echoшвидше за все, це вбудована утиліта в оболонці (але її не потрібно), і ls, ймовірно, це зовнішня утиліта (або "програма", як ви говорите).


7

Хоча це справедливе перше наближення, коли ви починаєте вивчати основи використання оболонок, на рівні "ось як запускається програма" і "ось як запускається кілька програм одна за одною в одному рядку" , це насправді не так.

Для початківця важче зрозуміти, але правильніше пояснити, що мова оболонки - це комп'ютерна мова . Він має синтаксис . Цей синтаксис містить різні лексичні елементи, включаючи (серед іншого) нові рядки, оператори, слова та зарезервовані слова.

if, then, else, І fiвсе зарезервовані слова . Вони мають особливе значення під час розбору вхідних даних, які кожен дає оболонці, відповідно до її граматики . Аналогічно ;є оператором розділення .

Таким чином, введення мовою оболонки - це загальноприйнята комп'ютерна програма, що інтерпретується іншою програмою, інтерпретатором , оболонкою. Його окремі граматичні частини не є програмами. Мова оболонки - це спосіб вказати (інші) програми для запуску оболонки.

[не є спеціальним лексичним елементом у граматиці оболонки, такою як оператор. Це звичайне слово , яке називає одну таку програму [. У багатьох оболонках є вбудована версія цієї програми, об'єднана в код самої програми оболонки, але ви також можете знайти зовнішню програму з таким ім'ям десь, наприклад, /bin/[або /usr/bin/[, до якої можуть запускатися інші програми, крім оболонок. Так само ]не є спеціальним лексичним елементом оболонки. Це звичайне слово, яке стає аргументом для [програми. [Програма вимагає , щоб його останній аргумент, коли він виконується, то] , що він приступає до потім ігнорувати.

Ще одна подібна програма, названа у вашому запитанні echo. Знову ж таки, у більшості оболонок є вбудована версія цієї програми. Але знову ж є і зовнішня версія програми, десь на зразок /bin/echoабо /usr/bin/echo, для програм, окрім оболонок, для виклику.

Третя програма, названа у вашому запитанні, - це ls. Оболонки зазвичай не мають вбудованих версій цієї програми, і це зовнішня програма, яку можна знайти десь, наприклад, /bin/lsабо /usr/bin/ls.

Щодо оболонки Bourne Again, ви можете прочитати більше про це в Основних особливостях оболонки документації щодо інформації про оболонку GNU Bourne Again. Інші оболонки, природно, мають різні граматики. Специфікація Single Unix описує синтаксис, до якого повинні дотримуватися всі оболонки, сумісні з POSIX (у своїх режимах, сумісних з POSIX).

Подальше читання

  • « Граматика оболонки ». Мова командної оболонки . Базові специфікації Випуск 7. Відкрита група. IEEE 1003.1-2008. ISBN 1937218812.
  • test. Комунальні послуги . Базові специфікації Випуск 7. Відкрита група. IEEE 1003.1-2008. ISBN 1937218812.
  • « Граматика оболонки ». Посібник із Z Shell . версія 5.3.1. 2017 рік.

5

Це насправді не надумане думати if, thenі в elseякості зовнішніх програм. Насправді оболонка Томпсона в оригінальному першому виданні Unix реалізована ifі gotoяк зовнішні програми. Це можливо, тому що підпроцес поділяє дескриптори файлів з оболонкою, тому (вперед) гото просто потрібно було прочитати вхід, поки він не знайде цільову мітку, а потім вийде. Дивіться оболонку Томпсона .


Або дійсно побачити Laurent Bercot - х ifі ifelse, які є частинами execline. ifОднак це не питання.
JdeBP

2
"Насправді не надумано думати про те, якщо, тоді і інше, як про зовнішні програми" Ну, це так, тому що їх немає.
Гонки легкості з Монікою

2

Програми є thenі elseне є. Інші частини є. Зауважте, що немає ;після них безпосередньо, але після команди, яка їм передує.

[ ... ] Є командою, і потребує; чи з подальшим початком іншої команди.

AFAIK, всі структури управління в Bash, і, мабуть, більшість * nix оболонок, однакові. Вони є вказівками перекладача. Тест або умова, з іншого боку, використовує програму / процес, який "виконується" і є командами. Оскільки thenє частиною рядка, який веде до echoкоманди, його потрібно відокремити новим рядком від попередньої команди [ ... ]. Він не повинен бути відділений від команди він контролює, то echo yes.

Юридично, хоч і некрасиво і важко читати, ви також могли це зробити.

if [ $VARIABLE == abcdef ]
then echo yes
else echo no
fi

Зауважте, що тут взагалі немає необхідності ;між елементами управління, навіть якщо вони не знаходяться в їх власній лінії.

Цікаво, що вся структура управління ( if ... fi) - це команда оболонки, і цілість повинна закінчуватися новим рядком або a ;. Останній рядок не може бути, fi echo doneале повинен бути fi; echo done. Те саме, що і завданняVARIABLE='abcdef' - це команда.

Хоча цілі структури управління - це команди, вони все ще не є програмами.


1

if, elif, then, І fiє всі зарезервовані ключові слова , використовувані для реалізації однієї з конструкцій , згаданих в якості команди з'єднання в оболонці, що означає , що не може бути команда (або , вірніше, інша команда) будь-яким з цих імен в оболонці. Мета ;загалом - не розділяти команди, а скасувати список команд . Наприклад, наступним є дійсне ifтвердження:

if echo foo; echo bar; echo baz; then echo done; echo really done; fi

Умовою ifоператора є список команд echo foo; echo bar; echo baz. Аналізатор знає, що умова закінчена, тому що then, що відразу слідує за комою, не може бути командою, оскільки це зарезервоване ключове слово. Таким чином, він знає, що далі then йде старт тіла. Так само fiє зарезервованим ключовим словом, і тому не може бути третьою командою в тілі ifоператора, але позначає кінець складеної команди.


дякую, якщо це використовується if program1 foo; program2 bar; program3 baz; , який статус програми повинен бути 0, щоб оболонка переходила then? Останній?
Максим Корецький

Просто program3 baz. Статус виходу списку команд - це стан виходу останньої команди у цьому списку. Інші два можуть вийти з ладу, не вплинувши на стан.
чепнер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.