Являются ли `if` и` then` собственно программами

15

Я читал, что точка с запятой используется для разделения программ:

$ echo 3; ls -la

Значит ли это if, thenи elseесть ли здесь отдельные программы?

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

Этот вопрос не о точках с запятой.

Максим Корецкий
источник
2
Возможный дубликат точки с запятой в условных структурах
Стивен Раух
1
@StephenRauch Не совсем дубликат. Более того, это разумный результат этого вопроса, как попытка дальнейшего понимания.
user207673
Более программная формулировка:[ $variable == abcdef ] && echo yes || echo no
Хаген фон
2
@HagenvonEitzen, который не является строго эквивалентным, если оператор в первой ветви завершится неудачно, вторая также будет выполнена.
Морген
Возможные дубликаты Каковы операторы управления и перенаправления оболочки?
G-Man говорит: «Восстановите Монику»

Ответы:

26

В ;Разделяет высказывания (грубо говоря). (Почти) всегда можно заменить ;символом новой строки.

Чтобы сказать это ; разделяет две программы, поэтому ifи thenдолжна быть «программой» является слишком упрощенным , как заявление может быть сделано из зарезервированных слов, оболочки функций, встроенные утилиты и внешних инженерных сетей, а также комбинации этих с использованием труб и логическими операторами и т.д. . и т.д.

Оба ifи thenявляются зарезервированными словами в грамматике оболочки , а не «программами». Здесь они используются для создания того, что технически называется составной команды .

echoскорее всего, встроенная утилита в оболочке (но не обязательно) и ls, вероятно, внешняя утилита (или, как вы говорите, «программа»).

Kusalananda
источник
7

Хотя это первое справедливое приближение, когда вы начинаете изучать основы использования оболочек, на уровне «вот как вы запускаете программу» и «вот как вы запускаете несколько программ одну за другой в одной строке» это не совсем так.

Новичку труднее понять, но более правильное объяснение состоит в том, что язык оболочки - это компьютерный язык . У него есть синтаксис . Этот синтаксис включает в себя различные лексические элементы, включая (среди прочего) переводы строк, операторы, слова и зарезервированные слова.

if, then, else, И fiвсе зарезервированные слова . Они имеют особое значение при разборе ввода, которое вы даете оболочке, в соответствии с ее грамматикой . Точно так же ;это разделитель оператором- .

Таким образом, ввод на языке оболочки в целом представляет собой компьютерную программу, которая интерпретируется другой программой- интерпретатором. , оболочкой. Его отдельные грамматические части не являются программами. Язык оболочки - это способ указания (других) программ для запуска оболочки.

[не является специальным лексическим элементом в грамматике оболочки, таким как оператор. Это обычное слово , которое называет одну такую ​​программу с именем [. Многие оболочки имеют встроенную версию этой программы, объединенную в код самой программы оболочки, но вы также можете найти внешнюю программу под этим именем, например, /bin/[или /usr/bin/[, которую могут вызывать другие программы, кроме оболочек. Точно так же ]не является специальным лексическим элементом оболочки. Это обычное слово, которое становится аргументом для [программы. [Программа требует , чтобы его последний аргумент, когда он выполняется, то ], что он приступает к затем игнорировать.

Другая похожая программа, названная в вашем вопросе echo. Опять же, большинство оболочек имеют встроенную версию этой программы. Но опять же, существует также внешняя версия программы, где-то, например, /bin/echoили /usr/bin/echo, для запуска программ, отличных от оболочек.

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

Об оболочке Bourne Again вы можете узнать больше об этом в разделе Основные функции оболочки документации по информации оболочки Bourne Again GNU. Естественно, другие оболочки имеют разные грамматики. Спецификация Single Unix описывает синтаксис, которому должны придерживаться все POSIX-совместимые оболочки (в их POSIX-совместимых режимах).

дальнейшее чтение

  • " Грамматика Shell ". Язык командной оболочки . Базовые спецификации Выпуск 7. Открытая группа. IEEE 1003.1-2008. ISBN 1937218812.
  • test, Утилиты . Базовые спецификации Выпуск 7. Открытая группа. IEEE 1003.1-2008. ISBN 1937218812.
  • " Грамматика Shell ". Руководство по Z Shell . версия 5.3.1. 2017.
JdeBP
источник
5

Это на самом деле не надумано if, thenа elseкак внешние программы. На самом деле оболочка Томпсона в оригинальном 1-м издании Unix реализована ifи gotoкак внешние программы. Это возможно, потому что подпроцесс разделяет файловые дескрипторы с процессом оболочки, поэтому (вперед) goto просто должен был прочитать ввод, пока не найдет метку назначения и не завершится. Смотри Томпсона .

Йохан Мирен
источник
Или действительно увидеть Лорана Берко ifи ifelseявляющегося частью execline. Это не ifв вопросе, хотя.
JdeBP
2
«На самом деле не так уж и сложно думать о том, если, тогда и о другом, как о внешних программах». Да, потому что это не так.
Легкость гонки с Моникой
2

Это thenи elseне программы. Другие части есть. Обратите внимание, что нет ;«непосредственно после них, но после команды они предшествуют.

Команда [ ... ] является командой, и для нее необходимо указать ;if, после которого следует начало другой команды.

AFAIK, все управляющие структуры в Bash и, вероятно, большинство * nix-оболочек одинаковы. Это инструкции для переводчика. Тест или условие, с другой стороны, используют программу / процесс, которые «выполняются» и являются командами. Так как thenявляется частью строки, которая приводит к echoкоманде, она должна быть отделена новой строкой от предыдущей команды [ ... ]. Его не нужно отделять от команды, которой он управляет echo yes.

Юридически, хотя уродливо и трудно читать, вы также можете сделать это.

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

Обратите внимание, что здесь вообще нет необходимости ;между элементами управления, даже если они находятся не на своей линии.

Интересно, что вся структура управления ( if ... fi) - это команда оболочки, и все должно заканчиваться символом новой строки или ;. Последняя строка не может быть, fi echo doneно должна быть fi; echo done. Так же, как назначениеVARIABLE='abcdef' команда.

Хотя целые структуры управления являются командами, они все же не являются программами.

user207673
источник
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оператора, но отмечает конец составной команды.

chepner
источник
спасибо, если это используется if program1 foo; program2 bar; program3 baz; , какой статус программы должен быть 0, чтобы шел шел then? Последний?
Максим Корецкий
Просто program3 baz. Статус выхода из списка команд - это статус выхода последней команды в этом списке. Два других могут потерпеть неудачу, не затрагивая условие.
chepner