Digamos que exista um programa, que requer dois argumentos; arquivo de entrada e arquivo de saída.
E se eu não desejar salvar esse arquivo de saída em disco, mas passá-lo diretamente para stdin
outro programa. Existe uma maneira de conseguir isso?
Muitos comandos que encontro no Linux oferecem uma opção para passar '-' como o argumento do arquivo de saída, que faz o que eu especifiquei acima. Isso stdin
ocorre porque não é possível passar o programa como argumento? Se for, como fazemos?
Um exemplo de como eu criaria imagens usando isso é:
pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" stdin(echo)
O shell que estou usando é o bash.
bash
io-redirection
arguments
Dziugas
fonte
fonte
cat <file | cmd /dev/fd/0
funciona na maioria das unidades.cat < README.txt | cp /dev/fd/0
. Dissecp: missing destination file operand after ‘/dev/fd/0’ Try 'cp --help' for more information.
program input-file /dev/stdout | another-program
? Observe também queecho
não lê nada do stdin.cp
arquivar em nenhum lugar.echo 1 2 3| cp /dev/fd/0 /dev/tty
irá imprimir1 2 3
. E, a propósito,/dev/fd/[num]
é mais provável que funcione do que/dev/std(in|out|err)
na maioria dos casos. Consulte Portabilidade dos links do descritor de arquivos sobre o que você pode esperar para trabalhar onde.Respostas:
Se o programa suportar a gravação em qualquer descritor de arquivo, mesmo que não possa ser procurado, você poderá usá-lo
/dev/stdout
como arquivo de saída. Este é um link simbólico para o/proc/self/fd/1
meu sistema. O descritor de arquivo 1 é stdout.fonte
pdftotext
como muitos (mas não todos) outros utilitários também suportam-
isso (o que funcionaria mesmo em sistemas que não suportam / dev / stdout, ou onde / dev / stdout não funciona como esperado, como no Linux, onde o stdout não é um cano).pdftotext file.pdf - | wc -c
Na
pdftotext
página do manual:Portanto, neste caso, tudo que você precisa é:
Ou se você quiser canalizar isso para STDIN de outro programa:
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 esta convenção. Nesse caso, a maneira idiomática de fazer isso no bash é usar uma substituição de processo :Aqui, o
>( )
comportamento se comporta basicamente como um arquivo passadomy_utility
, mas, em vez de ser um arquivo real, o fluxo é canalizado para o stdin do processo contido, ou seja, cat. Portanto, aqui, o texto deve ser finalizado conforme necessário.O uso de
cat
quase sempre aciona os alarmes UUOC em fóruns como este. Eu afirmo que, se o utilitário não suportar-
, esse é um uso útilcat
, embora, se houver alguma maneira de fazer essa substituição de processo sem ocat
, então eu sou todo ouvidos ;-).No entanto, se (como a pergunta disser) o destino final do fluxo for STDIN de outro programa, ele
cat
poderá ser eliminado:fonte
prog2
gravar em stdout, é melhor que , porque o formulário aguarda a conclusão (ou seja, antes que o shell emita o próximo prompt ou prossiga para o próximo comando (por exemplo, depois ou )), enquanto o - a menos que o formulário aguarde apenas o preenchimento. Além disso, após o formulário, é o status de saída de , enquanto, no outro, é o status de saída de . (Você paga seu dinheiro e você leva sua escolha.)prog1 input_file
>( cat ) |
prog2
prog1 input_file
>(
prog2
)
cat
prog2
;
&&
cat
prog1
cat
$?
prog2
$?
prog1
Se o seu shell os suportar, a maneira mais simples de fazer essas manipulações seria usar a substituição do processo :
<(…)
e>(…)
. Isso funciona no bash, zsh e ksh e possivelmente em outros shells. Por exemplo:No entanto, isso não ajudará no exemplo que você indicar, pois
pdftotext
será salvo em um arquivo de texto. Embora sua melhor opção (além da óbvia de usar-
) seja a/dev/stdout
sugestão sugerida pelo @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ê pode fazer:fonte
cat <()
possa ser útil em algumas situações, neste cenário, no entanto, não está funcionando. O problema (muito mal descrito pelo OP, devo admitir) é que sãopdftotext
necessários dois argumentos: arquivo de entrada e arquivo de saída . Se o segundo argumento estiver ausente, ele não produzirá nada, portantocat <(pdftotext "file.pdf")
também não retornará nada. Pode-se enganar opdftotext
comando dando>(cat)
como segundo argumento o Digital Trauma respondido, mas nãocat <()
faz sentido aqui. Obviamente,pdftotext
caso seja melhor usar apenas-
como o nome do arquivo de saída.>( )
efetivamente canalizará o fluxo para qualquer processo que esteja dentro - então, na verdade, precisamos de umcat
aqui para produzir esse fluxo. Normalmente, devemos ser capazes de fazer algo assimpdftotext input.pdf -
, mas aparentementepdftotext
não suporta o-
parâmetro de saída diretamente para stdout em vez de um arquivo - tente.>(grep something)
para ser mais útil. BTW, meupdftotext 3.04
Do suporte-
como um arquivo de saída, por isso estou um pouco surpreso com toda a discussão.pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf"
, que coloca a saída em um arquivo chamadoC BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.txt
, mas nenhum texto é enviado para STDOUT para canalizar para outro programa.tty
retorna o nome do terminal conectadostdout
.fonte
tty
o nome do terminal e, em seguida, usar esse arquivo como saída, por exemplopdftotext file.pdf /dev/pts/2
. Nesse caso, eu concordo.prog1 input_file
$(tty)
prog1 input_file
/dev/tty
prog1