передать стандартный вывод в качестве имени файла для командной строки util? - PullRequest
31 голосов
/ 13 октября 2011

Я работаю с утилитой командной строки, которая требует передачи имени файла для записи вывода, например,

foo -o output.txt

Единственное, что он записывает в stdout, - это сообщение, которое указывает, чтоэто бежало успешно.Я хотел бы иметь возможность передавать все, что записано в output.txt, в другую утилиту командной строки.Моя мотивация заключается в том, что output.txt в конечном итоге станет файлом размером 40 ГБ, который мне не нужно хранить, и я предпочел бы передавать потоки, а не работать с массивными файлами пошагово.

Есть ли способ в этом сценарии передать реальный вывод (например, output.txt) другой команде?Могу ли я каким-то волшебным образом передать stdout в качестве аргумента файла?

Ответы [ 5 ]

48 голосов
/ 13 октября 2011

Именованные каналы работают нормально, но у вас есть более приятный, более прямой синтаксис, доступный через подстановку процессов bash, что дает дополнительное преимущество - не использовать постоянный именованный канал, который впоследствии должен быть удален (подстановка процесса использует временные именованные каналы за кулисами). :

foo -o >(other command)

Кроме того, если вы хотите направить вывод в вашу команду и также сохранить вывод в файл, вы можете сделать это:

foo -o >(tee output.txt) | other command

37 голосов
/ 13 октября 2011

Решение 1. Использование процесса замены

Наиболее удобный способ сделать это - использовать процесс замены.В bash синтаксис выглядит следующим образом:

foo -o >(other_command)

(обратите внимание, что это bashism . Есть аналогичные решения для других оболочек, но суть в том, что он не переносимый.)

Решение 2. Использование именованных каналов явно

Вы можете сделать это явно / вручную следующим образом:

  1. Создать именованный каналиспользуя команду mkfifo.

    mkfifo my_buf
    
  2. Запустите другую команду с этим файлом в качестве ввода

    other_command < my_buf
    
  3. Выполнить fooи позвольте ему записать свой вывод в my_buf

    foo -o my_buf
    

Решение 3. Использование /dev/stdout

Вы также можете использовать файл устройства /dev/stdout следующим образом

foo -o /dev/stdout | other_command
31 голосов
/ 09 сентября 2015

Ради счастья stackoverflow позвольте мне написать достаточно длинное предложение, потому что мое предлагаемое решение имеет длину всего 18 символов вместо необходимых 30 +

foo -o /dev/stdout
5 голосов
/ 13 октября 2011

Вы можете использовать магию UNIX и создать именованный канал:)

  1. Создать трубу

    $ mknod -p mypipe
    
  2. Запустить процесс, который читает из канала

    $ second-process < mypipe
    
  3. Запустить процесс, который пишет в канал

    $ foo -o mypipe
    
1 голос
/ 09 января 2012

Я использую / dev / tty в качестве имени выходного файла, что эквивалентно использованию / dev / nul /, когда вы вообще ничего не хотите выводить. Тогда | и все готово.

...