Wie leitet man die Befehlsausgabe an andere Befehle weiter?

Beispiel:

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

ls | grep 'foo', andererseits funktioniert es wie erwartet (druckt Dateien mit 'foo' in ihrem 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 ?

 102
Author: Mihai Rotaru, 2010-09-16

5 answers

Es wird zwischen Befehlszeilenargumenten und Standardeingabe unterschieden. Eine Pipe verbindet den Standardausgang eines Prozesses mit dem Standardeingang eines anderen Prozesses. Also

ls | echo

Verbindet den Standardausgang von ls mit dem Standardeingang von echo. Gut richtig? Nun, echo ignoriert Standardeingabe und wird seine Befehlszeilenargumente - die in diesem Fall keine sind - sein eigenes stdout ausgeben. Die Ausgabe: gar nichts.

In diesem Fall gibt es einige Lösungen. Eine ist, einen Befehl zu verwenden, der liest stdin und Dumps zu stdout, wie katze.

ls | cat

Wird "funktionieren", je nachdem, was Ihre Definition von Arbeit ist.

Aber was ist mit dem allgemeinen Fall? Was Sie wirklich wollen, ist, stdout eines Befehls in Befehlszeilenargs eines anderen zu konvertieren. Wie andere gesagt haben, ist xargs in diesem Fall das kanonische Hilfstool, das seine Befehlszeilenargumente für einen Befehl aus seiner stdin liest und Befehle zum Ausführen erstellt.

ls | xargs echo

Sie können diesen Code auch mithilfe der Substitution konvertieren befehl $()

echo $(ls)

Würde auch tun, was Sie wollen.

Beide Werkzeuge sind ziemlich Kern Shell-Scripting, sollten Sie beide lernen.

Der Vollständigkeit halber, wie Sie in der Frage angeben, ist die andere grundlegende Möglichkeit, stdin in Befehlszeilenargumente zu konvertieren, der eingebaute Befehl read der Shell. Es konvertiert "Wörter" (Wörter wie durch die Variable IFS definiert) in eine temporäre Variable, die Sie bei jeder Befehlsausführung verwenden können.

 143
Author: Rich Homolka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2013-04-03 17:45:30

ls | echo druckt nur eine leere Zeile, weil echo keine Eingabe liest; Der letzte Befehl der Pipeline ist eigentlich echo, der nur eine leere Zeile druckt.

Allgemein:

a | b

Stellt sicher, dass die Ausgabe von a zur Eingabe von b wird. Ich schlage vor, dass Sie den Abschnitt Pipelines von man bash lesen.


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

ls | xargs -L 1 echo
echo `ls`
for i in `ls` ; do echo $i ; done
 20
Author: cYrus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2010-09-16 14:01:39

Wenn Sie echo den Befehl ls möchten, versuchen Sie es mit:

ls | xargs echo

Dies ruft echo mit der Ausgabe von ls auf.

 13
Author: Nathan Fellman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2010-09-16 14:03:04

Warum nicht einfach verwenden:

echo `ls`

Oder viel sicherer:

echo "`ls -lrt`"
 3
Author: Urbwzrd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2011-11-09 12:43:39

Dies kann auf verschiedene Arten erreicht werden, z. B. . |, STDERR 2>, xargs oder mit dem Befehl . $().

Beispiel für die Verwendung von xargs:

ls | xargs echo
 -1
Author: Benny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2021-01-08 07:17:06