Passe um canal para um comando que espera um nome de arquivo


19

Digamos que eu tenha um comando fooque leva um argumento filename: foo myfile.txt. Irritantemente, foonão lê da entrada padrão. Em vez de um arquivo real, eu gostaria de passar o resultado de outro comando (na realidade pv, que irá capturar o arquivo e gerar um medidor de progresso como efeito colateral).

Existe uma maneira de fazer isso acontecer? Nada na minha mochila parece fazer isso.

( fooneste caso, é um script PHP que, acredito, processa o arquivo sequencialmente).

Estou usando o Ubuntu e o Bash

EDITAR Desculpe a descrição do problema pouco clara, mas aqui está a resposta que faz o que eu quero:

pv longfile.txt | foo /dev/stdin

Muito óbvio agora que eu vejo.


Você está procurando uma linha?
Dave Forgac

Tem certeza de que foo não aceita um argumento "-" para que seja lido a partir de stdin?
rackandboneman

Infelizmente sim, neste caso - é um script php.
9788 Steve Jobs,

Sim, realmente. .
18712 Steve Bennett

Respostas:


19

Se eu entendo o que você deseja fazer corretamente, você pode fazê-lo com o recurso de substituição de comando do bash:

foo <(somecommand | pv)

Isso faz algo semelhante ao que as mkfiforespostas baseadas sugerem, exceto que o bash lida com os detalhes para você (e acaba passando algo como / dev / fd / 63 para o comando, em vez de um pipe nomeado comum). Você também pode fazer isso de maneira ainda mais direta assim:

somecommand | pv | foo /dev/stdin

11
oh, legal! Era pv inputfile.txt | foo /dev/stdinexatamente isso que eu estava procurando, mas não pensei nisso.
9788 Steve Jobs,

Woot! / dev / stdin
sage

<(.)trabalhou para mim. Essa sintaxe está documentada no manual do Bash? Entendo (.)que a substituição de comandos está documentada, mas não vi sua combinação com <explicada.
flow2k

@ flow2k É chamado de "substituição de processo" - consulte a seção 3.5.6 do manual do bash .
Gordon Davisson

Entendi. Você está certo - ele menciona que usa pipes nomeados / mkfifo.
flow2k 02/02

2
ARRAY=(`pv whatever`); for FILE in $ARRAY; do foo $FILE; done


1

Tente usar o mkfifo.

mkfifo file_read_by_foo; pv ... > file_read_by_foo 

Em outro shell, execute foo file_read_by_foo


0

xargs parece funcionar bem para isso:

echo longfile.txt | xargs pv

Isso faz algo diferente: executando pvvárias vezes, cada uma com uma ou mais linhas desenhadas longfile.txt. Não é o que eu estou procurando aqui.
18712 Steve Bennett
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.