Выбрать главу

alv      pts/1        2014-12-15 00:34 (:0)

alv      pts/5        2014-12-19 09:37 (:0)

А теперь последнее, чем и закроем тему регулярных выражений вообще. В этом разделе рассматривалось использование метасимволов в командной оболочке (конкретно, в данном случае. в Dash, Bash и Zsh). В других оболочках применение метасимволов и условия их экранирования могут несколько отличаться. И к тому же многие запускаемые из строки шелла команды могут иметь свои правила построения регулярных выражений. Так что в итоге их форма определяется сочетанием особенностей конкретной оболочки и команды, из неё запущенной. Все это при необходимости будет оговариваться в дальнейшем.

А пока переходим к рассмотрению командных конструкций — одной из тех особенностей CLI, которая определяет мощь и универсальность этого интерфейса.

Вводные слова о командных конструкциях

Надеюсь, из того, что было рассказано на предшествующих страницах, посвящённых CLI, читателю стало ясно, что подавляющее большинство команд в POSIX-системах очень просты по сути и предназначены для выполнения какого-либо одного элементарного действия.

То есть команда cp умеет только копировать файлы, команда rm — только удалять их, но зато делают они это хорошо. Подчас — через чур хорошо, что мог ощутить на себе каждый, кому «посчастливилось» по ошибке выдать директиву вроде

$ rm -Rf *

Для тех, кто не испытал этого волнительного ощущения, поясню: результатом будет полное и безвозвратное уничтожение всех файлов от текущего каталога вниз (включая подкаталоги любой степени вложенности).

А если задать ту же команду от лица администратора, то, в зависимости от текущего положения на файловом древе, можно нечувствительно удалить что угодно, вплоть до системы целиком: одна из причине, почему повседневные действия не следует выполнять под root'ом.

Собственно, разделение любой задачи на серию элементарных операций — это и есть основной принцип работы в POSIX-системах, тот самый пресловутый Unix-way, о котором столько говорят его приверженцы.

Однако вслед за этапом решительного размежевания (эх, неистребимы в памяти нашего поколения слова товарища Ленина) должен наступить этап объединения, как за анализом явления следует синтез эмпирических данных о нём. И целям такого объединения служат командные конструкции.

Командные конструкции — очень важный компонент интерфейса командной строки. Они позволяют объединять несколько команд воедино и выполнять различные команды последовательно или параллельно. Для этого служат специальные символы — операторы: фонового режима, объединения, перенаправления и конвейеризации.

Совместное выполнение команд

Простейшая командная конструкция — это выполнение команды в фоновом режиме, что вызывается вводом символа амперсанда после списка опций и (или аргументов):

$ command [options] [arguments] &

В Bash и Zsh пробел перед символом амперсанда не обязателен, но в некоторых шеллах он требуется, и потому лучше возвести его ввод (как и во всех аналогичных случаях) в ранг привычки. После этого возвращается приглашение командной строки и возможен ввод любых других команд (в том числе и фоновых). Команды для параллельного исполнения можно задать и в той же строке:

$ command1 & command2 & ... & commandN

В результате все команды, перечисленные в строке, кроме той, что указана последней, будут выполняться в фоновом режиме.

Существуют и конструкции для последовательного выполнения команд. Так, если ряд команд разделен в строке символом точки с запятой (;)

$ command1 ; command2 ; ... ; commandN

то сначала будет выполнена команда command1, затем — command1 и так далее. Молчаливо предполагается, что каждая из этих команд может иметь любое количество опций и аргументов. И, опять-таки, обрамление ; пробелами не обязательно во многих командных оболочках. Сами по себе команды не обязаны быть связанными между собой каким-либо образом — в сущности, это просто эквивалент последовательного их ввода в командной строке:

$ command1

$ command2

...

и так далее. При этом первая команда может, например, копировать файлы, вторая — осуществлять поиск, третья — выполнять сортировку, или другие действия. Очевидно, что в общем случае выполнение последующей команды не зависит от результатов работы предшествующей.

Однако возможна ситуация, когда результаты предыдущей команды из такой конструкции используются в команде последующей. В этом случае ошибка исполнения любой составляющей команды, кроме последней, делает невозможным продолжение работы всей конструкции. Что само по себе было бы ещё полбеды — однако в некоторых ситуациях исполнение последующей команды возможно только при условии успешного завершения предыдущей.