передать стандартный вывод в качестве имени файла для командной строки util?
Я работаю с утилитой командной строки, которая требует передачи имени файла для записи вывода, например.
foo -o output.txt
Единственное, что он пишет в stdout
, - это сообщение, указывающее, что оно успешно сработало. Я хотел бы передать все, что записано в output.txt
, в другую утилиту командной строки. Моя мотивация заключается в том, что output.txt окажется 40-гигабайтным файлом, который мне не нужно сохранять, и я предпочел бы передавать потоки, чем работать с массивными файлами, поэтапно.
Есть ли какой-либо способ в этом сценарии передать реальный вывод (т.е. output.txt
) другой команде? Могу ли я каким-то волшебным образом передать stdout
в качестве аргумента файла?
Ответы
Ответ 1
Наиболее удобный способ сделать это - использовать процесс подстановки. В bash синтаксис выглядит следующим образом:
foo -o >(other_command)
(Обратите внимание, что это bashism. Есть аналогичные решения для других оболочек, но суть в том, что он не переносимый.)
Вы можете сделать это явно/вручную следующим образом:
-
Создайте именованный канал с помощью команды mkfifo
.
mkfifo my_buf
-
Запустите другую команду с этим файлом в качестве ввода
other_command < my_buf
-
Выполните foo
и дайте ему записать вывод в my_buf
foo -o my_buf
Решение 3. Использование /dev/stdout
Вы также можете использовать файл устройства /dev/stdout
следующим образом
foo -o /dev/stdout | other_command
Ответ 2
Именованные каналы работают нормально, но у вас есть более удобный и более прямой синтаксис, доступный через замену процесса bash, который имеет дополнительное преимущество: не использовать постоянный именованный канал, который впоследствии должен быть удален (подстановка процесса использует временные именованные каналы позади сцены):
foo -o >(other command)
Кроме того, если вы хотите передать вывод в свою команду, а также сохранить вывод в файл, вы можете сделать следующее:
foo -o >(tee output.txt) | other command
Ответ 3
Чтобы сделать stackoverflow счастливым, позвольте мне написать достаточно длинное предложение, потому что мое предлагаемое решение составляет всего 18 символов вместо требуемого 30 +
foo -o /dev/stdout
Ответ 4
Вы можете использовать магию UNIX и создать именованный канал:)
-
Создайте трубку
$ mknod -p mypipe
-
Запустите процесс, который читается из канала
$ second-process < mypipe
-
Запустите процесс, который записывается в трубу
$ foo -o mypipe
Ответ 5
Я использую /dev/tty как имя выходного файла, эквивалентное использованию /dev/nul/, когда вы вообще ничего не хотите выводить. Тогда | и все готово.