Стандартный вывод не отличается от любого другого открытого файла, единственная особенность - это дескриптор файла 1
(поэтому в вашем процессе может быть только один дескриптор файла с индексом 1). Вы можете dup(2)
дескриптор файла1
чтобы получить, скажем, дескриптор файла 6
.В этом и заключается задача dup()
просто получить другой дескриптор файла (с другим номером), чем тот, который вы используете в качестве источника, , но для того же источника .Опущенные дескрипторы позволяют безразлично использовать любой из опущенных дескрипторов для вывода или изменять открытые флаги, такие как закрывать при exec флаг или неблокировать или append flag (не все являются общими, я не уверен, какие из них можно изменить, не затрагивая другие в дупле).Они совместно используют указатель файла, поэтому каждый write()
, который вы пытаетесь использовать для любого из файловых дескрипторов, будет обновляться в других.
Но идея перенаправления не в этом.Соглашение в Unix гласит, что каждая программа получит три дескриптора , уже открытых от своего родительского процесса.Итак, чтобы использовать разветвление, сначала вам нужно подумать о том, как написать нотацию для выражения того, что программа получит (уже открыл) более одного выходного потока (чтобы вы могли перенаправить любой из них правильно, перед вызовом программы ) То же самое относится и к объединению потоков.Здесь проблема более сложная, так как вам нужно выразить, как потоки данных могут быть объединены в один, и это делает проблему объединения зависимой от проблемы.
Файл dup()
pingне способ заставить файловый дескриптор записывать в два файла ... но наоборот, это способ сделать два разных файловых дескриптора для ссылки на один и тот же файл .
Единственный способ сделать то, что вы хотите, - это дублировать write(2)
вызовов на каждом дескрипторе файла, который вы собираетесь использовать.
Как прокомментировал какой-то ответ, команда tee(1)
позволяет вам разветвлять поток данных.в канале, но не с файловыми дескрипторами, tee(1)
просто открывает файл и write(2)
s вводит весь ввод, в дополнение к записи (2), также выводит его на стандартный вывод.
Там нетпредоставление для разветвления потоков данных в оболочке, так как нет условий для объединения (в частности) потоков данных на входе.Я думаю, что это некоторая заброшенная идея в дизайне оболочки Стива Борна, и вы, вероятно, дойдете до той же точки.
Кстати, просто изучите возможность использования общего оператора dup2()
, который является <<em> n >&
m >, но, опять же, учтите, что для программы перенаправления 2>&3 2>&4 2>&5 2>&6
означает, что вы предварительно открыли 7 файловых дескрипторов, 0
...6
, в котором stderr
является псевдонимом дескрипторов 3
до 6
(поэтому любые данные, записанные в любой из этих дескрипторов, появятся в том, что было stderr
), или вы можете использовать 2<file_a 3<file_b 4<file_c
, что означает, что ваша программа будетвыполняется с дескриптором файла 2
(stderr), перенаправленным с file_a
, а дескрипторы файла 3
и 4
уже открыты из файлов file_b
и file_c
.Вероятно, некоторые нотации должны быть разработаны (и сейчас мне не легко понять, как их разработать), чтобы обеспечить возможность передачи (с помощью системного вызова pipe(2)
) между различными процессами, которые были запущены для выполнения какой-либо задачи,но вам нужно построить общий граф, чтобы учесть общность.