Übergeben Sie eine Pipe an einen Befehl, der einen Dateinamen erwartet


19

Sagen , dass ich einen Befehl haben , foodie einen Dateinamen - Argument: foo myfile.txt. Lies ärgerlicherweise foonicht von der Standardeingabe. Anstelle einer tatsächlichen Datei möchte ich das Ergebnis eines anderen Befehls übergeben (in Wirklichkeit pvwird die Datei kategorisiert und eine Fortschrittsanzeige als Nebeneffekt ausgegeben).

Gibt es eine Möglichkeit, dies zu erreichen? Nichts in meiner Trickkiste scheint es zu tun.

( fooIn diesem Fall handelt es sich um ein PHP-Skript, das die Datei meines Erachtens sequentiell verarbeitet.)

Ich benutze Ubuntu und Bash

BEARBEITEN Entschuldigung für die etwas unklare Problembeschreibung, aber hier ist die Antwort, die das macht, was ich will:

pv longfile.txt | foo /dev/stdin

Sehr offensichtlich jetzt, wo ich es sehe.


Suchen Sie einen Einzeiler?
Dave Forgac

Sind Sie sicher, dass foo kein Argument von "-" akzeptiert, um es von stdin lesen zu lassen?
Rackandboneman

Leider ja, in diesem Fall handelt es sich um ein PHP-Skript.
Steve Bennett

Ja eigentlich. .
Steve Bennett

Antworten:


19

Wenn ich weiß, was Sie richtig machen wollen, können Sie dies mit der Befehlsersetzungsfunktion von bash tun:

foo <(somecommand | pv)

Dies entspricht in etwa dem, was die mkfifo-basierten Antworten vermuten lassen, mit der Ausnahme, dass die Bash die Details für Sie verwaltet (und dem Befehl nicht eine reguläre Named Pipe, sondern etwas wie / dev / fd / 63 übergeben wird). Möglicherweise können Sie dies auch noch direkter tun:

somecommand | pv | foo /dev/stdin

1
Oh, schön! Dies pv inputfile.txt | foo /dev/stdinist genau das, was ich suchte, aber nicht zu denken.
Steve Bennett

Woot! / dev / stdin
sage

<(.)arbeitete für mich. Ist diese Syntax im Bash-Handbuch dokumentiert? Ich verstehe, dass (.)die Befehlsersetzung dokumentiert ist, aber nicht die Kombination mit <erklärt wurde.
flow2k

@ flow2k Es heißt "Prozessersetzung" - siehe Abschnitt 3.5.6 des Bash-Handbuchs .
Gordon Davisson

Ich habs. Sie haben Recht - es wird erwähnt, dass Named Pipes / verwendet werden mkfifo.
flow2k

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


1

Versuchen Sie es mit mkfifo.

mkfifo file_read_by_foo; pv ... > file_read_by_foo 

Führen Sie in einer anderen Shell foo file_read_by_foo aus


0

xargs scheint dafür gut zu funktionieren:

echo longfile.txt | xargs pv

Das macht etwas anderes: pvmehrmals laufen , jeweils mit einer oder mehreren Linien longfile.txt. Überhaupt nicht das, wonach ich hier strebe.
Steve Bennett
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.