распределять вывод через FIFO

Они эквивалентны.

Относительный порядок перенаправлений может иметь значение, но не их положение по отношению к команде.

1
24.04.2017, 20:36
2 ответа

Эта команда

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

Если вам нужно больше greps, вам нужно больше 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
1
27.01.2020, 23:45

После 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
0
27.01.2020, 23:45

Теги

Похожие вопросы