Перевод статьи «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.
$ mkfifo -m 666 sharedpipe
$ ls -l mypipe0
prw-rw-rw-. 1 shs shs 0 Aug 7 12:50 sharedpipe
в этом листинге откуда взялось mypipe0?