Зачем нужен конвейер команд в bash

Изучаем Bash. Часть 1.


Сегодня начнём разбирать возможности bash.
Так как этот вопрос довольно объёмный, то его придётся разбить на несколько частей. Так что пойдём от простого к сложному. Кстати, есть очень большая вероятность, что информация, усвоенная при изучении bash, пригодится при работе с другими командными интерпретаторами.
Стандартный поток ввода и вывода.
Это довольно важные понятия означают всего навсего то, откуда по умолчанию читает программа данные (stdin) и куда выводит результаты своей работы (stdout). Также существует стандартный поток вывода ошибок (stderr). Обычно это экран (точнее, терминал пользователя) + клавиатура. Для чего это надо знать? А дело в том, что все эти потоки можно перенаправлять. Чаще всего для ввода/вывода используют файлы.
Например, так можно создать файл, содержащий список фалов в указанной директории.
$ ls -l > ~/file_with_files
Кстати, стоит помнить, что при следующем выполнении, файл будет полностью переписан, и всё, что было раньше потеряется. Если же нужно дописать в конец файла, то нужно использовать «>>» вместо «>»
$ ls -l >> ~/file_with_files
Также, при выполнении команды можно разделять потоки.
stdin имеет номер 0
stdout имеет номер 1
stderr имеет номер 2
То есть можно выводить ошибки в отдельный файл, причём обычные сообщения будут при этом отображаться как обычно. Для этого нужно перед «>» поставить число 2 (номер потока, аналогично для stdin, stdout). Например так
$ find / -name .bashrc 2> ~/finderrors.txt
Кроме того, существует такое устройство как /dev/null, на который можно также перенаправлять вывод. При этом ничего из направленного не будет нигде отображаться.
$ find / -name asdf 2 > /dev/null
Вывод можно направлять и в другую команду. Например, следующая команда выведет количество слов в файле
$ cat ~/finderrors.txt > wc -w
Если вам нужно написать скрипт, в котором какая-то программа требует ввода, то можно направить в неё содержимое файла
$ wc -w < ~/finderrors.txt
Примечание. «>» без указания номера потока трактуется как «1 >». То есть выводится будет только stdin.
Конвейеры.
Наверняка вы видели команды следующего вида:
$ cat /etc/bash.bashrc | more
В результате её работы будет приостановлен вывод при заполнении экрана. Так вот, «|» и есть этот самый конвейер. Говоря по-умному, это — канал, в который один процесс может только писать, а другой — только читать. Выборка и помещение в такой конвейер идёт по принципу FIFO (First In — First Out). Также этот принцип называется очередь, что очень просто и точно характеризует его работу. Конвейеры используются для того, чтобы скомбинировать работу нескольких маленьких программ.
Разберём работу следующей команды.
$ cat myfile | grep Linux | we -1
Сначала cat myfile выводит содержимое файла myfile, затем grep Linux считывает вывод и выделяет только строки содержащие слово Linux. Потом wc -l считает количество строк. В результате мы получим количество строк, содержащих слово Linux.
Очень удобно использовать утилиту xargs вместе с «|». xargs читает элементы вывода stdin, разделённые пробелами и выполняет программу, передав их ей один или несколько раз.
Например
$ find /tmp -name core -type f -print | xargs /bin/rm -f
Эта команда находит файлы с именем core в директории /tmp и удаляет их.
Специальные символы.
В отличие от ОС Windows, имена файлов в Linux могут содержать почти любые символы (например имя файла example*of:file вполне реально). Но некоторые знаки bash использует как служебные. И для корректной работы необходимо эти символы экранировать. Это можно делать несколькими способами.
Можно брать выражение в кавычки. Например
$ cp «example*of:file» ~
Также можно использовать одиночные кавычки
$ cp 'example*of:file' ~
Отличие состоит в том, что в одиночных кавычек теряют своё значение все спецсимволы, в двойных — все, кроме $ и \
Но самым универсальным является С-подобный способ отмены специальных символов. Для этого достаточно перед символом поставить «\» (без кавычек). Например наша команда будет выглядеть следующим образом.
$ cp example\*of\:file ~
Выполнение команд.
Существует несколько символов для организации выполнения команд.
Если нужно последовательно выполнить несколько команд, то их следует разделить символом «;». Например, следующая последовательность скомпилирует файл (а компиляция — долгий процесс, можно в это время поспать!), затем выключит компьютер.
$ make ; sudo shutdown -h now
Если же нужно выполнить программу в фоновом режиме (то есть вернуть управление пользователю сразу после запуска, это бывает удобно при запуске графических приложений), то необходимо после команды поставить символ «&». Например
$ sudo synaptic &
В результате у нас запустится synaptic и можно будет не выходя из него, пользоваться текущим эмулятором терминала.
А что же делать, если нам нужно выполнить команду только в том случае, если операция успешно завершится. Например, есть следующая задача:
Нужно скомпилировать файл. Для этого нужно выполнить configure, make, sudo make install. Причём выполнять нужно только в том случае, если предыдущая команда закончилась успешно.
В таких случаях применяет последовательность «&&». Оператор, стоящий после «&&» выполняется только в том случае, если предыдущая завершилась успешно. То есть у нас это будет выглядеть так:
$ ./configure && make && sudo make install
Если же нужно выполнить только в том случае, если программа завершится с ошибкой, то нужно использовать «||». Например, усложним задачу. Нужно будет при ошибке записать её в файл, а затем, независимо от окончания, выключить компьютер.
$ ./configure && make && make install || echo fail > ~/errorfile ; sudo shutdown -h now
Шаблоны имён файлов
Проще всего их перечислить в табличке. Стоит помнить, что шаблоны можно комбинировать в одной команде.
Шаблон Значение
* Любая последовательность символов, в том числе и пустая
? Любой одиночный символ
{a,b,c,d} Любой из символов, перечисленных в скобках
[0-6,a-d] Любой символ из указанных интервалов
[^0-6] Любой символ, не входящий в указанные интервалы
Проще всего их разбирать на примере.
Допустим, у нас есть папка, содержащая следующие файлы.
Glava01, Glava02, Glava03, Glava04, Glava05, Glava15, Glava17.
Применим шаблон Glava0* и получим список Glava01, Glava02, Glava03, Glava04, Glava05.
Применим шаблон Glava?5 и получим список Glava05, Glava15.
Применим шаблон Glava?{4,5} и получим список Glava04, Glava05, Glava15.
Применим шаблон Glava0[1-3] и получим список Glava01, Glava02, Glava03.
Выполнение арифметических выражений.
Да, bash и такое умеет. Для этого есть две формы
первая $[выражение]
вторая $((выражение))
Например
$ echo $[2+2*2]
В результате выполнения выведется число 6. Если выражение некорректно, то bash выдаст сообщение об ошибке.
Подстановка команд.
Подстановка команд является очень мощным средством bash. Смысл в том, что записанная команда меняется на результат её выполнения. Существует две формы записи
$(команда) и `команда` (в этом случае используются не одиночные кавычки, а символы, получающиеся при комбинации SHIFT+~). Например, вот яркий пример, который используется в Debian при установке заголовочных пакетов текущего ядра.
# apt-get install linux-headers-`uname -r`
Команда uname -r при своём выполнении выдаёт версию используемого ядра. То есть при выполнении у меня она меняется на
# apt-get install linux-headers-2.6.25-2-686
Причём, у вас она может приобрести другой вид. Также можно поменять ядро, а пакеты устанавливать той же командой.
Фильтры
Это команды, которые могут преобразовать входной поток данных и вывести результат на стандартный поток вывода.
Команда Краткое описание
cat На стандартный вывод (то есть
на экран) выводится содержимое указанного файла (или нескольких фай-
лов, если их имена последовательно задать в качестве аргументов команды).
grep, fgrep, egrep Ищут во входном файле или данных со стандартного ввода строки, содержащие указанный шаблон, и выдают их на стандартный вывод
tr Заменяет во входном потоке все встречающиеся символы, перечисленные в заданном перечне, на соответствующие символы из второго заданного перечня
comm Сравнивает два файла по строкам и выдает на стандартный вывод 3 колонки: в первой — строки, которые встречаются только в 1-ом файле, во второй — строки, которые встречаются только во 2-ом файле, и в третьей — строки, имеющиеся в обоих файлах
pr Форматирует для печати текстовый файл или содержимое стандартного ввода
sed Строковый редактор, использующийся для выполнения некоторых преобразований над входным потоком данных (берется из файла или со стандартного ввода)
more и less Выводят содержимое файла на экран отдельными страницами размером как раз в целый экран.
wc Подсчитывает количество слов, строк или байт в потоке.
Например,
$ grep CONFIG_XEN . -Rl | xargs -i sed -i -e 's/CONFIG_XEN/CONFIG_LUPO/g' {}
Ищет файлы в текущей папке, содержащие строку «CONFIG_XEN» и меняет её на «CONFIG_LUPO» во всех найденных файлах.
Вот тут мы и сделаем перерыв для того, чтобы разобраться во всём объёме материала. Bash — очень мощный интерпретатор и для его освоения нужна практика. В следующей статье будет рассматриваться создание скриптов для него. Начнём программировать. До следующих встреч!
Метки: линух, статьи

Tags: Зачем нужен конвейер команд в bash

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

Команды /scoreboard teams add название /scoreboard teams list /scoreboard teams join название /scoreboard teams leave ...

Linux pipes tips & tricks / Хабрахабр

Основы BASH. Часть 2. / Хабрахабр

Подскажите с решением нескольких заданий, пожалуйста. #!/bin/bash | Автор топика: Илья

30. Создайте конвейер для получения списка только имен и прав доступа к файлам, которые в данный момент находятся в Вашем рабочем каталоге. 31. Измените построенный конвейер так, чтобы список сохранялся в файле spisok Вашего HOME-каталога, а на экран выводилось только число файлов в списке. 32. Выведите на экран содержимое файла /etc/passwd, упорядоченное по полю с именем пользователя. 33. Создайте псевдоним loggedon, который будет выводить на экран упорядоченный в алфавитном порядке список имен работающих в системе пользователей. 34. Присвойте переменной IAM Ваше имя регистрации. Запустите еще один shell. Видите ли Вы эту переменную? Что нужно сделать, чтобы увидеть ее в порожденном shell? Измените значение переменной IAM в порожденном shell. Выйдите из порожденного shell. Посмотрите значение этой переменной в исходном shell. Объясните результат. 40. Напишите shell-программу hello, обеспечивающую следующую реакцию на аргументы командной строки: — аргумент “-d” — программа будет выполнять команду date; — аргумент “-l” — программа выведет содержимое текущего каталога; при отсутствии аргументов или неправильных аргументах в командной строке программа будет выводить справку о своих опциях. 41. Напишите программу words, которая будет выдавать пользователю приглашение на ввод по одному слову до тех пор, пока он не введет слово “end”. Запомните все введенные слова. После ввода слова “end” выведите на экран все введенные слова. Спасибо, если хотя бы одно из этого подскажете

Виталий 32. cat /etc/passwd | sort

Advanced Bash-Scripting Guide - Linux по-русски

Зачем необходимо знание языка Shell? 2. ..... Передача вывода от команды echo команде read, по конвейеру; 33-1. сценарий-обертка; 33-2. Более ...

Перенаправление ввода/вывода - OpenNet

Advanced Bash-Scripting Guide: Искусство программирования на языке ... Однострочные команды перенаправления # (затрагивают только ту строку, ... В конвейер передается только stderr. exec 3>&1 # Сохранить текущее ...

Сколько весит блок двигателя на трактор юмз
Отзывы о компании где продают японский минитрактор
Как сделать глушитель на трактор т 40
Показать / написать / закрыть комментарий(ии)