Командный интерпретатор

Материал из Xgu.ru

(Перенаправлено с Bash)
Перейти к: навигация, поиск


Короткий URL: shell


Содержание

[править] Что такое командный интерпретатор?

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

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

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

ОС Linux использует несколько различных видов интерпретаторов. Наиболее распространенными среди них являются:

  • sh. Bourne Shell. Прообраз командных интерпретаторов сегодняшнего дня. В современных Linux-системах sh представляет собой символическую ссылку на файл bash;
  • bash. Bourne-Again SHell. Основной командный интерпретатор ОС Linux. Представляет собой развитие ash и sh. Поддерживает богатый язык написания скриптов, удобный интерфейс для редактирования командной строки, автопродолжение команд и множество других полезных возможностей;
  • tcsh. C Shell. Расширенная версия интерпретатора C Shell, использующегося в BSD-системах. Поддерживает функцию автозавершения текста и расширенные возможности редактирования;
  • zsh. Очень развитый командный интерпретатор, объединяющий в себе возможности csh, bash с дополнительными, такими как: улучшенная поддержка автопродолжения, более развитые возможности редактирования, расширенные файловые шаблоны и ряд других;
  • nash. Not A SHell. Предельно облегченная оболочка, предназначенная для интерпретации сценариев в linuxrc файлах, при загрузке с виртуального диска initrd. Не позволяет работать пользователю в интерактивном режиме.

Отличительной особенностью программ интерпретаторов, являются две буквы sh, в конце их имени (от англ. shell — оболочка, командный интерпретатор). Как работает командный интерпретатор?

[править] Запуск интерпретатора

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

   $ bash

После запуска интерпретатор выполняет инициализационные скрипты. Порядок выполнения соответствует указанному ниже.

Инициализационные скрипты.

/etc/profile
Общесистемный скрипт настройки среды. Выполняется один раз при входе в систему (login shell)
~/.bash_profile
Пользовательский скрипт настройки среды. Выполняется один раз при входе в систему (login shell)
~/.bashrc
Пользовательский инициализационный скрипт командного интерпретатора. Выполняется каждый раз при запуске интерпретатора в интерактивном режиме, т.е. если он не используется для выполнения скриптов
/etc/bashrc
Общесистемный инициализационный скрипт командного интерпретатора. Вызывается файлом ~/.bashrc

[править] Работа интерпретатора

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

   [user@host dir]$

По умолчанию приглашение содержит информацию об имени пользователя, имени компьютера и текущем каталоге. Завершающим символом является $ или # в зависимости от того, обладает ли пользователь, от имени которого запущен интерпретатор, привилегиями суперпользователя (#) или нет ($).

Note-icon.gif

Формат приглашения можно настроить при помощи переменной командного интерпретатора PS1

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

Tip-icon.gif

Команда может выполняться в фоновом режиме. Для этого после ее названия нужно поставить символ & амперсанд. В этом случае, управление сразу же возвращается интерпретатору, команда при этом продолжает выполняется. При ее завершении на экран будет выдано информационное сообщение об этом.

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

  • Файловые шаблоны. Специальные метасимволы, необходимые для описания групп файлов;
  • Перенаправление. Механизм, обеспечивающий взаимодействие несвязанных между собой программ: данные, поступающие с выхода одной программы попадают на вход другой.
  • Переменные интерпретатора. Командный интерпретатор использует переменные как временное хранилище данных, необходимое ему для нормальной работы: например, переменные могут использоваться в скриптах интерпретатора или для передачи настроек. Переменные также обеспечивают удобный доступ к среде окружения программ.
  • Скриптинг. Команды могут не вводится пользователем в интерактивном режиме, а считываться из заранее подготовленного файла. Это облегчает многократное исполнение одинаковых или схожих между собой действий. Интерпретаторы развивают эту идею, позволяя обрабатывать не просто последовательность подряд идущих команд, а целые сценарии, содержащие конструкции алгоритмических языков программирования: циклы, ветвления, функции.

[править] Ввод командной строки

Командный интерпретатор bash делает редактирование командной строки предельно эффективным. Ввод строки осуществляется быстро и точно. Для выполнения этих требований bash обладает несколькими особенностями:

  • Мощный и гибко настраиваемый интерфейс редактирования командной строки;
  • История команд;
  • Автопродолжение.

[править] Редактирование

Командный интерпретатор bash предоставляет очень богатый интерфейс для ввода и редактирования командной строки. Интерфейс в значительной мере повторяет интерфейсы таких текстовых редакторов как vi (set -o vi) и emacs (set -o emacs; используется по умолчанию). Поддерживаются команды быстрого перемещения, удаления, вставки, управления историей, автозавершения, макрокоманды и многие другие.

Tip-icon.gif

Перечисленные привязки к клавишам не являются жесткими. Интерфейс может быть гибко настроен путём настройки библиотеки GNU readline. Интерпретатор bash поддерживает более сотни встроенных команд, облегчающих редактирование.

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

Ctrl-a (Home) | Ctrl-e (End)
Переход к началу | концу строки
Ctrl-b (влево) | Ctrl-f (вправо)
Переход на один символ влево | вправо
Meta-b |Meta-f
Переход на одно слово влево | вправо
Ctrl-l
Очистка экрана
Ctrl-d (Delete) | BackSpace
Удаление символа на месте курсора | перед курсором
Ctrl-k | Ctrl-x BackSpace
Удаление до конца | начала линии
Ctrl-y
Вставка последнего удаленного фрагмента

[править] История команд

Все команды, введенные пользователем в интерпретаторе bash, сохраняются. Перечень ранее введенных команд называется историей. После того как нажимается клавиша Enter, команда записывается в историю. Если при этом размер списка истории слишком велик (максимальный размер определяется переменной HISTSIZE), первая команда из него удаляется. При завершении работы bash история сохраняется в файле, а в начале его работы — восстанавливается.

Если команда раньше была введена, ее можно не вводить полностью, а просто выбрать из списка истории. Наиболее простые команды для передвижения по списку истории: клавиши вверх и вниз для перехода соответственно к предыдущему и следующему элементу истории. [Предостережение] Предостережение

Первая команда это первая команда в списке истории, т.е. первая введенная команда. Последняя — последняя команда в списке, последняя введенная команда.

Комбинации клавиш для управления историей.

вверх
Извлечь предыдущую команду из списка истории и передвинуться на одну команду назад
вниз
Извлечь следующую команду из списка истории и передвинуться на одну команду вперед
Page Up
Перейти к началу списка истории и извлечь первую введенную команду
Page Down
Перейти к концу списка истории, т.е. к строке, которая сейчас редактируется
Ctrl-r
Обратный поиск в истории. Просматриваются все строки, начиная с последней, и сравниваются с искомым текстом. Если вам нужно повторить поиск (перейти к следующему вхождению), надо нажать ctrl-r ещё раз.
Ctrl-s
Прямой поиск в истории. Просматриваются все строки, начиная с первой, и сравниваются с искомым текстом (по умолчанию ctrl-s это клавиша flow-control, которая просто замораживает консоль; отключить можно, так: stty stop '')
Meta-Ctrl-y
Вставить первый аргумент последней введенной команды (второе слово в строке)
Meta-.
Вставить последний аргумент последней введенной команды (последней слово в строке)
Ctrl-o
Принять на выполнение введенную строку и перейти к следующей команде в списке истории (при нажатии Enter осуществляется переход в конец списка)

[править] Автопродолжение

Автопродолжение (автодополнение, автозавершение — англ. autocompletion) является чрезвычайно удобной способностью bash. После того как набраны первые символы имени, нажатие клавиши Tab заставляет bash показать возможные варианты окончания набранного слова. Если вариант только один, bash использует его и автоматически завершает слово. Если вариантов несколько, bash выводит их все на экран. Если вариантов слишком много, bash предварительно спросит, стоит ли выводить их все? Наконец, если варианты завершения слова отсутствуют, bash издаст звуковой сигнал. Это хороший повод подумать о том, что при наборе слова, вероятно, уже допущена ошибка.

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

Для автопродолжения имени команды bash просматривает названия встроенных команд и предопределенных алиасов, если совпадений не найдено — имена всех файлов в каталогах с исполняемыми файлами. Кандидатами на завершение считаются имена всех исполняемых файлов, которые начинаются также как и вводимое имя.

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

Tip-icon.gif

Существует дополнительная надстройка над bash: bash_completion, которая позволяет выполнять автопродолжение не только имен файлов и команд, но и всевозможных аргументов команды, основываясь на контексте автопродолжения.

[править] Пример. Автопродолжение в bash

Автопродолжение не всегда ускоряет ввод. Иногда количество нажатий получается даже больше чем при ручном вводе. Неоспоримым плюсом является то, что при автопродолжении вероятность правильного набора имени максимальна.

Пользователь хочет найти дополнительную информацию по пакету bash. Он не помнит точно, где она находится, но приблизительно догадывается, где ее искать. Для поиска он использует команду find.

[i@core i]$ fi1
fi                  find                finger               2
fifteen_applet      find2perl           fitstopnm
file                findrpm             fix_bs_and_del
file_by_inode       findsmb             
file-types-capplet  findtr              
[i@core i]$ fin3
find       find2perl  findrpm    findsmb    findtr     
finger4
[i@core i]$ find5 /u6sr/7s8
sbin   share  src    
[i@core i]$ find /usr/sh9are/10d
dia   dict  doc   
[i@core i]$ find /usr/share/doc/ -name '*bash*'
/usr/share/doc/lynx-2.8.4/lynx_help/keystrokes/bashlike_edit_help.html
/usr/share/doc/bash-2.05
[i@core i]$ 

Набрав fi, пользователь нажимает Tab 1. Есть несколько вариантов автопродолжения 2. Он набирает еще одну букву и нажимает Tab 3 еще раз. Вариантов все еще много 4. Он набирает последнюю букву 5. Теперь он может быть уверен, что команда набрана правильно (если это вообще та команда, которая ему нужна). После этого он начинает набирать имя каталога: /u и нажимает Tab 6; имя автоматически продолжается до /usr/ — других вариантов нет 7. Пользователь нажимает s и Tab 8 — вариантов несколько; он выбирает то, что кажется ему наилучшим и нажимает h и Tab 9. Имя продолжается до /usr/share/ 10. Продолжая действовать в том же духе, он набирает имя каталога документации /usr/share/doc. Далее он вручную набирает остаток команды и передает ей выполнение.

[править] Обработка командной строки

После того как пользователь ввел команду и нажал Enter для запуска, bash начинает ее обработку.

Обработка команды производится в несколько этапов:

  1. Раскрытие скобок;
  2. Замена тильды;
  3. Подстановка переменных и параметров;
  4. Командная подстановка;
  5. Разбиение;
  6. Замена шаблонов.

Порядок проведения этапов обработки командной строки важен.

[править] Файловые шаблоны

Командный интерпретатор bash предоставляет очень удобное средство для работы с группами файлов — шаблоны. Шаблоны позволяют одним словом описывать множество символьных последовательностей, удовлетворяющих определенным требованиям.

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

Шаблонные символы.

*
Любая последовательность символов или пустая последовательность.
?
Один любой символ.
[]
Символьный класс. Один из тех символов, которые перечислены в квадратных скобках. Если первым символом является циркумфлекс ^, наоборот — любой из символов, не перечисленных в скобках. Может быть указан диапазон символов, например a-e означает abcde.

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

Note-icon.gif

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

Замена происходит так: bash последовательно просматривает список всех файлов находящихся в каталоге. Если имя файла удовлетворяет требованиям шаблона, он запоминается, в противном случае отбрасывается. Затем рассматривается имя следующего файла. Каталог, файлы которого проверяются на соответствие шаблону, определяется путевым именем предшествующим непосредственно шаблону. Если имени нет — рассматривается текущий каталог. Раскрытие шаблона происходит рекурсивно, т.е. если несколько частей путевого имени содержат шаблонные символы, тогда сначала раскрывается первое из них, потом для каждого полученного имени раскрывается второй шаблон и т.д.

[править] Пример. Файловые шаблоны

Вот несколько простых примеров: все файлы в текущем каталоге 1, все файлы, завершающиеся на .xml — файлы с суффиксом .xml 2, все файлы, начинающиеся на точку — скрытые файлы 3.

   * 1    *.xml 2    .* 3

А вот несколько примеров посложнее. Все файлы с суффиксом .xml во всех подкаталогах первого уровня каталога /home/i/xml 1. Все файлы и подкаталоги второго уровня, содержащие слово linux 2. Все файлы в текущем каталоге, которые содержат в своем имени символ '-', '+', '*' (!) или '=' 3.

   /home/i/xml/*/*.xml 1  /*/*linux* 2  /*[-+*=]* 3

[править] Фигурные скобки

Командный интерпретатор bash предоставляет еще одно средство для описания символьных последовательностей. Оно отличается от шаблонов тем, что позволяет описывать имена несуществующих файлов или каталогов. Такой механизм является очень удобным при создании группы файлов или каталогов с похожими названиями. Этот механизм известен как скобочная подстановка или раскрытие фигурных скобок.

Скобочный шаблон имеет следующий вид:

   Префикс{Строка1,Строка2,...}Суффикс

После раскрытия скобок генерируется последовательность строк:

   ПрефиксСтрока1Суффикс ПрефиксСтрока2Суффикс ...

Скобки могут быть вложенными. В этом случае они раскрываются рекурсивно.

[править] Пример. Скобочная подстановка

Создать каталоги 1999, 2000, 2001 и 2002, каждый из которых содержит 12 подкаталогов соответствующих месяцам (01, 02,..).

   $ mkdir -p {1999,200{0,1,2}}/{0{1,2,3,4,5,6,7,8,9},1{0,1,2}}

Создать развернутое дерево каталогов при использовании скобочной подстановки можно одной командой:

$ mkdir -p a/{b/{c,d},e/{f,g,h/i/j/k}}
$ tree
.
`-- a
    |-- b
    |   |-- c
    |   `-- d
    `-- e
        |-- f
        |-- g
        `-- h
            `-- i
                `-- j
                    `-- k

11 directories, 0 files

Команда создает дерево в текущем каталоге:

[править] Командная подстановка

Бывает, что в качестве аргумента одной команды необходимо использовать информацию, полученную в результате выполнения другой команды. Можно выполнить первую команду, запомнить или записать результаты ее работы, а затем вызвать вторую команду, вручную указав полученные параметры. Этот способ является, как минимум, неудобным. Иногда он может быть вообще неприменим — например, если количество параметров велико или программа вызывается неоднократно. Для решения этой проблемы, командный интерпретатор bash предоставляет особый механизм, называемый командной подстановкой.

   $(команда)

или

   `команда`

При подстановке команда выполняется, а выданные результаты автоматически подставляются на ее место. Командная подстановка может быть вложенной. Для этого нужно использовать форму $() или экранировать внутренние кавычки `` при помощи символов \[1].

Tip-icon.gif

Для решения похожих задач может использоваться команда xargs, которая строит и вызывает командную строку на основе данных, поступающих на стандартный поток ввода.

[править] Пример. Командная подстановка

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

   $ touch `cat files`

Командный интерпретатор предоставляет другой — более быстрый — способ записи конструкции `cat файл`: она имеет вид `<файл`. Вышеприведенный пример выглядит так:

   $ touch `<users`

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

   $ du `find ~ -atime 5`

Рассмотрим этот пример более подробно. Команда du сообщает размер всех файлов, перечисленных в качестве ее параметров. Команда find выводит список всех файлов, находящихся в каталоге ~ (домашнем каталоге), к которым не было доступа последние 24*5=120 часов. После командной подстановки получается, что параметрами команда du являются имена всех файлов, к которым не было доступа последние 5 суток.

Еще один пример с командой find. Удаление из домашнего каталога всех файлов core, создаваемых при крахе программ:

   $ rm -f `find ~ -name core`

[править] Подстановка переменных и параметров

Интерпретатор заменяет все названия переменных их содержимым. Конструкция вида $имя рассматривается интерпретатором как переменная окружения. Интерпретатор заменяет каждую переменную окружения ее значением. Если переменная не определена, при интерпретации она заменяется пустым значением или, другими словами, попросту удаляется из текста.

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

Интерпретатор bash поддерживает несколько дополнительных конструкций, повышающих гибкость и удобство подстановки параметров в определенных случаях:

Note-icon.gif

Если отсутствует двоеточие <:>, выполняется проверка только на то, существует ли переменная. Является ли переменная пустой или нет не имеет значения.

${имя:-значение}
Использовать значение по умолчанию. Если переменная имя неизвестна или пуста, подставляется значение, иначе значение переменной имя;
${имя:=значение}
Присвоить значение по умолчанию. Аналогична предыдущему, но только в том случае, если имя не определено, переменной имя присваивается значение.
${имя:?значение}
Выдать ошибку, если переменная не определена. Если имя не определено, сообщить об ошибке на стандартный поток ошибок. В качестве текста сообщения использовать значение.
${имя:+значение}
Использовать альтернативное значение. Если имя определено, ничего не подставляется (конструкция удаляется). Иначе, подставляется значение.
${имя:смещение} ${имя:смещение:длина}
Подстановка подстроки. Подставляется подстрока переменной имя, начиная с позиции смещение. Если задана длина, то подставляется соответствующее количество символов, иначе строка до конца.
${!префикс*}
Подставляются имена всех переменных, которые начинаются на заданную последовательность префикс.
${#имя}
Количество символов в значении переменной имя. Если имя — массив, то подставляется количество элементов массива.

[править] Замена тильды

В Linux символ ~ означает домашний каталог пользователя. Интерпретатор bash идет дальше и развивает эту идею. Слово вместе с предшествующей ему тильдой ~имя, заменяется на имя домашнего каталога пользователя под названием имя (~i становится /home/i, где /home/i — домашний каталог пользователя i).

Символы ~+ означают содержимое переменной окружения PWD (текущий каталог), а ~- — содержимое переменной окружения OLDPWD, т.е. каталога, в котором пользователь находился до того, как перешел в текущий каталог. Символы ~+ и ~- можно указывать с дополнительными численными параметрами, которые означают глубину перехода по стеку каталогов (см. bash(1)/pushd).


[править] Арифметическая подстановка

Арифметическая подстановка позволяет вычислить арифметическое выражение и подставить на его место результат.

   $((Арифметическое выражение))

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

[править] Пример. Арифметическая подстановка

Вот немного наивный пример подсчета количества пользователей системы, у которых нет домашних каталогов:

   $ echo $((`cat /etc/passwd |wc -l` - `ls /home |wc -w` ))

Количество строк в файле /etc/passwd, равное количеству пользователей системы, минус количество слов в листинге каталога /home, которое должно быть равно количеству домашних каталогов пользователей.

Для арифметической подстановки есть ещё конструкция $[ ... ], но она считается нестандартной, поддерживается не всеми интерпретаторами, и её лучше не использовать[2].

[править] Экранирование и кавычки

Эти темы не раскрыты: Написать про то, какие кавычки бывают, чем они отличаются, как и где их использовать, как можно экранировать сами кавычки[3].

[править] Перенаправление и каналы

Основная страница: Стандартные потоки ввода/вывода

[править] Перенаправление

Процесс взаимодействия с пользователем выполняется в терминах записи и чтения в файл. То есть вывод на экран представляется как запись в файл, а ввод — как чтение файла. Файл, из которого осуществляется чтение, называется стандартным потоком ввода, а в который осуществляется запись — стандартным потоком вывода. [Замечание] Замечание

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

Кроме потоков ввода и вывода, существует еще и стандартный поток ошибок, на который выводятся все сообщения об ошибках и те информативные сообщения о ходе работы программы, которые не могут быть выведены в стандартный поток вывода.

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

Операторы перенаправления в bash.

<файл
Использовать файл как источник данных для стандартного потока ввода.
>файл
Направить стандартный поток вывода в файл. Если файл не существует, он будет создан; если существует — перезаписан сверху.
2>файл
Направить стандартный поток ошибок в файл. Если файл не существует, он будет создан; если существует — перезаписан сверху.
>>файл
Направить стандартный поток вывода в файл. Если файл не существует, он будет создан; если существует — данные будут дописаны к нему в конец.
2>>файл
Направить стандартный поток ошибок в файл. Если файл не существует, он будет создан; если существует — данные будут дописаны к нему в конец.
&>файл или >&файл
Направить стандартный поток вывода и стандартный поток ошибок в файл. Другая форма записи: >файл 2>&1.

[править] Пример. Перенаправление

Эта команда объединяет три файла: header, body и footer в один файл letter:

   $ cat header body footer > letter

Команда cat по очереди выводит содержимое файлов, перечисленных в качестве параметров на стандартный поток вывода. Стандартный поток вывода перенаправлен в файл letter.

Здесь используется сразу перенаправление стандартного потока ввода и стандартного потока вывода:

   $ sort < unsortedlines > sortedlines

Программа sort сортирует данные, поступившие в стандартный поток ввода, и выводит их на стандартный поток вывода. Стандартный поток ввода подключен к файлу unsortedlines, а выход записывается в sortedlines.

Здесь перенаправлены потоки вывода и ошибок:

   $ find /home -name '*.rpm' >rpmlist 2> /dev/null

Программа find ищет в каталоге /home файлы с суффиксом .rpm. Список найденных файлов записывается в файл rpmlist. Все сообщения об ошибках удаляются. Удаление достигается при помощи перенаправления потока ошибок на устройство /dev/null — специальный фиктивный файл, означающий ничто. Данные, отправленные туда, безвозвратно исчезают.

[править] Каналы

Стандартные потоки можно перенаправлять не только в файлы, но и на вход других программ. Если поток вывода одной программы соединить с потоком ввода другой программы, получится конструкция, называемая каналом или трубопроводом (от англ. pipe).

В bash канал выглядит как последовательность команд, отделенных друг от друга символом |:

   команда1 | команда2 | команда3 ...

Стандартный поток вывода команды1 подключается к стандартному потоку ввода команды2, стандартный поток вывода команды2 в свою очередь подключается к потоку ввода команды3 и т.д.

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

Note-icon.gif

Каналы в ОС Linux являются одной из наиболее часто применяемых конструкций, а фильтры — наиболее часто применяемых программ. Большинство повседневных задач в Linux легко решаются при помощи конструкций построенных на основе нескольких фильтров.

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

Можно создавать ответвление в каналах. Команда tee позволяет сохранять данные, передающиеся в канале:

   tee [опции] файл... 

Программа tee копирует данные, поступающие на стандартный поток ввода, в указанные в качестве аргументов команды файлы, и передает данные на стандартный поток вывода.

[править] Каналы

Пример: сортируется файл unsortedlines и результат записывается в sortedlines.

   $ cat unsortedlines | sort > sortedlines

Команда выполняет те же действия, но запись является более наглядной.

Вот пример посложнее. Вывести название и объем пользовательского каталога, занимающее наибольшее место на диске.

   $ du -s /home/*1 | sort -nr2 | head -13

Уже известная команда du, при вызове ее с ключом -s, сообщает суммарный объем каждого каталога или файла, перечисленного в ее параметрах.

Ключ -n команды sort означает, что сортировка должна быть арифметической, т.е. строки должны рассматриваться как числа, а не как последовательности символов (Например, 12>5 в то время как строка '12'<'5' т.к. сравнение строк производится посимвольно и '1'<'5'). Ключ -r означает изменения порядка сортировки — с возрастающего на убывающий.

Команда head выводит несколько первых строк поступающего на ее вход потока, отбрасывая все остальные. Ключ -1 означает, что надо вывести только одну строку.

Таким образом, список пользовательских каталогов с их суммарным объемом 1 арифметически сортируется по убыванию 2 и из полученного списка берется первая строка 3, т.е. строка с наибольшим числом, соответствующая самому объемному каталогу.

Использование команды tee:

   $ sort text | tee sorted_text | head -n 1

Содержимое файла text сортируется, и результат сортировки записывается в файл sorted_text. Первая строка отсортированного текста выдается на экран.

[править] Программы-фильтры

Эти темы не раскрыты: Написать про то, что такое программа фильтр и какие основные программы-фильтры используются в UNIX

[править] Проверки

Эти темы не раскрыты: Написать про test и про командные скобки, а также про код завершения

[править] Последовательности команд и командные конструкции

Эти темы не раскрыты: Написать про &&,

[править] Вопросы и ответы

[править] Как посмотреть текущую привязку комбинаций клавиш к действиям?

bind -p

[править] Дополнительная информация

Работа с аргументами командной строки:

[править] Примечания

  1. Тонкости использования командной подстановки: http://wiki.bash-hackers.org/syntax/expansion/cmdsubst
  2. https://groups.google.com/forum/?fromgroups#!topic/gnu.bash.bug/HoPd5I2Zqzk%5B1-25%5D о том почему $(()) лучше чем $[ ]
  3. http://wiki.bash-hackers.org/syntax/quoting (англ.) — подробно о кавычках