Como a entrada padrão de um programa pode ser passada como um argumento para outro?

17

Digamos que um programa exista, o que leva dois argumentos; arquivo de entrada e arquivo de saída.

E se eu não quiser salvar este arquivo de saída no disco, mas passá-lo diretamente para stdin de outro programa. Existe uma maneira de conseguir isso?

Muitos comandos que eu encontro no Linux fornecem uma opção para passar '-' como o argumento do arquivo de saída, que faz o que eu especifiquei acima. Isso ocorre porque passar o stdin de um programa como um argumento não é possível? Se for, como fazemos isso?

Um exemplo de como eu imagino usando isso é:

pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" stdin(echo)

O shell que estou usando é bash.

    
por Dziugas 20.07.2015 / 04:51

4 respostas

13

Se o programa suportar a gravação em qualquer descritor de arquivo, mesmo que não seja possível, você poderá usar /dev/stdout como o arquivo de saída. Este é um link simbólico para /proc/self/fd/1 no meu sistema. O descritor de arquivo 1 é stdout.

    
por 20.07.2015 / 05:27
11

Na página pdftotext man:

If text-file is ´-', the text is sent to stdout.

Então, neste caso, tudo que você precisa é:

pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" -

Ou se você quiser canalizar isso para STDIN de outro programa:

pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" - | another_prog

Usar - como substituto para um nome de arquivo é uma convenção que muitos utilitários seguem (incluindo pdftotext) quando queremos entrada de STDIN ou saída para STDOUT. No entanto, nem todos os utilitários seguem essa convenção. Nesse caso, a maneira idiomática de fazer isso no bash é usar uma substituição de processo :

my_utility "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" >( cat )

Aqui, o >( ) se comporta em grande parte como um arquivo passado para my_utility , mas em vez de ser um arquivo real, o fluxo é canalizado para o stdin do processo contido, ou seja, cat. Então, aqui, o texto deve finalmente sair conforme necessário.

O uso de cat quase sempre ativa Sinos de alarme do UUOC em fóruns como esse. Eu afirmo que se o utilitário não suportar - , então este é um uso útil de cat , embora se houver alguma maneira de fazer essa substituição de processo sem o cat , então eu sou todo ouvidos ;-) .

No entanto, se (como a pergunta indica) o destino final do fluxo for STDIN de outro programa, então o cat pode ser eliminado:

my_utility "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" >( another_prog )
    
por 20.07.2015 / 07:06
4

Se o seu shell os suporta, a maneira mais simples de fazer tais manipulações seria usar substituição de processo : <(…) e >(…) . Isso funciona em bash, zsh e ksh e possivelmente em outras shells. Por exemplo:

$ sort <(printf "b\nc\na\n")
a
b
c
$ ls
foo
$ cp <(find . -name foo) bar
$ ls
bar  foo

No entanto, isso não ajudará no exemplo que você declarar, pois pdftotext será salvo em um arquivo de texto. Embora sua melhor escolha (além da óbvia de usar - ) seja usar /dev/stdout como sugerido por @TiCPU, você também pode usar outro recurso de shell. A construção !:N refere-se ao enésimo argumento do comando anterior. Portanto, você poderia fazer:

$ pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf"  out.txt
$ cat !:2
    
por 20.07.2015 / 12:02
-2
cmd tty

tty retorna o nome do terminal conectado a stdout .

    
por 20.07.2015 / 16:15