И труба и перенаправление существуют в оболочке
Как объяснить вывод cat /etc/passwd | cat </etc/issue
?
В этом случае второй cat
получает содержимое от /etc/passwd
как $STDIN
и опять /etc/issue
перенаправлен Почему есть только /etc/issue
оставил?
Более того, cat </etc/passwd </etc/issue
только выводит содержимое в /etc/issue
, Является /etc/passwd
перезаписаны?
Я не ищу решение, как cat
два файла, но путать с тем, как pipeline
работает.
2 ответа
Трубопровод и перенаправление обрабатываются слева направо.
Итак, сначала ввод cat
перенаправлен на трубу. Затем он перенаправляется на /etc/issue
, Затем программа запускается, используя последнее перенаправление, которым является файл.
Когда вы делаете cat <file1 <file2
, STDIN сначала перенаправлен на file1
затем он перенаправляется на file2
, Затем программа запускается и получает данные от последнего перенаправления.
Это как присвоение переменных. Если вы делаете:
stdin=passwd
stdin=issue
Значение stdin
в конце последний назначенный.
Это объясняется в bash
документация, в первом абзаце раздела о перенаправлении:
Перед выполнением команды ее ввод и вывод могут быть перенаправлены с использованием специальных обозначений, интерпретируемых оболочкой. Перенаправление может также использоваться для открытия и закрытия файлов для текущей среды выполнения оболочки. Следующие операторы перенаправления могут предшествовать или появляться в любом месте простой команды или могут следовать за командой. Перенаправления обрабатываются в порядке их появления слева направо.
(акцент мой). Я предполагаю, что это также в спецификации оболочки POSIX, я не потрудился посмотреть на это. Так всегда вели себя оболочки Unix.
Сначала создается труба: стандартный вывод cat /etc/passwd
отправляется на запись стороне трубы, и стандартный ввод cat </etc/issue
установлен на стороне чтения канала. Затем команда на каждой половине трубы обрабатывается. На LHS нет другого перенаправления ввода / вывода, но на RHS стандартный ввод перенаправляется, поэтому /etc/issue
, Это означает, что на самом деле ничего не читается в конце чтения канала, поэтому LHS cat
завершается SIGPIPE (возможно; в качестве альтернативы он записывает данные в канал, но ни один процесс не читает их). LHS cat
никогда не знает о вводе канала - он имеет только вход файла для стандартного ввода.