[linux-l] SuSE 9.1: wc funktioniert nicht mehr mit standard input

Jan-Benedict Glaw jbglaw at lug-owl.de
Fr Sep 17 21:50:55 CEST 2004


On Fri, 2004-09-17 13:44:27 +0200, Clemens <pinguinpflege at onlinehome.de>
wrote in message <200409171344.27996.pinguinpflege at onlinehome.de>:
> Am Donnerstag, 16. September 2004 22:03 schrieb Jan-Benedict Glaw:
> 
> > Das schickt sowohl stdout als auch stderr nach "wc":
> > # smbclient .... 2>&1 | wc -l
> >
> > Das schickt alles, was nach stderr geschickt wird, nach "wc".
> > stdout-Ausgaben werden nach /dev/null geerdet:
> > # smbclient .... 2>&1 > /dev/null | wc -l
> >
> > Ach ja, das muß ein durchschnittlicher Windows-User nicht verstehen:-)
> > Ich erklär' das aber auch gern' noch...
> 
>  Also ich würde mich freuen wenn Du Lust hättest das zu erklären.

Also... Wenn ein "normales" Programm von der Shell gestartet wird, dann
hat es drei sog. "file descriptors" geöffnet. Mit so einem Henkel kann
man in eine Datei schreiben, daraus lesen, mit anderen Prozessen
kommunizieren etc. Diese drei "fds" sind durchnummeriert:

	0	nennt man "stdin". Von diesem fd kann der Prozess lesen,
		dann bekommt er die Eingaben, die von der Tastatur
		kommen oder via einer Pipe hineingeschoben werden:

			cat /eine/datei | programm

		"programm" kann dann von fd 0 die Datei lesen, denn
		deren Inhalt pumpt "cat" da hinein.


	1	nennt man "stdout". Wenn ein Programm einfach so
		Ausgaben macht, dann gehen die zu diesem fd. "cat" aus
		dem obrigen Beispiel schickt den Datei-Inhalt an seinen
		fd 1, der von der aufrufenden shell mit dem fd 0 von
		"programm" verbunden ist.


	2	nennt man "stderr". Hierher schicken Programme ihre
		Fehlermeldungen. Das wird so gemacht, damit man
		"normale" Ausgaben von den Fehlern trennen kann.

Das Pipe-Zeichen (|) führt in einer Shell also dazu, daß fd 1 des linken
Programmes mit fd 0 des rechten Programmes verbunden wird. Dieser
einfache Mechanismus alleine ist schon _verdammt_ mächtig.

Ähnlich ist das mit dem Größer-Als-Zeichen (>). Es verbindet den fd 1
(also stdout) mit normalerweise einer Datei, deren Namen anzugeben ist.

Vor Das Größer-Als-Zeichen kann man grundsätzlich noch die fd-Nummer
angeben. (Gibt man nichts an, wird fd 1 angenommen). Dieses nutzt man,
um z.B. alleinig die Fehlermeldungen (die ja an stderr, aka fd 2, gehen)
wegzuschmeißen:

	./einprogramm 2>/dev/null

In dem initial angegebenen Beispiel wollen wir die normalen Ausgaben
wegwerfen und die Fehler-Ausgaben weiterverarbeiten. Dröseln wir das
auf, schrittweise:

	# smbclient .... 2>&1

"2>" irgendwas kennen wir schon: Fehlermeldungen (die an stderr, fd 2,
geschickt werden) sollen umgeleitet werden. Aber hier ist kein
Dateiname angegeben. Stattdessen "&1". Dieses Ampersand-Zeichen bewirkt,
daß stderr nun nicht mehr an das Terminal geschickt wird (da laufen
Fehlermeldungen ja gewöhnlich auf:-) ,  sondern an eine _Kopie_ des
Zieles, an das die Daten von fd 1 gehen würden. Technisch gesehen wird
die libc-Funktion dub2() aufgerufen. Also wird das alte Ziel von fd 2
zugemacht und fortan zeigt fd 2 dahin, wo bisher fd 1 ebenfalls
hingezeigt hat.


	# smbclient .... 2>&1 > /dev/null

Jetzt kommt der nächste Schritt: Alles, was an fd 1 (man erinnere sich:
wenn bei einer Umleitung keine fd-Nummer angegeben wird, dann wird eins
genommen), geht nun (auf nimmer Wiedersehen) nach /dev/null. Davon
unangetastet zeigt fd 2 (was ja eine Kopie von fd 1 ist) immernoch ganz
brav in Richtung einfache Ausgabe.

Das ist der Teil, der einem Nicht-Programmierer so verdammt schwer zu
veranschaulichen ist :-(

Und hier ist dann der Voll-Ausbau:

	# smbclient .... 2>&1 > /dev/null | wc -l

Nachdem wir uns sozusagen eine Sicherungs-Kopie von stdout angelegt
haben, schmeißen wir die eigentlichen stdout-Ausgaben in die Tonne
(/dev/null). Danach bedienen wir uns der Kopie von stdout (da kommen
jetzt ja die Fehler-Ausgaben heraus), um sie, wie eh und je, in "wc"
hineinzuschieben.

Trickserei verstanden?

MfG, JBG

-- 
Jan-Benedict Glaw       jbglaw at lug-owl.de    . +49-172-7608481             _ O _
"Eine Freie Meinung in  einem Freien Kopf    | Gegen Zensur | Gegen Krieg  _ _ O
 fuer einen Freien Staat voll Freier Bürger" | im Internet! |   im Irak!   O O O
ret = do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA));
-------------- nächster Teil --------------
Ein Dateianhang mit Binärdaten wurde abgetrennt...
Dateiname   : signature.asc
Dateityp    : application/pgp-signature
Dateigröße  : 189 bytes
Beschreibung: Digital signature
URL         : <https://mlists.in-berlin.de/pipermail/linux-l-mlists.in-berlin.de/attachments/20040917/0e8d559a/attachment.sig>


Mehr Informationen über die Mailingliste linux-l