Passa una pipe a un comando che prevede un nome file


19

Dire che ho un comando fooche prende un argomento filename: foo myfile.txt. In modo fastidioso, foonon legge dallo standard input. Invece di un file vero e proprio, mi piacerebbe passarlo come risultato di un altro comando (in realtà pv, che cat cat il file e genererà un indicatore di avanzamento come effetto collaterale).

C'è un modo per farlo accadere? Niente nella mia borsa di trucchi sembra farlo.

( fooin questo caso è uno script PHP che credo elabora il file in sequenza).

Sto usando Ubuntu e Bash

EDIT Ci scusiamo per la descrizione del problema leggermente poco chiara, ma ecco la risposta che fa quello che voglio:

pv longfile.txt | foo /dev/stdin

Molto ovvio ora che lo vedo.


Stai cercando un one-liner?
Dave Forgac,

Sei sicuro che foo non accetti un argomento di "-" per farlo leggere da Stdin?
rackandboneman,

Purtroppo sì, in questo caso - è uno script php.
Steve Bennett,

Sì, davvero. .
Steve Bennett,

Risposte:


19

Se capisco cosa vuoi fare correttamente, puoi farlo con la funzione di sostituzione dei comandi di bash:

foo <(somecommand | pv)

Questo fa qualcosa di simile a quello che mkfifosuggeriscono le risposte basate su base, tranne per il fatto che bash gestisce i dettagli per te (e finisce per passare qualcosa come / dev / fd / 63 al comando, piuttosto che una normale pipe chiamata). Potresti anche essere in grado di farlo ancora più direttamente in questo modo:

somecommand | pv | foo /dev/stdin

1
oh, bello! Questo pv inputfile.txt | foo /dev/stdinè esattamente quello che stavo cercando, ma non ci ho pensato.
Steve Bennett,

Woot! / dev / stdin
saggio

<(.)ha funzionato per me. Questa sintassi è documentata nel manuale di Bash? Capisco (.)come la sostituzione dei comandi è documentata, ma non ho visto la sua combinazione con <spiegato.
flow2k

@ flow2k Si chiama "sostituzione del processo" - vedere la sezione 3.5.6 del manuale di bash .
Gordon Davisson il

Fatto. Hai ragione - menziona che usa named pipe / mkfifo.
flow2k

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


1

Prova a usare mkfifo.

mkfifo file_read_by_foo; pv ... > file_read_by_foo 

In un'altra shell, esegui foo file_read_by_foo


0

xargs sembra funzionare bene per questo:

echo longfile.txt | xargs pv

Questo fa qualcosa di diverso: correre pvpiù volte, ognuna con una o più linee tratteggiate longfile.txt. Non è quello che sto cercando qui.
Steve Bennett,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.