Какой тип скобок в shell предназначен для выполнения команд linux

Обновлено: 05.07.2024

Оболочка пользователя ( shell ) в Linux.

Операционные системы семейства Linux, как впрочем, и любые другие ОС, предполагают наличие интерфейса взаимодействия между компонентами компьютерной системы и конечным пользователем, т. е. наличие программного уровня, который обеспечивает ввод команд и параметров для получения желаемых результатов. Такой программный уровень получил название "оболочка" или, на английском языке - shell .

Что такое оболочка ?

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

- Интерпретация командной строки.

- Доступ к командам и результатам их выполнения.

- Поддержка переменных , специальных символов и зарезервированных слов.

- Обработка файлов, операций стандартного ввода и вывода.

- Реализация специального языка программирования оболочки.

Для операционных систем семейства Unix / Linux возможно использование нескольких различных оболочек, отличающихся свойствами и методами взаимодействия с системой. Наиболее распространенными оболочками являются

sh - оболочка Bourne , классическая оболочка для ОС Unix

bash оболочка Bourne Again (GNU Bourne-Again SHell). Пожалуй, наиболее распространенная на данный момент, оболочка в среде ОС семейства Linux.

ksh - оболочка Korn , разработанная в качестве развития оболочки Bourne с историей командной строки и возможностью редактирования команд.

csh - оболочка C , использующая синтаксис популярного языка программирования C

tcsh - версия оболочки C с интерактивным редактированием командной строки.

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

В процессе загрузки операционных систем семейства Linux, после загрузки ядра системы выполняется переход в интерактивный режим – режим взаимодействия пользователя и операционной системы. В ОС Linux, первым запускаемым в ходе загрузки процессом, является программа инициализации init , которая считывает содержимое конфигурационного файла /etc/inittab , определяет перечень и характеристики терминалов, имеющихся в системе, и вызывает программу интерактивного входа getty , отображающую приглашение для ввода имени пользователя. После ввода имени пользователя и пароля, программа getty вызывает программу login , которая проверяет достоверность учетной записи, выполняет переход в домашний каталог пользователя и передает управление программе начального запуска сеанса, в качестве которой обычно используется программа оболочки пользователя, конкретная разновидность которой определяется содержимым файла /etc/passwd для данной учетной записи. Например:

user1:x:508:511::/home/user1:/bin/sh
interbase:x:510:511::/home/interbase:/bin/csh
apb:x:511:513:apb:/home/apb:/bin/bash

При выходе из оболочки, ядро системы возвращает управление программе init , которая перезапускает процесс входа в систему и на терминале отображается приглашение к вводу имени пользователя. Выход из оболочки может быть выполнен одним из двух способов :

- посредством команды exit выполненной пользователем

- при получении процессом оболочки сигнала kill , отправленного ядром, например при перезагрузке системы.

Интерпретация командной строки.

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

ls -l file01 file02

содержит команду ls , опцию -l и два имени файлов file01 file02 .

При использовании нескольких опций, их можно объединять. Например, варианты следующих команд идентичны :

Команды, являющиеся частью оболочки, называются встроенными. К таким командам относятся, например, cd, if, case и т. п. Естественно, встроенные команды могут отличаться для различных вариантов оболочек. Кроме встроенных команд, возможно использование программных модулей, представляющих собой отдельные исполняемые файлы, или файлов скриптов или сценариев - обычных текстовых файлов, содержащих последовательно выполняемые строки с командами оболочки. Некоторые скрипты (сценарии) могут выполняться процессами Linux, как например, планировщиком задач cron . Планировщик задач, как правило, предназначен для автоматического выполнения задач администрирования системы по расписанию. Задачи cron представляют собой команды или скрипты и выполняются автоматически, без какого либо вмешательства человека и могут выполняться в контексте разных учетных записей пользователей. В случае, когда задача планировщика предполагает выполнение какого-либо скрипта, возникает проблема выбора оболочки, которая должна быть запущена в качестве дочернего процесса cron для обработки команд из файла скрипта - ведь оболочка может быть любой, а синтаксис скрипта, как правило, предполагает использование конкретной оболочки, под которую он написан. Для устранения данной проблемы, в ОС семейства Linux принято в первой строке скрипта указывать разновидность оболочки, необходимой для его выполнения, в виде:

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

/etc/profile - устанавливает переменные только для командных оболочек. Может запускать любые скрипты в оболочках, совместимых с Bourne shell.

/etc/bash.bashrc - устанавливает переменные только для интерактивных оболочек. Он также запускает bash-скрипты.

/etc/environment - используется модулем PAM-env. В этом файле можно указывать только пары имя=значение .

Каждый из этих файлов имеет свои особенности применения, поэтому следует внимательно выбирать тот, который подходит для ваших целей. Например, если нужно добавить пользовательский каталог

/bin в переменную PATH для всех пользователей, поместите следующий код в один из системных файлов инициализации окружения (/etc/profile или /etc/bash.bashrc):

/bin в переменную $PATH.

if [[ $UID -ge 1000 && -d $HOME/bin && -z $(echo $PATH | grep -o $HOME/bin)

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

Если же нужно изменить среду окружения для конкретного пользователя, используется модификация содержимого среды окружения пользователя:

/.bash_login и т.п. - файлы инициализации командной оболочки из домашнего каталога пользователя.

/.profile - файл инициализации профиля пользователя. Используется многими оболочками для определения переменных среды.

/.pam_environment - пользовательский аналог файла /etc/environment, который используется модулем PAM-env.

Например, чтобы добавить каталог пользователя

/bin в пути поиска исполняемых файлов, заданных переменной PATH , можно например, в файл

/.profile поместить строку:

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

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

/bin в пути поиска исполняемых файлов:

Новое значение переменной PATH будет действовать только до завершения текущего сеанса пользователя.

Для просмотра значения переменной можно использовать команду echo $переменная , например:

В настоящее время, самой распространенной оболочкой, как уже упоминалось выше, является bash . Вызвано это, в первую очередь тем, что оболочка bash является sh - совместимой командной оболочкой, в которую добавлены полезные возможности из оболочек Korn shell ( ksh ) и C shell ( csh ). Оболочка bash может без какой-либо модификации выполнять большинство скриптов, написанных под язык программирования оболочки sh и в максимальной степени пытается приблизиться к стандарту POSIX , что привело к появлению множества улучшений, причем как для программирования, так и использования в интерактивном режиме. В современной реализации bash имеется режим редактирования командной строки, неограниченный размер истории команд, средства управление заданиями, возможность использования псевдонимов, обширный перечень встроенных команд, функции командной оболочки и т.п. В целом, bash в наибольшей степени соответствует потребностям среднестатистического пользователя, что и сделало ее наиболее используемой в среде Linux.

При запуске bash без параметров командной строки, оболочка запускается в интерактивном режиме, отображая на экране приглашение к вводу команд. Интерактивная оболочка обычно читает данные из терминала пользователя и пишет данные в этот же терминал, стандартным устройством ввода является клавиатура, а стандартным устройством вывода – дисплей. Пользователь вводит команды на клавиатуре, а результат их выполнения отображается на дисплее.

Комментарии могут располагаться и в конце строки с исполняемым кодом.

Комментариям могут предшествовать пробелы (пробел, табуляция).

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

Разделитель команд. [Точка-с-запятой] Позволяет записывать две и более команд в одной строке.

Ограничитель в операторе выбора case . [Двойная-точка-с-запятой]

команда "точка" . Эквивалент команды source (см. Пример 11-18). Это встроенная команда bash.

"точка" может являться частью имени файла . Если имя файла начинается с точки, то это "скрытый" файл, т.е. команда ls при обычных условиях его не отображает.

Если подразумевается имя каталога, то одна точка означает текущий каталог и две точки -- каталог уровнем выше, или родительский каталог.

Символ точка довольно часто используется для обозначения каталога назначения в операциях копирования/перемещения файлов.

Символ "точка" в операциях поиска. При выполнении поиска по шаблону , в регулярных выражениях, символ "точка" обозначает одиночный символ.

Двойные кавычки . В строке "STRING" , ограниченной двойными кавычками не выполняется интерпретация большинства служебных символов, которые могут находиться в строке. см. Глава 5.

Запятая . Оператор запятая используется для вычисления серии арифметических выражений. Вычисляются все выражения, но возвращается результат последнего выражения.

Более детальному рассмотрению темы экранирования посвящена Глава 5.

Разделитель, используемый в указании пути к каталогам и файлам. [слэш] Отделяет элементы пути к каталогам и файлам (например /home/bozo/projects/Makefile).

Подстановка команд. [обратные кавычки] Обратные кавычки могут использоваться для записи в переменную команды `command` .

пустая команда. [двоеточие] Это эквивалент операции "NOP" ( no op, нет операции). Может рассматриваться как синоним встроенной команды true. Команда " : " так же является встроенной командой Bash, которая всегда возвращает "true" ( 0 ).

Символ-заполнитель в условном операторе if/then:

Как символ-заполнитель для оператора вложенного документа. См. Пример 17-9.

В комбинации с оператором > (оператор перенаправления вывода), усекает длину файла до нуля. Если указан несуществующий файл -- то он создается.

В комбинации с оператором >> -- оператор перенаправления с добавлением в конец файла и обновлением времени последнего доступа ( : >> new_file). Если задано имя несуществующего файла, то он создается. Эквивалентно команде touch.

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

Символ " : " может использоваться как разделитель полей в /etc/passwd и переменной $PATH.

инверсия (или логическое отрицание) используемое в условных операторах. Оператор ! инвертирует код завершения команды, к которой он применен. (см. Пример 6-2). Так же используется для логического отрицания в операциях сравнения, например, операция сравнения "равно" ( = ), при использовании оператора отрицания, преобразуется в операцию сравнения -- "не равно" ( != ). Символ ! является зарезервированным ключевым словом BASH.

В некоторых случаях символ ! используется для косвенного обращения к переменным.

Кроме того, из командной строки оператор ! запускает механизм историй Bash (см. Приложение F). Примечательно, что этот механизм недоступен из сценариев (т.е. исключительно из командной строки).

символ-шаблон. [звездочка] Символ * служит "шаблоном" для подстановки в имена файлов. Одиночный символ * означает любое имя файла в заданном каталоге.

В регулярных выражениях токен * представляет любое количество (в том числе и 0) символов.

арифметический оператор. В арифметических выражениях символ * обозначает операцию умножения.

Двойная звездочка (два символа звездочки, следующих подряд друг за другом -- ** ), обозначает операцию возведения в степень.

Оператор проверки условия. В некоторых выражениях символ ? служит для проверки выполнения условия.

В конструкциях с двойными скобками, символ ? подобен трехместному оператору языка C. См. Пример 9-28.

сивол-шаблон. Символ ? обозначает одиночный символ при подстановке в имена файлов. В регулярных выражениях служит для обозначения одиночного символа.

Символ $ , предшествующий имени переменной, указывает на то, что будет получено значение переменной.

end-of-line (конец строки). В регулярных выражениях, символ "$" обозначает конец строки.

код завершения. Переменная $? хранит код завершения последней выполненной команды, функции или сценария.

id процесса. Переменная $$ хранит id процесса сценария.

группа команд.

Команды, заключенные в круглые скобки исполняются в дочернем процессе -- subshell-е.

Переменные, создаваемые в дочернем процессе не видны в "родительском" сценарии. Родительский процесс-сценарий, не может обращаться к переменным, создаваемым в дочернем процессе.

инициализация массивов.

Фигурные скобки.

Команда интерпретируется как список команд, разделенных точкой с запятой, с вариациями, представленными в фигурных скобках. [1] При интерпретации имен файлов (подстановка) используются параметры, заключенные в фигурные скобки.

Использование неэкранированных или неокавыченных пробелов внутри фигурных скобок недопустимо.

file1 : A file1 : B file1 : C file2 : A file2 : B file2 : C

Блок кода. [фигурные скобки] Известен так же как "вложенный блок" , эта конструкция, фактически, создает анонимную функцию. Однако, в отличии от обычных функций, переменные, создаваемые во вложенных блоках кода, доступны объемлющему сценарию.

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

Пример 3-1. Вложенные блоки и перенаправление ввода-вывода

Пример 3-2. Сохранение результата исполнения вложенного блока в файл

В отличие от групп команд в (круглых скобках), описаных выше, вложенные блоки кода, заключенные в исполняются в пределах того же процесса, что и сам скрипт (т.е. не вызывают запуск дочернего процесса -- subshell). [2]

pathname -- полное имя файла (т.е. путь к файлу и его имя). Чаще всего используется совместно с командой find.

Обратите внимание на то, что символ " ; " , которым завершается ключ -exec команды find, экранируется обратным слэшем. Это необходимо, чтобы предотвратить его интерпретацию.

test.

Проверка истинности выражения, заключенного в квадратные скобки [ ]. Примечательно, что [ является частью встроенной команды test (и ее синонимом), И не имеет никакого отношения к "внешней" утилите /usr/bin/test.

test.

Проверка истинности выражения, заключенного между [[ ]] (зарезервированное слово интерпретатора).

См. описание конструкции [[ . ]] ниже.

элемент массива.

При работе с массивами в квадратных скобках указывается порядковый номер того элемента массива, к которому производится обращение.

диапазон символов.

двойные круглые скобки.

Вычисляется целочисленное выражение, заключенное между двойными круглыми скобками (( )) .

См. обсуждение, посвященное конструкции (( . )) .

Конструкция scriptname >filename перенаправляет вывод scriptname в файл filename. Если файл filename уже существовал, то его прежнее содержимое будет утеряно.

Конструкция command &>filename перенаправляет вывод команды command, как со stdout, так и с stderr, в файл filename.

Конструкция command >&2 перенаправляет вывод со stdout на stderr.

Конструкция scriptname >>filename добавляет вывод scriptname к файлу filename. Если задано имя несуществующего файла, то он создается.

(command)>

<(command)

перенаправление ввода на встроенный документ.

конвейер. Передает вывод предыдущей команды на ввод следующей или на вход командного интерпретатора shell. Этот метод часто используется для связывания последовательности команд в единую цепочку.

Конвейеры (еще их называют каналами) -- это классический способ взаимодействия процессов, с помощью которого stdout одного процесса перенаправляется на stdin другого. Обычно используется совместно с командами вывода, такими как cat или echo, от которых поток данных поступает в "фильтр" (команда, которая на входе получает данные, преобразует их и обрабатывает).

cat $filename | grep $search_word

В конвейер могут объединяться и сценарии на языке командной оболочки.

А теперь попробуем объединить в конвейер команду ls -l с этим сценарием.

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

Конвейер исполняется в дочернем процессе, а посему -- не имеет доступа к переменным сценария.

Если одна из команд в конвейере завершается аварийно, то это приводит к аварийному завершению работы всего конвейера.

принудительное перенаправление, даже если установлен ключ noclobber option.

логическая операция OR (логическое ИЛИ). В опрециях проверки условий, оператор || возвращает 0 (success), если один из операндов имеет значение true (ИСТИНА).

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

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

Пример 3-3. Запуск цикла в фоновом режиме

Команда, исполняемая в пределах сценария в фоне, может подвесить сценарий, ожидая нажатия клавиши. К счастью, это легко "лечится".

Логическая операция AND (логическое И). В операциях проверки условий, оператор && возвращает 0 (success) тогда, и только тогда, когда оба операнда имеют значение true (ИСТИНА).

префикс ключа. С этого символа начинаются опциональные ключи команд.

COMMAND -[Option1][Option2][. ]

ls -al

sort -dfu $filename

set -- $variable

перенаправление из/в stdin или stdout. [дефис]

Обратите внимание, что в этом контексте "-" - не самостоятельный оператор Bash, а скорее опция, распознаваемая некоторыми утилитами UNIX (такими как tar, cat и т.п.), которые выводят результаты своей работы в stdout.

В случае, когда ожидается имя файла, тогда "-" перенаправляет вывод на stdout (вспомните пример с tar cf) или принимает ввод с stdin.

Добавим символ "-" и получим более полезный результат. Это заставит командный интерпретатор ожидать ввода от пользователя.

Теперь команда принимает ввод пользователя со stdin и анализирует его.

Используя передачу stdout по конвейеру другим командам, можно выполнять довольно эффектные трюки, например вставка строк в начало файла.

С помощью команды diff -- находить различия между одним файлом и частью другого:

grep Linux file1 | diff file2 -

И наконец пример использования служебного символа "-" с командой tar.

Пример 3-4. Резервное архивирование всех файлов, которые были изменены в течение последних суток

Могут возникнуть конфликтные ситуации между опреатором перенаправления "-" и именами файлов, начинающимися с символа "-" . Поэтому сценарий должен проверять имена файлов и предаварять их префиксом пути, например, ./-FILENAME, $PWD/-FILENAME или $PATHNAME/-FILENAME.

Если значение переменной начинается с символа "-" , то это тоже может быть причиной появления ошибок.

предыдущий рабочий каталог. [дефис] Команда cd - выполнит переход в предыдущий рабочий каталог, путь к которому хранится в переменной окружения $OLDPWD .

Не путайте оператор "-" (предыдущего рабочего каталога) с оператором "-" (переназначения). Еще раз напомню, что интерпретация символа "-" зависит от контекста, в котором он употребляется.

Минус. Знак минус в арифметических операциях.

В зависимости от контекста применения, символ " = " может выступать в качестве оператора сравнения.

Плюс. Оператор сложения в арифметических операциях.

В зависимости от контекста применения, символ + может выступать как оператор регулярного выражения.

Ключ (опция). Дополнительный флаг для ключей (опций) команд.

Отдельные внешние и встроенные команды используют символ " + " для разрешения некоторой опции, а символ " - " -- для запрещения.

модуль. Модуль (остаток от деления) -- арифметическая операция.

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

домашний каталог. [тильда] Соответствует содержимому внутренней переменной $HOME.

bozo -- домашний каталог пользователя bozo, а команда ls

bozo выведет содержимое его домашнего каталога.

/ -- это домашний каталог текущего пользователя, а команда ls

/ выведет содержимое домашнего каталога текущего пользователя.

текущий рабочий каталог. Соответствует содержимому внутренней переменной $PWD.

предыдущий рабочий каталог. Соответствует содержимому внутренней переменной $OLDPWD.

начало-строки. В регулярных выражениях символ "^" задает начало строки текста.

изменяет поведение терминала или управляет выводом текста. Управляющий символ набирается с клавиатуры как комбинация CONTROL + <клавиша>.

Ctl-C

Завершение выполнения процесса.

Ctl-D

Выход из командного интерпретатора (log out) (аналог команды exit).

"EOF" (признак конца файла). Этот символ может выступать в качестве завершающего при вводе с stdin.

Ctl-G

Ctl-H

Backspace -- удаление предыдущего символа.

Ctl-J

Ctl-L

Перевод формата (очистка экрана (окна) терминала). Аналогична команде clear.

Ctl-M

Ctl-U

Стирание строки ввода.

Ctl-Z

используется как разделитель команд или переменных. В качестве пробельного символа могут выступать -- собственно пробел (space), символ табуляции, символ перевода строки, символ возврата каретки или комбинация из вышеперечисленных символов. В некоторых случаях, таких как присваивание значений переменным, использование пробельных символов недопустимо.

Пустые строки никак не обрабатываются командным интерпретатором и могут свободно использоваться для визуального выделения отдельных блоков сценария.

$IFS -- переменная специального назначения. Содержит символы-разделители полей, используемые некоторыми командами. По-умолчанию -- пробельные символы.

Примечания

Интерпретатор, встретив фигурные скобки, раскрывает их и возвращает полученный список команд, которые затем и исполняет.

Исключение: блок кода, являющийся частью конвейера, может быть запущен в дочернем процессе (subshell-е).

3. ПРОСТЕЙШИЕ СРЕДСТВА SHELL

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

Shell не является необходимым и единственным командным языком (хотя именно он стандартизован в рамках POSIX [POSIX 1003.2] - стандарта мобильных систем). Например, немалой популярностью пользуется язык cshell, есть также kshell, bashell (из наиболее популярных в последнее время) и другие. Более того, каждый пользователь может создать свой командный язык. Может одновременно на одном экземпляре операционной системы работать с разными командными языками.

ОБРАТИТЕ ВНИМАНИЕ. shell - это одна из многих команд UNIX. То есть в набор команд оболочки (интерпретатора) "shell" входит команда "sh" - вызов интерпретатора "shell". Первый "shell" вызывается автоматически при вашем входе в систему и выдает на экран промтер. После этого вы можете вызывать на выполнение любые команды, в том числе и снова сам "shell", который вам создаст новую оболочку внутри прежней.

Так например, если вы подготовите в редакторе файл "f1":

то это будет обычный текстовый файл, содержащий команду "echo", которая при выполнении выдает все написанное правее ее на экран. Можно сделать файл "f1" выполняемым с помощью команды "chmod 755 f1". Но его можно ВЫПОЛНИТЬ, вызвав явно команду (!) "sh" ("shell"):

Файл можно выполнить и в текущем экземпляре "shell". Для этого существует специфическая команда "." (точка), т.е.

СОВЕТ. Начинайте командный sh-файл с пустой строки или пустого оператора ":".

Поскольку UNIX - система многопользовательская, вы можете даже на персональном компьютере работать параллельно, скажем, на 12-ти экранах (переход с экрана на экран ALT/функциональная клавиша), имея на каждом экране нового (или одного и того же) пользователя со своей командной оболочкой. Можете и в графическом режиме X-Window также открыть большое число окон, а в каждом окне может быть свой пользователь со своей командной оболочкой.

Стержневым элементом языка shell является команда.

3.1. Структура команд

Команды в shell обычно имеют следующий формат:

ls имя команды выдачи содержимого директория,
-ls флаги ( "-" - признак флагов, l - длинный формат, s - об'ем файлов в блоках).
/usr/bin директорий, для которого выполняется команда.

Эта команда выдаст на экран в длинном формате содержимое директория /usr/bin, при этом добавит информацию о размере каждого файла в блоках.

К сожалению, такая структура команды выдерживается далеко не всегда. Не всегда перед флагами ставится минус, не всегда флаги идут одним словом. Есть разнообразие и в представлении аргументов. К числу команд, имеющих экзотические форматы, относятся и такие "ходовые" команды, как сс, tar, dd, find и ряд других.

Как правило (но не всегда), первое слово (т.е. последовательность символов до пробела, табуляции или конца строки) shell воспринимает, как команду. Поэтому в командной строке

первое слово будет расшифровано shell, как команда (конкатенации), которая выдаст на экран файл с именем "cat" (второе слово), находящийся в текущем директории.

3.2. Группировка команд.

; и
<перевод строки>
определяют последовательное выполнение команд;
& асинхронное (фоновое) выполнение предшествующей команды;
&& выполнение последующей команды при условии нормального завершения предыдущей, иначе игнорировать;
|| выполнение последующей команды при ненормальном завершении предыдущей, иначе игнорировать.

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

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

Иногда необходимо, чтобы все фоновые процессы завершились, прежде чем будет выполняться какой-то расчет. Для этого служит специальная команда "wait [PID]". Эта команда ждет завершения указанного идентификатором (числом) фонового процесса. Если команда без параметра, то она ждет завершения всех фоновых процессов, дочерних для данного "sh".

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

где k1, k2 и k3 - какие-то команды, то "k2" будет выполнена только при успешном завершении "k1"; после любого из исходов обработки "k2" (т.е. "k2" будет выполнена, либо пропущена) будет выполнена "k3".

Здесь обе команды ("k2" и "k3") будут выполнены только при успешном завершении "k1".

В фоновом режиме будет выполняться последовательность команд "k1" и "k2".

Фоновые процессы (как и теневую экономику) сложно уничтожить, поскольку традиционная команда "CTL/C" прерывает только процессы переднего плана. Для уничтожения фонового процесса надо знать его номер. При запуске фонового процесса на экран выдается число, соответствующее номеру (идентификатору) этого процесса (PID). Если этот номер забыт или надо убедиться, что этот процесс не закончен, с помощью команды

можно получить перечень идентификаторов процессов (PID), имена пользователей, текущее время, затраченное процессами, и т.д.

В выведенной таблице можно найти номера процессов, подлежащих уничтожению, например это "849" и "866". Тогда командой

можно уничтожить эти процессы. При уничтожении процессов надо вы должны иметь то же имя пользователя, какое было приписано уничтожаемым процессам (или иметь имя привилегированного пользователя).

ПРЕДУПРЕЖДЕНИЕ. Если параллельно обрабатывается или создается файл с ОДНИМ именем (например, несколько пользователей вызвали в редактор один и тот же файл), то в системе продолжит существование тот вариант файла, который возвращен (записан) в систему последним. Это частая ошибка пользователей персональных компьютеров, которые редактируют один файл параллельно с нескольких экранов.

Круглые скобки "()", кроме выполнения функции группировки, выполняют и функцию вызова нового экземпляра интерпретатора shell.

Пусть мы находились в начальном каталоге "/mnt/lab/asu"

Тогда в последовательности команд

две команды "ls" выдадут 2 экземпляра содержимого каталога "/mnt/lab", а последовательность

выдаст сначала содержимое каталога "/mnt/lab", а затем содержимое "/mnt/lab/asu", т.к. при входе в скобки вызывается новый экземпляр shell, в рамках которого и осуществляется переход. При выходе из круглых скобок происходит возврат в старый shell и в старый каталог.

3.3. Перенаправление команд

Команда, которая может работать со стандартным входом и выходом, называется ФИЛЬТРОМ.

Пользователь имеет удобные средства перенаправления ввода и вывода на другие файлы (устройства). Символы ">" и ">>" обозначают перенаправление вывода.

команда "ls" сформирует список файлов текущего каталога и поместит его в файл "f1" (вместо выдачи на экран). Если файл "f1" до этого существовал, то он будет затерт новым.

команда pwd сформирует полное имя текущего каталога и поместит его в конец файла "f1", т.е. ">>" добавляет в файл, если он непустой.

Символы "<" и "<<" обозначают перенаправление ввода.

подсчитает и выдаст на экран число строк в файле f1.

создаст с использованием редактора файл "f2", непосредственно с терминала. Окончание ввода определяется по символу, стоящему правее "<<" (т. е. "!"). То есть ввод будет закончен, когда первым в очередной строке будет "!".

Можно сочетать перенаправления. Так

выполняются одинаково: подсчитывается число строк файла "f3" и результат помещается в файл "f4".

Средство, объединяющее стандартный выход одной команды со стандартным входом другой, называется КОНВЕЙЕРОМ и обозначается вертикальной чертой "|".

список файлов текущего каталога будет направлен на вход команды "wc", которая на экран выведет число строк каталога.

Конвейером можно об'единять и более двух команд, когда все они, возможно кроме первой и последней - фильтры:

Данный конвейер из файла "f1" ("cat") выберет все строки, содержащие слово "result" ("grep"), отсортирует ("sort") полученные строки, а затем пронумерует ("cat -b") и выведет результат в файл "f2".

Поскольку устройства в ОС UNIX представлены специальными файлами, их можно использовать при перенаправлениях. Специальные файлы находятся в каталоге "/dev". Например, "lp" - печать; "console" - консоль; "ttyi" - i-ый терминал; "null" - фиктивный (пустой) файл (устройство).

выведет содержимое текущего каталога на печать, а f1 < /dev/null обнулит файл "f1".

В этом случае будет отсортирован файл "f1" и передан на печать, а 20 последних строк также будут выданы на экран.

которая должна выдать на экран последовательно содержимое файлов "f1" и "f2", выдаст вам, например, следующее

Можно указать не только какой из стандартных файлов перенаправлять, но и в какой стандартный файл осуществить перенаправление.

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

<- закрывает стандартный ввод.
>- закрывает стандартный вывод.

3.4. Генерация имен файлов.

При генерации имен используют метасимволы:

* произвольная (возможно пустая) последовательность символов;
? один произвольный символ;
[. ] любой из символов, указанных в скобках перечислением и/или с указанием диапазона;
cat f* выдаст все файлы каталога, начинающиеся с "f";
cat *f* выдаст все файлы, содержащие "f";
cat program.? выдаст файлы данного каталога с однобуквенными расширениями, скажем "program.c" и "program.o", но не выдаст "program.com";
cat [a-d]* выдаст файлы, которые начинаются с "a", "b", "c", "d". Аналогичный эффект дадут и команды "cat [abcd]*" и "cat [bdac]*".

3.5. Командные файлы.

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

Пусть с помощью редактора создан файл с именем "cmd", содержащий одну строку следующего вида:

Можно вызвать shell как команду (!), обозначаемую "sh", и передать ей файл "cmd", как аргумент или как перенаправленный вход, т.е.

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

Более интересный и удобный вариант работы с командным файлом - это превратить его в выполняемый, т.е. просто сделать его командой, что достигается изменением кода защиты. Для этого надо разрешить выполнение этого файла.

сделает код защиты "rwx__x__x". Тогда простой вызов

приведет к выполнению тех же трех команд.

Результат будет тот же, если файл с содержимым

представлен в виде:

так как переход на другую строку также является разделителем в последовательности команд.

Таким образом, выполняемыми файлами могут быть не только файлы, полученные в результате компиляции и сборки, но и файлы, написанные на языке shell. Их выполнение происходит в режиме интерпретации с помощью shell-интерпретатора

Еще раз отметим, что shell-интерпретатор, это всего лишь одна из сотен команд ОС UNIX, имеющая равные с прочими привилегии.

Столкнулся со странным поведением скрипта в тех случаях, когда я пишу примерно так:

Можно ли так использовать круглые скобки и если нет то почему?



Круглые скобки - запуск подпроцесса (отдельного процесса bash) и выполнение кода в нём:

В принципе Ваш код должен работать правильно, если не считать того, что так делать нерационально.

P.S. Проблемы будут, если попытаетесь изменить какие-то переменные из основной программы внутри порождённого процесса: естественно, в основном процессе они и не подумают изменяться.

DRVTiny ★★★★★ ( 06.07.18 10:18:26 )
Последнее исправление: DRVTiny 06.07.18 10:27:38 (всего исправлений: 1)

О. в этом то и проблема как раз! Спасибо, я понял свою ошибку. То есть какого-то короткого способа записи


Способ есть, но скобки тебе в этом не помогут. Дай конкретный контекст.

То есть какого-то короткого способа записи

в общем случае нет


DRVTiny ★★★★★ ( 06.07.18 12:04:14 )
Последнее исправление: DRVTiny 06.07.18 12:04:34 (всего исправлений: 1)

Квадратные скобки никаких сабшеллов не создают.

А зачем нужны двойные квадратные скобки []?



DRVTiny ★★★★★ ( 06.07.18 13:50:31 )
Последнее исправление: DRVTiny 06.07.18 13:50:42 (всего исправлений: 1)

В вашем случае ругается. на код


И я забыл ; исправил, да в таком виде работает, спасибо

Так, а в чем прикол? у меня одинаково с круглыми и фигурными исполняется, только с круглыми процесс создается еще.

Блин, как это сделать теперь обратно?

непереносим, относится к т.н. башизмам и за его использование в приличном обществе бъют по лицу.

Есть один нюанс, когда условие true, а code_if_true завершится с отличным от нуля статусом, то выполнится code_if_false.


только хардкор, только ash.


непереносим, относится к т.н. башизмам и за его использование в приличном обществе бъют по лицу.

Да какая разница? Ведь bash/shell в приличном обществе и не используют.


относится к т.н. башизмам и за его использование в приличном обществе бъют по лицу.

Ну и общество у вас.

Бсдуны, что с них взять. Как будто никому не плевать на их боли.


А что используют?


Что им мешает в бзде баш использовать?

Подозреваю, что фанатизм



И ещё, в догонку.

Всё хочу спросить, куда вы их все, блядь, переносить собираетесь? В Стиме продавать? Шелловские скрипты пишутся в 99.999999% случаев для конкретной системы, а то и машины.



BASH есть под все известные мне платформы, я на AIX написал башевого кода не так уж и мало. Если говорить о дефолте, то он вообще чуть ли не в каждом никсе свой, и это чаще не sh, чем sh. А главное, у ТС по-любому sh, так что какая разница?


Плюсую. Ничего не мешает, кроме религиозных воззрений

BASH есть под все известные мне платформы

Зато установлен по умолчанию далеко не на всех.

Если говорить о дефолте, то он вообще чуть ли не в каждом никсе свой

А это не важно. Важно что это POSIX совместимый шелл, на котором башизмы работать не обязаны.

Именно что sh, а не bash. А вы вводите человека в заблуждение, расписывая преимущества непереносимой конструкции, и забыв упомянуть что она, собственно, непереносима.


расписывая преимущества непереносимой конструкции, и забыв упомянуть что она, собственно, непереносима.


например, когда пишешь configure.ac или автотулзовские M4 макросы, весьма желательна переносимость

Harald ★★★★★ ( 06.07.18 22:35:35 )
Последнее исправление: Harald 06.07.18 22:36:28 (всего исправлений: 1)

Ну попробуй, запусти /bin/sh скрипт со своими [[ на дебиане. Там /bin/sh это, на минуту, dash. А скрипт с /bin/bash запусти на FreeBSD. Там его никогда по этому пути не будет.


Есть прекрасная утилита env. А во FreeBSD ещё в 2009-м году был сплошной уродский csh, в котором были абсолютно чудовищные сишизмы. И что? сиш был тогда хорош, потому что BSD?

BASH - самая распространённая командная оболочка для Linux, Linux - самая распространённая *nix-система. bash есть даже для android и ставится элементарно. И да, если на то пошло, тот же python тоже по дефолту есть далеко не везде, а в Debian не только dash, но ещё и некий IceWeasel (потому что Debian, и этим всё сказано). При этом в Debian всё-таки есть, внезапно, /bin/bash.


И что? сиш был тогда хорош, потому что BSD?

Про которые все были в курсе и всем не навязывали.

сиш был тогда хорош, потому что BSD?

Во времена оные, оригинальный bourne shell был ну совсем уж restricted. Вот взять dash, выкинуть от туда $ синтаксис и прочие >&- получим времена csh и того родителя bash.

BASH - самая распространённая командная оболочка для Linux,

Проблема как обычно в том, что тот же синтаксис [[ имеет несовместимости с 2-3-4 версиями bash. Я нарывался и было весьма неприятно. Оно и понятно, когда имеем типичный линусковый подход: сейчас мы по быстрому сделаем модно-молодёжно и круто наперекор вашим старческим догмам, а потом оказывается, что имеются противоречия в синтаксисе.

Но это не важно. Самое смешное в этом топике в том, что теперь можно-молодёжно ни за что не юзать if/then/else! Такое чувству, что мир сошёл с ума.


Про которые все были в курсе и всем не навязывали.

Ну, наконец-то баш сравнили с системди. Аплодирую стоя.

синтаксис [[ имеет несовместимости с 2-3-4 версиями bash.

Да, как и в любом другом языке. Вы, уважаемый, на k&r C до сих пор пишете?

удобство, я так понимаю, в принципе не рассматривается? и кто тут религиозен после этого


Да, как и в любом другом языке. Вы, уважаемый, на k&r C до сих пор пишете?

Вы не поверите, но я даже иногда использую синтаксис cmd_if && < cmd1; cmd2 >. Хотя изначально синтаксис с одельностоящими фигурными скобками придуман был для группировки команд с едиными файловыми перенаправлениями. Но оказалось, что для очень коротких комманд, типа < echo Ok; exit 0>вполне сойдёт и для && / || синтаксиса. Но нет же, по молодёжному инфантильно-нигилистическому ясен пень надо обязательно выдирать гланды через задний проход, и кто так не делает, тот старопердун. Смешно и грустно.


например, когда пишешь configure.ac или автотулзовские M4 макросы, весьма желательна переносимость

А ещё есть Makefile, который вообще не на шелле. Кто-то призывает их писать на баше? Я же не зря оставил 0.000001%. И это повод отказываться от возможностей новых версий языка?


Смахнул слезу со щетины.

Расскажи нахера эти [[ нужны? Кроме поиска приключений на свою жопэ.

Честно говоря, я не думаю, что такая ситуация редка, многие проприетаарные решения могут работать десятилетиями просто потому что работает. Мне вот сейчас выдали обновление с 4.9, так вот, то nand отваливается, то kernel panic.

Читайте также: