Почему трубы используются вместо перенаправления ввода
Я новичок в системах Linux и не могу понять, почему нам нужны два оператора, которые могут перенаправить вывод: pipe as |
и оператор перенаправления вывода >
? Разве мы не можем всегда использовать второе? В большинстве случаев я вижу, что канал используется, если несколько команд связаны друг с другом. Однако, если вывод перенаправляется в файл, как в echo 'hello' > filename
, используется оператор перенаправления вывода. Что мне здесь не хватает?
4 ответа
Ключевой момент, который следует помнить, состоит в том, что каналы являются устройством межпроцессного взаимодействия, которое позволяет двум процессам (и это действительно команды) обмениваться данными, в то время как операторы перенаправления предназначены для манипулирования тем, где пишет конкретный процесс.
В ролике Unix Pipeline, создатель awk
Язык и один из оригинальных людей, которые работали над AT&T Unix, Брайан Керниган объясняет:
Во-первых, вам не нужно писать одну большую массивную программу - у вас есть более мелкие программы, которые могут уже выполнять часть работы... Другое - то, что возможно, что объем обрабатываемой вами информации не будет соответствовать вы сохранили его в файле... потому что помните, мы вернулись во времена, когда диски на этих вещах имели, если вам повезло, один или два мегабайта данных... Таким образом, конвейер никогда не должен был создавать весь вывод
Как вы можете видеть, в контексте, в котором создавались конвейеры, они фактически были не просто устройством связи, но также экономили место для хранения и упрощали разработку. Конечно, мы можем использовать перенаправление вывода / ввода для всего (особенно в настоящее время с емкостью хранения в диапазоне терабайт), однако это будет неэффективно с точки зрения хранения, а также со скоростью обработки - помните, что вы напрямую подаете выходные данные из одной команды в другую с |
, Рассмотреть что-то вроде command1 | grep 'something'
, Если вы напишите вывод command1
сначала в файл, потребуется время, чтобы написать все, а затем grep
пройти весь файл. При использовании конвейера и того факта, что выходные данные буферизуются (это означает, что левый процесс приостанавливается до того, как правый процесс снова готов к чтению), выходные данные передаются напрямую от одной команды к другой, что экономит время.
Стоит отметить, что для межпроцессного взаимодействия есть вариант использования именованных каналов, к которому вы можете использовать >
оператор для записи из одной команды, и <
чтобы позволить другой команде читать из нее, и это тот случай, когда вы хотите иметь конкретный пункт назначения в файловой системе, где несколько сценариев / команд могут писать и согласовывать этот конкретный пункт назначения. Но когда это не нужно, анонимный канал |
это все, что вам действительно нужно.
Я считаю, что операторы < > используются для чтения / записи файлов, тогда как | Символ используется для передачи стандартного вывода одной команды к другой.
cal | less
позволяет просматривать вывод команды cal с помощью команды less.
cal > less
помещает вывод cal в файл с именем less.
|
используются для отправки выходных данных одной команды в качестве входных данных для другой команды, которая идет после символа канала.$ echo foo | grep -o 'f' f
Чтобы перенаправить вывод одной команды в файл, вы можете использовать перенаправление вывода
>
оператор.$ echo foo > file1
Пишет
foo
в файл1. Вам не нужно вручную создавать этот файл.Если вы хотите перенаправить вывод на множество файлов, вам придется использовать
tee
команда.echo foo | tee file1 file2
Пишет
foo
в файл1 и файл2. Вам не нужно вручную создавать эти файлы. Теперь file1 и file2 содержат только строкуfoo
,
Существует много разговоров о перенаправлении вывода, но я подумал, что этот вопрос касается ввода. Я собираюсь игнорировать >
а также >>
потому что они не имеют ничего общего с вводом. Вместо этого я собираюсь сосредоточиться на <
, <(...)
а также |
:
<
ожидает чтения из файла вSTDIN
в то время как,<(...)
обеспечивает дескриптор файла дляSTDOUT
команды (...
Вот)|
трубыSTDOUT
из одного процесса вSTDIN
следующего
Итак <
не является прямым эквивалентом канала (это чтение из файла) и <(...)
читает из правильного места, но это дает дескриптор файла в качестве вывода. Вам нужно объединить их, чтобы предложить эквивалент трубы.
a | b
< <(a) b
Просто прочитав это, я надеюсь, что это полностью объясняет, почему существует труба. Это гораздо более читабельно.