Перевод статьи «Pipes and more pipes on Linux».
Системы Linux поддерживают конвейеры, которые позволяют передавать вывод от одной команды к другой. Но они также поддерживают «именованные конвейеры», а это уже нечто иное.
Большинство людей, активно пользующихся командной строкой Linux, быстро переходят к использованию конвейеров. Честно говоря, они и меня привели меня в восторг, когда я впервые использовала командную строку в системе Unix, и спустя десятилетия я продолжаю восхищаться их мощью и удобством.
Используя конвейеры, я обнаружила, как много можно сделать, отправляя вывод одной команды другой, а иногда и последующим командам, чтобы дополнительно настроить нужный мне вывод. Команды, включающие конвейеры, как в примере ниже, позволили мне извлекать нужную информацию без необходимости компилировать программу или писать скрипт.
$ cat myposts | grep Linux | wc -l
1456
Эта команда отправляет содержимое файла «myposts» команде grep, ищущей слово «Linux», а затем передает вывод команде wc для подсчета количества строк в выводе.
Как вы, вероятно, подозреваете, конвейеры получили свое название благодаря сходству с промышленными конвейерами. Иногда их также называют «безымянными» или «анонимными» конвейерами, потому что это не единственный вид конвейеров, который предоставляет Linux. К этому мы еще вернемся.
На самом деле, конвейеры настолько полезны, что я часто превращаю некоторые из команд, в которых они используются, в алиасы (псевдонимы), чтобы еще больше упростить их выполнение. Например, показанную ниже команду, которая выводит список всех процессов, связанных с текущей учетной записью, можно добавить в файл .bashrc пользователя:
$ echo ‘alias myprocs=»ps -ef | grep `whoami`»‘ >> ~/.bashrc
$ tail -1 ~/.bashrc
alias myprocs=»ps -ef | grep `whoami`»
Использование алиаса:
$ myprocs
root 3219 738 0 12:15 ? 00:00:00 sshd: shs [priv]
shs 3229 1 4 12:15 ? 00:00:00 /usr/lib/systemd/systemd —user
shs 3245 3229 0 12:15 ? 00:00:00 (sd-pam)
shs 3269 3219 0 12:15 ? 00:00:00 sshd: shs@pts/0
shs 3284 3269 0 12:15 pts/0 00:00:00 -bash
shs 3319 3284 0 12:15 pts/0 00:00:00 ps -ef
shs 3320 3284 0 12:15 pts/0 00:00:00 grep —color=auto shs
Чтобы видеть только идентификаторы процессов, можно создать алиас, подобный этому:
$ alias myps=”ps aux | grep ^`whoami` | awk ‘{print $2}’”
Обратите внимание, что он ищет имя пользователя только в первом поле (на это указывает символ ^, обозначающий начало строки, и отображает второе поле. Это гарантирует, что $2 не будет интерпретироваться до тех пор, пока используется псевдоним.
Но конвейеры для передачи вывода одних команд другим не являются единственным видом конвейеров, доступных в Linux. В системах Linux существуют две совершенно разные формы конвейеров: те, что показаны выше, и т. н. «именованные конвейеры».
Именованные конвейеры
В отличие от неименованных конвейеров, именованные могут отправлять данные в любом направлении. Команды могут отправлять данные в именованные конвейеры и могут читать их содержимое. Кроме того, содержимое именованных конвейеров хранится не в файловой системе, а только в виртуальной памяти.
Именованные конвейеры позволяют процессам взаимодействовать друг с другом. Они создаются как специальные файлы в файловой системе (на это указывает первый символ в длинном листинге — «p»). Другие разрешения указывают, кто может читать или писать в конвейер.
Вот пример создания именованного конвейера с помощью команды mkfifo:
$ mkfifo mypipe
$ ls -l mypipe
prw-r—r—. 1 justme justme 0 Aug 8 13:55 mypipe
Обратите внимание на начальное «p» в выводе: оно указывает на то, что файл является именованным конвейером. Также обратите внимание на 0 в 5-м поле, который показывает, что конвейер не имеет содержимого.
Используя аргумент -m, вы можете установить права на файл, чтобы разрешить другим пользователям писать в конвейер. Обратите внимание, что по умолчанию владелец может читать и писать, а остальные — только читать. Вот пример:
$ mkfifo -m 666 sharedpipe
$ ls -l mypipe0
prw-rw-rw-. 1 shs shs 0 Aug 7 12:50 sharedpipe
Но даже если вы теперь отправите данные в именованный конвейер, он покажется пустым.
$ echo “Here comes some content” > mypipe
$ ls -l mypipe
prw-r—r—. 1 justme justme 0 Aug 13:57 mypipe
Другой процесс может прочитать содержимое с помощью команды, подобной этой:
$ cat mypipe
Here comes some content
Запустив команду, отправляющую данные в конвейер, в фоновом режиме, мы сможем прочитать эти данные с помощью команды cat. Обратите внимание, что в листинге файлов файл по-прежнему пуст, но с помощью команды cat мы можем получить текст один раз. После этого он исчезает. Однако ничто не мешает нам отправить в конвейер больше данных — пока он еще существует.
$ echo «Here comes some content» > mypipe &
[1] 1593
$ ls -l mypipe
prw-r—r—. 1 fedora fedora 0 Aug 5 13:55 mypipe
$ cat mypipe
Here comes some content
[1]+ Done echo «Here comes some content» > mypipe
$ cat mypipe
^C
Завершение
Именованные конвейеры сложнее, чем неименованные, и используются гораздо реже, но они играют интересную роль в системах Linux.
Запись Безымянные и именованные конвейеры в Linux впервые появилась techrocks.ru.