Хороший способ уловить разницу между ними - немного поэкспериментировать в командной строке. Несмотря на визуальное сходство в использовании <
персонажа, он делает что-то очень отличное от перенаправления или конвейера.
Давайте использовать date
команду для тестирования.
$ date | cat
Thu Jul 21 12:39:18 EEST 2011
Это бессмысленный пример, но он показывает, что cat
принял вывод команды date
STDIN и выплюнул ее обратно. Те же результаты могут быть достигнуты путем замены процесса:
$ cat <(date)
Thu Jul 21 12:40:53 EEST 2011
Однако то, что произошло за кадром, было другим. Вместо того, чтобы получить поток STDIN, cat
ему фактически передали имя файла, который нужно было открыть и прочитать. Вы можете увидеть этот шаг, используя echo
вместо cat
.
$ echo <(date)
/proc/self/fd/11
Когда cat получил имя файла, он прочитал содержимое файла для нас. С другой стороны, echo просто показал нам имя файла, который был передан. Эта разница становится более очевидной, если вы добавите больше замен:
$ cat <(date) <(date) <(date)
Thu Jul 21 12:44:45 EEST 2011
Thu Jul 21 12:44:45 EEST 2011
Thu Jul 21 12:44:45 EEST 2011
$ echo <(date) <(date) <(date)
/proc/self/fd/11 /proc/self/fd/12 /proc/self/fd/13
Можно объединить подстановку процесса (который генерирует файл) и перенаправление ввода (который подключает файл к STDIN):
$ cat < <(date)
Thu Jul 21 12:46:22 EEST 2011
Это выглядит примерно так же, но на этот раз кошке был передан поток STDIN вместо имени файла. Вы можете увидеть это, попробовав это с помощью echo:
$ echo < <(date)
<blank>
Поскольку echo не читает STDIN и аргумент не передается, мы ничего не получаем.
Каналы и входные данные перенаправляют содержимое в поток STDIN. Подстановка процессов запускает команды, сохраняет их вывод в специальный временный файл и затем передает это имя файла вместо команды. Любая команда, которую вы используете, обрабатывает ее как имя файла. Обратите внимание, что созданный файл - это не обычный файл, а именованный канал, который удаляется автоматически, когда он больше не нужен.
[[ -p <(date) ]] && echo true
. Это выдает,true
когда я запускаю его с bash 4.4 или 3.2.Я должен предположить, что вы говорите о
bash
какой-то другой расширенной оболочке, потому что оболочка posix не имеет подстановки процессов .bash
справочные страницы отчетов:Другими словами, и с практической точки зрения, вы можете использовать выражение, подобное следующему
в качестве имени файла для других команд, для которых в качестве параметра требуется файл. Или вы можете использовать перенаправление для такого файла:
Возвращаясь к вашему вопросу, мне кажется, что процесс замещения и каналы имеют мало общего.
Если вы хотите последовательно передать вывод нескольких команд, вы можете использовать одну из следующих форм:
но вы также можете использовать перенаправление при замене процесса
наконец, если
command3
принимает параметр файла (в подмену stdin)источник
Вот три вещи, которые вы можете сделать с заменой процесса, которые невозможны в противном случае.
Несколько входов процесса
Там просто нет способа сделать это с трубами.
Сохранение STDIN
Скажем, у вас есть следующее:
И вы хотите запустить его напрямую. Следующее терпит неудачу с треском. Bash уже использует STDIN для чтения сценария, поэтому другой ввод невозможен.
Но этот способ работает отлично.
Замена исходящего процесса
Также обратите внимание, что процесс подстановки работает и в другом направлении. Таким образом, вы можете сделать что-то вроде этого:
Это немного запутанный пример, но он отправляет stdout во
/dev/null
время передачи stderr сценарию sed для извлечения имен файлов, для которых была отображена ошибка «Permission denied», а затем отправляет результаты THOSE в файл.Обратите внимание, что первая команда и перенаправление stdout заключены в круглые скобки ( подоболочка ), поэтому отправляется только результат команды THAT,
/dev/null
и он не связывается с остальной частью строки.источник
diff
примере вы можете заботиться о том случае , когдаcd
может завершиться неудачей:diff <(cd /foo/bar/ && ls) <(cd /foo/baz && ls)
.Если команда принимает список файлов в качестве аргументов и обрабатывает эти файлы как ввод (или вывод, но не часто), каждый из этих файлов может быть именованным каналом или псевдофайлом / dev / fd, прозрачно предоставляемым подстановкой процесса:
Это будет «передавать» выходные данные трех команд для сортировки, так как сортировка может принимать список входных файлов в командной строке.
источник
<()
, как и многие расширенные функции оболочки, изначально был функцией ksh и был принят bash и zsh.psub
это особенность рыбы, никак не связанная с POSIX.Следует отметить, что процесс подстановки не ограничивается формой
<(command)
, в которой выходные данные используютсяcommand
в виде файла. Это может быть в форме,>(command)
которая также подает файл в качестве входных данныхcommand
. Это также упоминается в цитате из руководства bash в ответе @ enzotib.Для
date | cat
приведенного выше примера команда, использующая процесс подстановки формы>(command)
для достижения того же эффекта, будет иметь вид:Обратите внимание, что
>
перед>(cat)
необходимо. Это снова может быть ясно проиллюстрировано,echo
как в ответе @ Caleb.Так что, без лишних
>
,date >(cat)
будет то же самое,date /dev/fd/63
что будет выводить сообщение на stderr.Предположим , у вас есть программа , которая только принимает имена файлов в качестве параметров и не обрабатывать
stdin
илиstdout
. Я буду использовать упрощенный сценарий,psub.sh
чтобы проиллюстрировать это. Содержаниеpsub.sh
ISВ принципе, он проверяет , что оба его аргументы файлы (не обязательно обычные файлы) , и если это так, то напишите первое поле каждой строки
"$1"
с"$2"
использованием AWK. Затем команда, которая объединяет все, что упомянуто до сих пор,Это напечатает
и эквивалентно
но следующее не будет работать, и мы должны использовать здесь процесс подстановки,
или его эквивалентная форма
Если
./psub.sh
также читаетstdin
кроме того, что упомянуто выше, то такой эквивалентной формы не существует, и в этом случае мы ничего не можем использовать вместо подстановки процесса (конечно, вы также можете использовать именованный канал или временный файл, но это другое сказка).источник