Действительно ли программы `if` и` then`

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

$ echo 3; ls -la 

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

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

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

5 Solutions collect form web for “Действительно ли программы `if` и` then`”

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

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

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

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

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

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

if , then else и fi – все зарезервированные слова . Они имеют определенные значения при анализе ввода, который он дает оболочке, в соответствии с ее грамматикой . Аналогичным образом ; является сепараторным оператором .

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

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

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

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

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

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

  • « Грамматика Шелл ». Shell Command Language . Базовые спецификации Выпуск 7. Открытая группа. IEEE 1003.1-2008. ISBN 1937218812.
  • test . Утилиты . Базовые спецификации Выпуск 7. Открытая группа. IEEE 1003.1-2008. ISBN 1937218812.
  • « Грамматика Шелл ». Руководство Z Shell . версия 5.3.1. 2017.

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

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

[ ... ] это команда, и она нужна ; если за ним следует начало другой команды.

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 fi; echo done . То же, что и присваивание VARIABLE='abcdef' – это команда.

Несмотря на то, что все управляющие структуры являются командами, они по-прежнему не являются программами.

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 echo foo; echo bar; echo baz echo foo; echo bar; echo baz . Парсер знает, что условие закончено, потому что then , которое сразу следует за точкой с запятой, не может быть командой, потому что это зарезервированное ключевое слово. Таким образом, он знает, что then следует начало тела. Аналогично, fi является зарезервированным ключевым словом и, следовательно, не может быть третьей командой в теле оператора if , но отмечает конец составной команды.

  • Запустите сценарий оболочки через символическую ссылку из каталога, содержащего сам сценарий
  • Как перейти в предыдущий рабочий каталог в терминале?
  • `Unhandled Exception: System.ArgumentNullException: значение не может быть ошибкой null.` при запуске` dotnet run` с использованием сценария запуска
  • Установка и размонтирование в том же сценарии оболочки приводит к ошибке
  • Чтение содержимого в строке в bash
  • Как вычислить имя файла эскиза из оболочки?
  • Найти каталог и скопировать другой каталог в найденный каталог?
  • Новая строка в переменной
  • Постоянное переключение на zsh в скрипте, без root и без запроса пароля
  • Плитка logfile на куски и поиск ошибок
  • У меня есть несколько копий .bash_profile, какой из них действительно используется? (если есть)
  • Linux и Unix - лучшая ОС в мире.