2016-01-31 4 views
16

Wenn ich das folgende Bash Skript ausführen, würde ich erwarten, dass es Hello drucken. Stattdessen druckt es eine leere Zeile und wird beendet.Piping funktioniert nicht mit Echo-Befehl

echo 'Hello' | echo 

Warum nicht piping Ausgabe echo-echo Arbeit?

+2

Sie scheinen zu erwarten, dass das zweite Echo sich wie "Katze" verhält. –

Antwort

25

echo druckt alle seine Argumente. Es liest nicht von stdin. So die zweite echo alle Argumente (keine) gedruckt und beendet, die Hello auf stdin ignorieren.

Für ein Programm, das seine stdin und druckt liest, die stdout, cat verwenden:

$ echo Hello | cat 
Hello 
+1

oder '$ echo Hallo | xargs echo 'was äquivalent zu echo Hallo | ist xargs' standardmäßig. – daGo

2

Es ist, weil echo (beide builtin und /bin/echo) nichts von stdin lesen.

Verwenden cat statt:

echo 'Hello' | cat 
Hello 

oder ohne Rohre:

cat <<< 'Hello' 
3

Piping nur für Befehle durchgeführt werden können Eingaben von stdin nehmen. Aber Echo nimmt nicht von Standard. Es wird die Eingabe vom Argument nehmen und es ausdrucken. Also wird das nicht funktionieren. Um zu echo können Sie etwas tun wie echo $(echo 'hello')

8

Sie scheinen keine Rohre zu verstehen. In diesem Fall sind sie korrekter als anonyme Pipes bekannt, weil sie keinen Namen haben (es gibt auch benannte Pipes). Anonyme Pipes funktionieren nur zwischen verwandten Prozessen, z. B. Prozessen mit demselben Parent.

Pipes sind Teil des IO-Systems, das aus der C-Laufzeitbibliothek resultiert. Diese Streams sind standardmäßig gepuffert (es gibt eine Ausnahme). Grundsätzlich verbindet eine Pipe nur den Ausgabepuffer von einem Prozess mit dem Eingabepuffer eines anderen.

Die ersten drei Ströme verwendet (Filedeskriptoren genannt) 0 numeriert sind, 1 und 2. Der erste, 0, als Standardeingabe bekannt oder stdin (der Name in C verwendet werden). Standardmäßig ist dies mit der Tastatur verbunden, aber es kann entweder über das Symbol < oder den Programmnamen auf der rechten Seite einer Pipe umgeleitet werden.

Die zweite, 1, ist bekannt als Standard-Ausgabe oder stdout. Standardmäßig ist dies mit dem Terminalbildschirm verbunden, kann jedoch mithilfe des Symbols > oder des Programmnamens auf der linken Seite einer Pipe umgeleitet werden.

So:

echo 'Hello' | echo 

nimmt die Standardausgabe von echo und übergibt sie an die Standardeingabe von echo. Aber echo liest nicht stdin! Also passiert nichts.

Filterprogramme verarbeiten Sie die in der Befehlszeile angegebenen Dateinamen. Wenn keine Dateinamen angegeben sind, lesen sie stdin. Beispiele umfassen cat, grep und sed, aber nichtecho. Zum Beispiel:

echo 'Hello' | cat 

werden 'Hallo', angezeigt werden und die cat ist nutzlos (es oft ist).

echo 'Hello' | cat file1 

wird die Ausgabe von echo ignorieren und nur den Inhalt von Datei1 anzuzeigen. Denken Sie daran, dass stdin nur gelesen wird, wenn kein Dateiname angegeben ist.

Was denken Sie, dass dies angezeigt wird?

echo 'Hello' | cat < file1 file2 

und warum?

schließlich der dritte Strom, 2, genannt Standardfehler oder stderr, und dies ist ungepufferte. Es wird von Pipes ignoriert, da sie nur zwischen stdin und stdout operieren. Sie können jedoch stderr umleiten stdout zu verwenden (siehe man dup2):

myprog 2>&1 | anotherprog 

Die 2>&1 bedeutet "Dateideskriptor 2 an der gleichen Stelle wie fie Descriptor 1 umleiten".

Das oben genannte Verhalten ist normal, jedoch kann ein Programm alles überschreiben, wenn es will. Es könnte beispielsweise aus dem Dateideskriptor 2 lesen. Ich habe viele andere Details weggelassen, einschließlich anderer Formen der Umleitung wie Prozesssubstitution und hier Dokumente.