[gelöst] BASH: Wie stdout in Variable lenken?

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
crischi
Beiträge: 93
Registriert: 08.02.2010 20:44:10
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Chemnitz

[gelöst] BASH: Wie stdout in Variable lenken?

Beitrag von crischi » 06.03.2010 22:31:04

Hallo,

Ich habe ein Problem bezgl. des Bash-Skriting.
Ich suche eine einfache (oder überhaupt eine) Möglichkeit, einen Stream in eine Variable zu kopieren. Sprich, ich will die Ausgabe eines Kommandos in eine Variable lenken. Ich bin noch neu in der Bash-Programmierung (Ahnungsloser) und habe gedacht, dass es in etwa so funktionieren könnte:

Code: Alles auswählen

prog-mit-stdout-ausgabe | read var
echo $var
Problem ist nur, die Variable bleibt leer. Was mache ich falsch, bin ich auf dem Holzweg?

lg,
crischi.
Zuletzt geändert von crischi am 07.03.2010 18:11:58, insgesamt 1-mal geändert.
"The optimist proclaims that we live in the best of all possible worlds, and the pessimist fears this is true", James Branch Cabell

michaels
Beiträge: 1164
Registriert: 29.03.2009 18:12:25

Re: BASH: Wie stdout in Variable lenken?

Beitrag von michaels » 06.03.2010 22:36:21

Hi,

sollte es nicht einfach:

Code: Alles auswählen

deineVar = `/bin/deinProgMitAusgabe`
sein!?

Gruß

Benutzeravatar
crischi
Beiträge: 93
Registriert: 08.02.2010 20:44:10
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Chemnitz

Re: BASH: Wie stdout in Variable lenken?

Beitrag von crischi » 06.03.2010 22:44:59

Ja, genau, danke, funktioniert!!!
Trotzdem, wieso geht es mit read eigentlich nicht?

lg,
crischi.
"The optimist proclaims that we live in the best of all possible worlds, and the pessimist fears this is true", James Branch Cabell

Benutzeravatar
Meillo
Moderator
Beiträge: 9254
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: BASH: Wie stdout in Variable lenken?

Beitrag von Meillo » 07.03.2010 11:00:36

michaels hat geschrieben: sollte es nicht einfach:

Code: Alles auswählen

deineVar = `/bin/deinProgMitAusgabe`
sein!?
Aber die Leerzeichen um das Gleichheitszeichen müssen weg.

crischi hat geschrieben:

Code: Alles auswählen

prog-mit-stdout-ausgabe | read var
echo $var
Problem ist nur, die Variable bleibt leer. Was mache ich falsch, bin ich auf dem Holzweg?
So pauschal kann man das nicht sagen. In der ksh beispielsweise funktioniert das so. Du verwendest vermutlich die bash; deren Manpage sagt:
Each command in a pipeline is executed as a separate process (i.e., in a subshell).
Dein Aufruf ist also gleichbedeutend mit:

Code: Alles auswählen

( date ) | ( read var )
var ist damit nur in der Subshell existent und kann nicht in die Elternshell übernommen werden.

Die ksh führt das *letzte* Kommando einer Pipeline in der Elternshell aus, falls möglich, um eben solche read-Konstrukte zu ermöglichen. Wenn komplexere Konstrukte (while, for) im Spiel sind, ist das meist nicht möglich. Erwähnt sei, dass dieses Verhalten der ksh in ihrer Geschichte gewechselt hat.
Use ed once in a while!

Benutzeravatar
crischi
Beiträge: 93
Registriert: 08.02.2010 20:44:10
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Chemnitz

Re: BASH: Wie stdout in Variable lenken?

Beitrag von crischi » 07.03.2010 17:56:10

Ich habe gerade noch ein bisschen was über die Shell-Programmierung gelesen. Das Prinzip der Subshells ist mir jetzt nun klarer geworden. Ich habe das Problem aber mit der Zuweisung gelöst var=`command`.
Trotzdem habe ich spasseshalber mal den read-Ansatz verfolgt. Prinzipiell bleiben nur 2 Möglichkeiten, 1) (Buch) man schreibt aus der Subshell in eine Datei und liest sie später in der Eltern-Shell wieder oder 2) (mein Ansatz) man bleibt einfach in der Subshell, denn alle schon vorher beschriebenen Variablen sind ja für die Kinder sichtbar:

Code: Alles auswählen

#!/bin/bash
#set -x
parent=3
echo "Dieser Text" |( read child
echo $child
echo $parent )
lg,
crischi.

PS: Dieses Buch erklärt eigentlich für Afänger die Shell-Programmierung recht anschaulich mit vielen Beispielen und gut durchdacht:
http://www.schatenseite.de/uploads/media/shell.pdf
"The optimist proclaims that we live in the best of all possible worlds, and the pessimist fears this is true", James Branch Cabell

Benutzeravatar
Meillo
Moderator
Beiträge: 9254
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: BASH: Wie stdout in Variable lenken?

Beitrag von Meillo » 07.03.2010 18:38:25

crischi hat geschrieben:Ich habe gerade noch ein bisschen was über die Shell-Programmierung gelesen. Das Prinzip der Subshells ist mir jetzt nun klarer geworden. Ich habe das Problem aber mit der Zuweisung gelöst var=`command`.
Trotzdem habe ich spasseshalber mal den read-Ansatz verfolgt.
Das gefällt mir.
Prinzipiell bleiben nur 2 Möglichkeiten, 1) (Buch) man schreibt aus der Subshell in eine Datei und liest sie später in der Eltern-Shell wieder oder 2) (mein Ansatz) man bleibt einfach in der Subshell, denn alle schon vorher beschriebenen Variablen sind ja für die Kinder sichtbar:

Code: Alles auswählen

#!/bin/bash
#set -x
parent=3
echo "Dieser Text" |( read child
echo $child
echo $parent )
Oft will man halt die Variable nicht nur wieder ausgeben, sondern damit andere Teile des Scriptes beeinflussen; im Beispiel von Schleifen möglicherweise auch weiter oben liegende.

PS: Dieses Buch erklärt eigentlich für Afänger die Shell-Programmierung recht anschaulich mit vielen Beispielen und gut durchdacht:
http://www.schatenseite.de/uploads/media/shell.pdf
Ich habe es auch mal gelesen und finde es ganz nett. Am besten hat mir gefallen, dass es sehr kompakt viele Tools vorstellt.

Am meisten über Shellprogrammierung habe ich aber nicht aus Büchern über Shell*programmierung* gelernt, sondern aus Büchern über *Shells*. Das O'Reilly-Buch über die Bash ist sehr gut. Das Buch von Bolsky und Korn über die Korn-Shell finde ich noch besser. Bei diesen Büchern lernt man wirklich verstehen.
Use ed once in a while!

Benutzeravatar
crischi
Beiträge: 93
Registriert: 08.02.2010 20:44:10
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Chemnitz

Re: [gelöst] BASH: Wie stdout in Variable lenken?

Beitrag von crischi » 07.03.2010 20:56:54

Ja, richtig, das hatte ich nicht bedacht:
Bei Schleifen hat man natürlich ein Problem, wenn der Kopf nach wie vor in der Eltern-Shell ist.

Aber alles in allem ist das eine spannende Sache, die Shell-Programmierung. Man kann ziemlich gut altägliche Probleme lösen, ohne gleich den C-Compiler anschmeißen zu müssen und hat gegenüber Perl (das mir einigermaßen geläufig ist) den Vorteil, nicht erst nach den Aufrufen stöbern zu müssen. Wobei ich sagen muss, dass mir auch Perl recht gut gefällt, ich habe sogar eine Portierung für's iPhone gefunden. Perl hat natürlich gegenüber einem Shell-Skript einen eklatanten Geschwindigkeisvorteil, da ja schon beim Start des Skripts selbiges in Maschinencode übersetzt wird.

lg
crischi.
"The optimist proclaims that we live in the best of all possible worlds, and the pessimist fears this is true", James Branch Cabell

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Re: BASH: Wie stdout in Variable lenken?

Beitrag von gms » 07.03.2010 21:11:32

crischi hat geschrieben: Trotzdem habe ich spasseshalber mal den read-Ansatz verfolgt. Prinzipiell bleiben nur 2 Möglichkeiten, 1) (Buch) man schreibt aus der Subshell in eine Datei und liest sie später in der Eltern-Shell wieder oder 2) (mein Ansatz) man bleibt einfach in der Subshell, denn alle schon vorher beschriebenen Variablen sind ja für die Kinder sichtbar
oder
3) beim "read-Ansatz" muß man nicht umbedingt eine Pipe verwenden, daher kann man auch die Subshell umgehen:

Code: Alles auswählen

gms@gms1 ~ $ read var <<EOF
> $(date)
> EOF
gms@gms1 ~ $ echo $var
Son Mär 7 21:12:29 CET 2010
Gruß
gms

Benutzeravatar
Meillo
Moderator
Beiträge: 9254
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: BASH: Wie stdout in Variable lenken?

Beitrag von Meillo » 07.03.2010 21:49:55

gms hat geschrieben: oder
3) beim "read-Ansatz" muß man nicht umbedingt eine Pipe verwenden, daher kann man auch die Subshell umgehen:

Code: Alles auswählen

gms@gms1 ~ $ read var <<EOF
> $(date)
> EOF
gms@gms1 ~ $ echo $var
Son Mär 7 21:12:29 CET 2010
Wobei das ja nichts anderes ist als

Code: Alles auswählen

read var "$(date)"
EDIT: Doch, es gibt sehr wohl einen Unterschied, und der ist gravierend. Die vorige Zeile ist nämlich Quatsch. :roll:

Da finde ich

Code: Alles auswählen

var="$(date)"
eleganter.
Zuletzt geändert von Meillo am 07.03.2010 22:38:32, insgesamt 1-mal geändert.
Grund: Here-Docs sind eben *nicht* das Gleiche wie Text in Double-Quotes. (Memo an mich: Gehirn einschalten.)
Use ed once in a while!

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Re: BASH: Wie stdout in Variable lenken?

Beitrag von gms » 07.03.2010 22:03:55

Meillo hat geschrieben:Da finde ich

Code: Alles auswählen

var="$(date)"
eleganter.
ich übrigens auch, darum gings aber nicht, den hier haben wohl ALLE vorgestellten "read-Ansätze" verloren :wink:

Interessanter wird mein Beispiel bei solchen Konstrukten:

Code: Alles auswählen

while read var1 var2; do
# berechne var3
var3=..
done <<EOF
$(command)
EOF
# und verwende var3 außerhalb
echo $var3
hier würde man sich mit eine Pipe schwerer tun.

Gruß
gms

btw
Meillo hat geschrieben: Wobei das ja nichts anderes ist als

Code: Alles auswählen

read var "$(date)"
das geht so nicht
Zuletzt geändert von gms am 07.03.2010 22:35:12, insgesamt 1-mal geändert.

Benutzeravatar
Meillo
Moderator
Beiträge: 9254
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: BASH: Wie stdout in Variable lenken?

Beitrag von Meillo » 07.03.2010 22:34:53

Ich nehme meine Anmerkung von vorhin zurück ... ich hatte einen fetten Denkfehler. :roll:
Use ed once in a while!

Antworten