Passer un canal à une commande qui attend un nom de fichier

19

Dire que j'ai une commande fooqui prend un argument de nom de fichier: foo myfile.txt. Chose ennuyeuse, foone lit pas depuis l'entrée standard. Au lieu d'un fichier réel, je voudrais lui transmettre le résultat d'une autre commande (en réalité pv, qui cat le fichier et produira un indicateur de progression comme effet secondaire).

Y a-t-il un moyen d'y arriver? Rien dans mon sac de trucs ne semble le faire.

( foodans ce cas, c'est un script PHP qui, je crois, traite le fichier de manière séquentielle).

J'utilise Ubuntu et Bash

EDIT Désolé pour la description du problème légèrement floue, mais voici la réponse qui fait ce que je veux:

pv longfile.txt | foo /dev/stdin

Très évident maintenant que je le vois.

Steve Bennett
la source
Vous recherchez un monoplace?
Dave Forgac
Êtes-vous sûr que foo n'accepte pas un argument "-" pour le faire lire depuis stdin?
rackandboneman
Malheureusement, dans ce cas - c'est un script php.
Steve Bennett
Oui en fait. .
Steve Bennett

Réponses:

19

Si je comprends bien ce que vous voulez faire correctement, vous pouvez le faire avec la fonction de substitution de commandes de bash:

foo <(somecommand | pv)

Cela fait quelque chose de similaire à ce que les mkfiforéponses basées suggèrent, sauf que bash gère les détails pour vous (et il finit par passer quelque chose comme / dev / fd / 63 à la commande, plutôt qu'un canal nommé normal). Vous pouvez également le faire encore plus directement comme ceci:

somecommand | pv | foo /dev/stdin
Gordon Davisson
la source
1
oh, chouette! C'est pv inputfile.txt | foo /dev/stdinexactement ce que je cherchais, mais je n'y ai pas pensé.
Steve Bennett
Woot! / dev / stdin
sage
<(.)travaillé pour moi. Cette syntaxe est-elle documentée dans le manuel de Bash? Je comprends (.)que la substitution de commandes est documentée, mais je n'ai pas vu sa combinaison avec <expliquée.
flow2k
@ flow2k Cela s'appelle "substitution de processus" - voir la section 3.5.6 du manuel bash .
Gordon Davisson
Je l'ai. Vous avez raison - il mentionne qu'il utilise des tuyaux nommés / mkfifo.
flow2k
2
ARRAY=(`pv whatever`); for FILE in $ARRAY; do foo $FILE; done
Hyppy
la source
1

Essayez d'utiliser mkfifo.

mkfifo file_read_by_foo; pv ... > file_read_by_foo 

Dans un autre shell, exécutez foo file_read_by_foo

devenir plus sage
la source
0

xargs semble bien fonctionner pour cela:

echo longfile.txt | xargs pv
MadHatter soutient Monica
la source
Cela fait quelque chose de différent: courir pvplusieurs fois, chacun avec une ou plusieurs lignes tirées de longfile.txt. Pas du tout ce que je recherche ici.
Steve Bennett