Что касается вашего вопроса производительности, каналы более эффективны, чем файлы, потому что дисковый ввод-вывод не требуется. Так cmd1 | cmd2
является более эффективным , чем cmd1 > tmpfile; cmd2 < tmpfile
(это может не быть правдой , если tmpfile
поддерживается на диске RAM или другого устройства памяти как именованный канал, но если это именованный канал, cmd1
должен работать в фоновом режиме , как его выход может блокировать , если труба заполняется ). Если вам нужен результат cmd1
и все еще нужно отправить его вывод cmd2
, вы должны cmd1 | tee tmpfile | cmd2
разрешить cmd1
и cmd2
запускать параллельно, избегая операций чтения с диска cmd2
.
Именованные каналы полезны, если многие процессы читают / пишут в один и тот же канал. Они также могут быть полезны, когда программа не предназначена для использования stdin / stdout для своих операций ввода-вывода, нуждающихся в использовании файлов . Я поместил файлы курсивом, потому что именованные каналы не являются файлами с точки зрения хранения, поскольку они находятся в памяти и имеют фиксированный размер буфера, даже если они имеют запись в файловой системе (для справочных целей). У других вещей в UNIX есть записи файловой системы, не являющиеся файлами: просто представьте себе /dev/null
или другие записи в /dev
или /proc
.
Поскольку каналы (именованные и безымянные) имеют фиксированный размер буфера, операции чтения / записи в них могут блокироваться, в результате чего процесс чтения / записи переходит в состояние IOWait. Кроме того, когда вы получаете EOF при чтении из буфера памяти? Правила этого поведения хорошо определены и могут быть найдены в человеке.
Одна вещь, которую вы не можете сделать с каналами (именованными и безымянными), это поиск в данных. Поскольку они реализованы с использованием буфера памяти, это понятно.
О "everything in Linux/Unix is a file"
, я не согласен. Именованные каналы имеют записи файловой системы, но не являются точно файловыми. Безымянные каналы не имеют записей файловой системы (кроме, может быть, в /proc
). Однако большинство операций ввода-вывода в UNIX выполняются с использованием функции чтения / записи, для которой требуется файловый дескриптор , включая безымянный канал (и сокет). Я не думаю, что мы можем сказать это "everything in Linux/Unix is a file"
, но мы, конечно, можем сказать это "most IO in Linux/Unix is done using a file descriptor"
.