Предположим, что существует программа, которая принимает два аргумента; входной файл и выходной файл.
Что делать, если я не хочу сохранять этот выходной файл на диск, а скорее передавать его прямо на stdin
другой программы. Есть ли способ достичь этого?
Множество команд, с которыми я сталкиваюсь в Linux, предоставляют возможность передать '-' в качестве аргумента выходного файла, который делает то, что я указал выше. Это потому, что передача stdin
программы в качестве аргумента невозможна? Если да, то как мы это сделаем?
Пример того, как я мог бы использовать это:
pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" stdin(echo)
Оболочка, которую я использую, – bash.
Если программа поддерживает запись в любой файловый дескриптор, даже если он не может искать, вы можете использовать /dev/stdout
в качестве выходного файла. Это символическая ссылка на /proc/self/fd/1
в моей системе. Файловый дескриптор 1 является стандартным.
На странице руководства pdftotext
:
Если текстовым файлом является «- », текст отправляется на стандартный вывод.
Таким образом, в этом случае все, что вам нужно, это:
pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" -
Или если вы хотите передать это STDIN другой программе:
pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" - | another_prog
Использование -
как замена имени файла – это соглашение, за которым следуют многие утилиты (включая pdftotext), когда мы хотим вводить STDIN или выводить на STDOUT. Однако не все утилиты следуют этому соглашению. В этом случае идиоматическим способом сделать это в bash является использование подстановки процесса :
my_utility "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" >( cat )
Здесь >( )
ведет себя в основном как файл, переданный в my_utility
, но вместо того, чтобы быть реальным файлом, поток передается в stdin содержащегося процесса, то есть cat. Поэтому здесь текст должен в конечном итоге выводиться по мере необходимости.
Использование cat
почти всегда выставляет на буйках булавки UUOC на таких форумах. Я утверждаю, что если утилита не поддерживает, то это полезное использование cat
, хотя, если есть какие-то способы сделать эту замену процесса без cat
, тогда я все уши ;-).
Однако, если (по заявлению вопроса) конечным пунктом назначения потока является STDIN другой программы, то cat
может быть устранена:
my_utility "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" >( another_prog )
Если ваша оболочка поддерживает их, самым простым способом таких манипуляций будет использование замены процесса : <(…)
и >(…)
. Это работает в bash, zsh и ksh и, возможно, в других оболочках. Например:
$ sort <(printf "b\nc\na\n") a b c $ ls foo $ cp <(find . -name foo) bar $ ls bar foo
Однако это не поможет в примере, который вы указываете, поскольку pdftotext
будет сохранять в текстовом файле. Хотя ваш лучший выбор (помимо очевидного использования -
) заключается в использовании /dev/stdout
как было предложено @TiCPU, вы также можете использовать другую функцию оболочки. Конструкция !:N
относится к N-му аргументу предыдущей команды. Поэтому вы можете сделать:
$ pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" out.txt $ cat !:2
cmd tty
tty
возвращает имя терминала, подключенного к stdout
.