it-swarm.com.de

Wie leite ich die Befehlsausgabe an andere Befehle weiter?

Beispiel:

ls | echo gibt nichts aus (eigentlich eine Leerzeile). Ich würde erwarten, dass es eine Liste von Dateien druckt.

ls | grep 'foo' hingegen funktioniert wie erwartet (druckt Dateien mit 'foo' im Namen).

Was ich in diesen Situationen mache, ist so etwas wie: ls | while read OUT; do echo $OUT; done, aber das ist ziemlich umständlich.

Warum funktioniert Piping mit einigen Befehlen, aber nicht mit anderen? Wie kann ich dieses Problem umgehen?

81
Mihai Rotaru

Es wird zwischen Befehlszeilenargumenten und Standardeingaben unterschieden. Eine Pipe verbindet die Standardausgabe eines Prozesses mit der Standardeingabe eines anderen. So

ls | echo

Verbindet den Standardausgang von ls mit dem Standardeingang von Echo. Gut, oder? Nun, echo ignoriert die Standardeingabe und gibt seine Kommandozeilenargumente - in diesem Fall keine für - seine eigene Standardausgabe aus. Die Ausgabe: gar nichts.

In diesem Fall gibt es einige Lösungen. Eine Möglichkeit besteht darin, einen Befehl zu verwenden, der stdin liest und stdout ausgibt, z. B. cat.

ls | cat

Wird "funktionieren", abhängig von Ihrer Definition der Arbeit.

Aber was ist mit dem allgemeinen Fall? Was Sie wirklich wollen, ist, stdout eines Befehls in Befehlszeilenargumente eines anderen zu konvertieren. Wie andere bereits gesagt haben, ist xargs in diesem Fall das kanonische Hilfsprogramm, das die Befehlszeilenargumente für einen Befehl aus der Standardeingabe liest und die auszuführenden Befehle erstellt.

ls | xargs echo

Sie können dies auch mit dem Ersetzungsbefehl $() umwandeln.

echo $(ls)

Würde auch machen was du willst.

Beide Tools sind ziemlich wichtig für Shell-Skripte. Sie sollten beide lernen.

Der Vollständigkeit halber ist, wie Sie in der Frage angeben, die andere grundlegende Möglichkeit, stdin in Befehlszeilenargumente zu konvertieren, der in die Shell integrierte Befehl read. Es konvertiert "Wörter" (Wörter, wie sie durch die Variable IFS definiert sind) in eine temporäre Variable, die Sie in allen Befehlsläufen verwenden können.

115
Rich Homolka

ls | echo gibt nur eine leere Zeile aus, da echo keine Eingabe liest. Der letzte Befehl der Pipeline ist echo, der nur eine leere Zeile ausgibt.

Allgemein:

a | b

stellt sicher, dass die Ausgabe von a zur Eingabe von b wird. Ich empfehle Ihnen, den Abschnitt Pipelines von man bash zu lesen.


Wenn Sie wirklich ls und echo zusammen verwenden möchten, finden Sie hier einige (ziemlich nutzlose) Beispiele:

ls | xargs -L 1 echo
echo `ls`
for i in `ls` ; do echo $i ; done
18
cYrus

Wenn Sie den Befehl echols ausführen möchten, versuchen Sie Folgendes:

ls | xargs echo

Dies ruft echo mit der Ausgabe von ls auf.

9
Nathan Fellman

Warum nicht einfach benutzen:

echo `ls`

Oder viel sicherer:

echo "`ls -lrt`"
3
Urbwzrd