Angenommen, ein Programm besteht aus zwei Argumenten. Eingabedatei und Ausgabedatei.
Was ist, wenn ich diese Ausgabedatei nicht auf der Festplatte speichern, sondern direkt an ein stdin
anderes Programm übergeben möchte? Gibt es einen Weg, dies zu erreichen?
Viele Befehle, auf die ich unter Linux stoße, bieten die Option, '-' als Ausgabedatei-Argument zu übergeben, was genau das tut, was ich oben angegeben habe. Liegt das daran, dass die Weitergabe stdin
eines Programms als Argument nicht möglich ist? Wenn ja, wie machen wir das?
Ein Beispiel für die Verwendung dieses Bilds ist:
pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" stdin(echo)
Die Shell, die ich benutze, ist bash.
bash
io-redirection
arguments
Dziugas
quelle
quelle
cat <file | cmd /dev/fd/0
funktioniert bei den meisten einheiten.cat < README.txt | cp /dev/fd/0
. Es hießcp: missing destination file operand after ‘/dev/fd/0’ Try 'cp --help' for more information.
program input-file /dev/stdout | another-program
? Beachten Sie auch, dassecho
nichts von stdin liest.cp
Datei nirgendwo.echo 1 2 3| cp /dev/fd/0 /dev/tty
wird gedruckt1 2 3
. Und übrigens/dev/fd/[num]
ist eher zu arbeiten als/dev/std(in|out|err)
in den meisten Fällen. Unter Portabilität von Dateideskriptor-Links erfahren Sie, was Sie wo erwarten können.Antworten:
Wenn das Programm das Schreiben in einen beliebigen Dateideskriptor unterstützt, auch wenn es nicht suchen kann, können Sie ihn
/dev/stdout
als Ausgabedatei verwenden. Dies ist ein Symlink zu/proc/self/fd/1
meinem System. Dateideskriptor 1 ist stdout.quelle
pdftotext
Wie viele (aber nicht alle) andere Dienstprogramme auch, die dies unterstützen-
(was sogar auf Systemen funktionieren würde, die / dev / stdout nicht unterstützen, oder auf denen / dev / stdout nicht wie erwartet funktioniert, wie unter Linux, wo stdout nicht funktioniert ein Rohr).pdftotext file.pdf - | wc -c
Von der
pdftotext
Manpage:In diesem Fall brauchen Sie also nur:
Oder wenn Sie dies an STDIN eines anderen Programms leiten möchten:
Die Verwendung
-
als Ersatz für einen Dateinamen ist eine Konvention, der viele Dienstprogramme folgen (einschließlich pdftotext), wenn wir eine Eingabe von STDIN oder eine Ausgabe an STDOUT wünschen. Es folgen jedoch nicht alle Dienstprogramme dieser Konvention. In diesem Fall besteht der idiomatische Weg, dies in bash zu tun, in der Verwendung einer Prozesssubstitution :Hier
>( )
verhält sich das weitgehend wie eine Datei, an die übergeben wirdmy_utility
, aber anstatt eine echte Datei zu sein, wird der Stream in den Standard des enthaltenen Prozesses geleitet, dh cat. Hier sollte der Text also letztendlich nach Bedarf ausgegeben werden.Die Verwendung von UUOC löst
cat
in solchen Foren fast immer Alarmglocken aus . Ich behaupte, dass, wenn das Dienstprogramm nicht unterstützt-
, dies eine nützliche Verwendung voncat
ist. Wenn es jedoch Möglichkeiten gibt, diese Prozessersetzung ohne das zu tuncat
, dann bin ich ganz Ohr ;-).Wenn jedoch (wie in der Frage angegeben) das endgültige Ziel des Streams STDIN eines anderen Programms ist,
cat
kann Folgendes beseitigt werden:quelle
prog2
auf stdout geschrieben wird, ist dies besser als , da das Formular auf das Ausfüllen wartet (dh bevor die Shell die nächste Eingabeaufforderung ausgibt oder zum nächsten Befehl übergeht (z. B. nach oder )), während die -less Formular wartet nur auf das Ausfüllen . Nach dem Formular befindet sich auch der Beendigungsstatus von , wohingegen in dem anderen der Beendigungsstatus von ist . (Sie zahlen Ihr Geld und Sie treffen Ihre Wahl.)prog1 input_file
>( cat ) |
prog2
prog1 input_file
>(
prog2
)
cat
prog2
;
&&
cat
prog1
cat
$?
prog2
$?
prog1
Wenn Ihre Shell sie unterstützt, ist die einfachste Möglichkeit, solche Manipulationen durchzuführen, die Verwendung der Prozessersetzung :
<(…)
und>(…)
. Dies funktioniert in bash, zsh und ksh und möglicherweise auch in anderen Shells. Beispielsweise:Dies ist jedoch in dem von Ihnen angegebenen Beispiel nicht hilfreich, da
pdftotext
es in einer Textdatei gespeichert wird. Während Ihre beste Wahl (abgesehen von der offensichtlichen Verwendung-
)/dev/stdout
die von @TiCPU vorgeschlagene Verwendung ist, können Sie auch eine andere Shell-Funktion verwenden. Das Konstrukt!:N
verweist auf das N-te Argument des vorherigen Befehls. Daher können Sie Folgendes tun:quelle
cat <()
dies in einigen Situationen nützlich sein kann, aber in diesem Szenario funktioniert es überhaupt nicht. Das Problem (das von OP sehr schlecht beschrieben wird, muss ich zugeben) besteht darin, dasspdftotext
zwei Argumente erforderlich sind : Eingabedatei und Ausgabedatei . Wenn das zweite Argument fehlt, wird nichts erzeugt, undcat <(pdftotext "file.pdf")
es wird auch nichts zurückgegeben. Man kann daspdftotext
Kommando betrügen, indem man>(cat)
als zweites Argument wie Digitales Trauma antwortet, aber hiercat <()
ist es sinnlos. Für denpdftotext
Fall, dass es am besten ist, nur den-
Namen der Ausgabedatei zu verwenden.>( )
leitet den Stream effektiv an den Prozess weiter, der sich im Inneren befindet. Wir benötigen also eincat
Here, um diesen Stream auszugeben. Normalerweise sollten wir in der Lage sein, so etwas zu tunpdftotext input.pdf -
, aber anscheinendpdftotext
unterstützt es nicht den-
Parameter, direkt auf stdout anstatt auf eine Datei auszugeben - probieren Sie es aus.>(grep something)
, um nützlicher zu sein. BTW, meinepdftotext 3.04
do Unterstützung-
als Ausgabedatei, so dass ich ein wenig bin überrascht von der ganzen Diskussion.pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf"
, bei der die Ausgabe in eine Datei mit dem Namen gestellt wirdC BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.txt
, aber der Text wird nicht an STDOUT ausgegeben, um an ein anderes Programm weitergeleitet zu werden.tty
Gibt den Namen des Terminals zurück, mit dem verbunden iststdout
.quelle
tty
dem Namen des Terminals suchen und diese Datei dann beispielsweise als Ausgabe verwendenpdftotext file.pdf /dev/pts/2
. In diesem Fall stimme ich zu.prog1 input_file
$(tty)
prog1 input_file
/dev/tty
prog1