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 ?
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.
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
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.
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`"
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
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