Они эквивалентны.
Относительный порядок перенаправлений может иметь значение, но не их положение по отношению к команде.
Эта команда
make 2>&1 | tee myfifo | grep -E "errors|warnings" myfifo > errors.log | cat myfifo
P1 P2 P3
не имеет большого смысла. Он запускает эти 4 команды одновременно с каналами между ними:
make 2>&1
: стандартный вывод и стандартный вывод направляются на P1 tee myfifo
: стандартный ввод с P1, стандартный вывод с P2. Итак, tee
записывает вывод как в myfifo
, так и в P2. grep -E "ошибки|предупреждения" myfifo > errors.log
: стандартный ввод из P2, но вы передаете имя файла (myfifo
) в grep
, поэтому grep
не будет читать со своего стандартного ввода. stdout переходит в errors.log
, ничего не пишет в P3 cat myfifo
: stdin из P3, но опять же, поскольку cat
получает имя файла, он вместо этого читает его. Таким образом, grep
и cat
читают из myfifo
одновременно. Поскольку с P2 ничего не читается, tee
зависнет, когда P2 будет заполнен. Также cat
не будет отображать части myfifo
, прочитанные grep
.
make 2>&1 | tee myfifo | grep -e errors -e warnings > errors.log | cat myfifo
ближе к тому, что вы имели в виду, я думаю. Опять же, P3 не используется, но мы используем |
, чтобы одновременно запустить cat
и дождаться его.
Или вы можете сделать:
make 2>&1 | tee myfifo & grep -e errors -e warnings > errors.log
wait
Если вам нужно больше grep
s, вам нужно больше fifos:
make 2>&1 | tee fifo2grep1 fifo2grep2 &
grep errors fifo2grep1 > errors.log &
grep warnings fifo2grep2 > warnings.log
wait
В системах, поддерживающих /dev/fd/x
, вы также может делать:
make 2>&1 | { tee /dev/fd/3 | grep -e errors -e warnings 3>&-; } 3>&1
(обычно это то, что делает подстановка процесса в оболочках, которые ее поддерживают).
С 2 grep
получается:
make 2>&1 |
{
{
tee /dev/fd/3 /dev/fd/4 |
grep errors > errors.log 3>&- 4>&-
} 4>&1 |
grep warnings > warnings.log 3>&-
} 3>&1
После grep -E "errors | warnings" myfifo> errors.log
канал больше не содержит данных. Таким образом, следующая команда cat myfifo
, читающая из канала, будет заблокирована.
Если я правильно понял ваш вопрос, вы хотите распечатать все сообщения на стандартный вывод и перенаправить все сообщения об ошибках и предупреждения в errors.log
. Итак, если вы хотите использовать канал, используйте два:
mkfifo pipe1 pipe2
make 2>&1 | tee pipe1 pipe2 | grep -E "errors|warnings" pipe1 > errors.log | cat pipe2