![]() |
|
|||||||
| Newsgroup de.comp.os.unix.shell Shell, Skripte und Tools. |
![]() |
|
|
Themen-Optionen | Ansicht |
|
#1
|
|||
|
|||
|
Ich werde alt... sowas funktionierte doch sonst so schön?
#!/bin/bash tmp="hallo welt" ps aux | grep "/dev/" | while read line; do tmp="$tmp $line" # echo "tmp= $tmp" done echo "tmp= $tmp" Ausgabe des Programms ist "tmp= Hallo Welt", wenn man den Kommentar entfernt sieht man aber, dass die Variable "tmp" ordentlich gefüllt war. Hmpf? Bernd -- Visit http://www.nixwill.de and http://www.spammichvoll.de jean.oliver*nixwill.de & bernado.bernhardi*spammichvoll.de |
|
|
||||
|
||||
|
|
|
#2
|
|||
|
|||
|
Bernd Hohmann wrote:
> #!/bin/bash > tmp="hallo welt" > ps aux | grep "/dev/" | while read line; do > tmp="$tmp $line" > # echo "tmp= $tmp" > done > echo "tmp= $tmp" Das hängt von der Shell ab. Manche Shells belegen eine temporäre Variable innerhalb der Loop. Die pdksh z. B. macht das so. Die echte KSH auf Linux macht das - soweit ich weiss - nicht. Offensichtlich verwendet auch die Bash eine temporäre Variable, die bei Beendigung der Loop verschwindet. Dieses Verhalten finde ich etwas lästig. Ich habe aber noch keine zufriedenstellende Lösung dafür gefunden. Meist kann man aber mit einem Würgaround leben. Hier ein paar Beispiele: Wenn z. B. nur der Wert des letzten Durchlaufs interessiert kann man so vorgehen: #!/bin/bash tmp="hallo welt" tmp="$tmp $(ps aux|while read line;do echo "xx $line";done|tail -1)" echo "tmp= $tmp" Wenn es nur darum geht, alle Zeilen aneinanderzuhängen (mit Blanks getrennt) geht das so: #!/bin/bash tmp=$(ps aux|tr '\n' ' ') echo "$tmp" Wenn alle Zeilen hintereinandergehängt werden sollen und der Trenner soll beliebig sein geht das z. B. so: #!/bin/bash tmp=$(ps aux|sed -e 's/$/!DAS IST DER TRENNER!/'|tr -d '\n') echo "$tmp" -- Ernest |
|
#3
|
|||
|
|||
|
Ernest Herder schrieb:
> Offensichtlich verwendet auch die Bash eine temporäre Variable, die bei > Beendigung der Loop verschwindet. > Dieses Verhalten finde ich etwas lästig. > Ich habe aber noch keine zufriedenstellende Lösung dafür gefunden. > Meist kann man aber mit einem Würgaround leben. Das scheint was mit der Pipe zu tun zu haben, die in meinem Muster genutzt wird. Im Netz gibts hinreichend viele Diskussionen darüber, wie man das umgehen kann - keine hat mir sonderlich gefallen was die Lesbarkeit angeht. Darum habe ich jetzt die Keule ausgepackt und schiebe die Zwischenergebnisse in eine temporäre Datei - fertsch. Bernd -- Visit http://www.nixwill.de and http://www.spammichvoll.de jean.oliver*nixwill.de & bernado.bernhardi*spammichvoll.de |
|
#4
|
|||
|
|||
|
Bernd Hohmann schrieb am Donnerstag 05 November 2009 22:40:
> Ernest Herder schrieb: > >> Offensichtlich verwendet auch die Bash eine temporäre Variable, >> die bei Beendigung der Loop verschwindet. >> Dieses Verhalten finde ich etwas lästig. >> Ich habe aber noch keine zufriedenstellende Lösung dafür gefunden. >> Meist kann man aber mit einem Würgaround leben. > > Das scheint was mit der Pipe zu tun zu haben, die in meinem Muster > genutzt wird. Nein: var=foo; for text in bar fubar; do var="${var} ${text}"; done; echo $var foo bar fubar Es liegt an der Pipeline. Das sind drei Prozesse, also naturgemäß getrennte Environments. Die Lösung Deines Problems ist einfach: "tmp= $(ps aux | grep "/dev/" | while read line; do tmp="$tmp $line";done)" CU Hauke -- http://www.hauke-laging.de/ideen/ |
|
#5
|
|||
|
|||
|
Bernd Hohmann <bernd.hohmann.20090228*freihaendler.com>:
> Ich werde alt... sowas funktionierte doch sonst so schön? > > #!/bin/bash > tmp="hallo welt" > ps aux | grep "/dev/" | while read line; do > tmp="$tmp $line" > # echo "tmp= $tmp" > done > echo "tmp= $tmp" > > Ausgabe des Programms ist "tmp= Hallo Welt", wenn man den Kommentar > entfernt sieht man aber, dass die Variable "tmp" ordentlich gefüllt war. > > Hmpf? while...do macht eine Subshell. Nach done ist $tmp dieser Subshell verloren und du hast nur noch das $tmp von oben. man export Juergen -- Juergen P. Meier - "This World is about to be Destroyed!" end If you think technology can solve your problems you don't understand technology and you don't understand your problems. (Bruce Schneier) |
|
#6
|
|||
|
|||
|
Hallo,
Bernd Hohmann <bernd.hohmann.20090228*freihaendler.com> wrote: > Ich werde alt... sowas funktionierte doch sonst so schön? > > #!/bin/bash > tmp="hallo welt" > ps aux | grep "/dev/" | while read line; do > tmp="$tmp $line" > # echo "tmp= $tmp" > done > echo "tmp= $tmp" > > Ausgabe des Programms ist "tmp= Hallo Welt", wenn man den Kommentar > entfernt sieht man aber, dass die Variable "tmp" ordentlich gefüllt war. > Hmpf? Beide Seiten der Pipeline laufen in ihrer eigenen Subshell. Die Subshell fuer die rechte Seite der pipeline, in der du fleissig Variablen setzt, wird nach Beendigung dieser Kommandozeile beendet und deine Aenderungen am Environment sind damit verloren ... Tschuess, Juergen Ilse (juergen*usenet-verwaltung.de) -- Ein Domainname (auch wenn er Teil einer Mailadresse ist) ist nur ein Name, nicht mehr und nicht weniger ... |
|
#7
|
|||
|
|||
|
Hallo, Juergen,
Du meintest am 06.11.09: >> Ich werde alt... sowas funktionierte doch sonst so schön? >> >> #!/bin/bash >> tmp="hallo welt" >> ps aux | grep "/dev/" | while read line; do >> tmp="$tmp $line" >> # echo "tmp= $tmp" >> done >> echo "tmp= $tmp" >> >> Ausgabe des Programms ist "tmp= Hallo Welt", wenn man den Kommentar >> entfernt sieht man aber, dass die Variable "tmp" ordentlich gefüllt >> war. > while...do macht eine Subshell. Nach done ist $tmp dieser Subshell > verloren und du hast nur noch das $tmp von oben. > man export "export" ist interessant zu lesen (allerdings wohl besser "help export"), löst aber das Problem nicht: #! /bin/bash tempo=drei export tempo (echo vorher $tempo tempo=vier echo drinnen $tempo ) echo nachher $tempo # zeigt, dass "tempo" in der Subshell eher als lokale Variable behandelt wird, insbesondere wird der in der Subshell zugewiesene Wert nicht zurückgegeben. Viele Gruesse Helmut "Ubuntu" - an African word, meaning "Slackware is too hard for me". |
|
#8
|
|||
|
|||
|
Juergen P. Meier schrieb am Freitag 06 November 2009 06:57:
> while...do macht eine Subshell. Nein: var=foo; while true; do var=geändert; break; done; echo $var geändert Die Pipeline macht die Subshell. CU Hauke -- http://www.hauke-laging.de/ideen/ |
|
#9
|
|||
|
|||
|
Bernd Hohmann <bernd.hohmann.20090228*freihaendler.com> writes:
Hallo, > #!/bin/bash > tmp="hallo welt" > ps aux | grep "/dev/" | while read line; do > tmp="$tmp $line" > # echo "tmp= $tmp" > done > echo "tmp= $tmp" > > Ausgabe des Programms ist "tmp= Hallo Welt", wenn man den Kommentar > entfernt sieht man aber, dass die Variable "tmp" ordentlich gefüllt > war. Dass deine Schleife in einer Subshell ausgeführt wird, wurde ja bereits erklärt. Ich löse so etwas meistens per "Here-Document": tmp="hallo welt" while read line do tmp="$tmp $line" done <<EOF $(ps aux | grep "/dev/") EOF echo "tmp= $tmp" Gruß Jörg |
|
#10
|
|||
|
|||
|
Joerg Mertens <joerg-mertens*t-online.de> writes:
>Bernd Hohmann <bernd.hohmann.20090228*freihaendler.com> writes: >Dass deine Schleife in einer Subshell ausgeführt wird Und _warum_ ist das so? WO ist der (shell-interne) Zwang begründet, das eine: (irgendwas was in einer Pipe abgeht) | while read VAR do # tu was done anders zu behandeln als: while read VAR do # tu was done < (das selbe wie oben nur paedagogisch schlechter plaziert :-) Warum ueberhalt eine Sub-Shell? fragend, Holger |
|
|
|
|
![]() |
| Themen-Optionen | |
| Ansicht | |
|
|
Ähnliche Themen
|
||||
| Thema | Erstellt von | Forum | Antworten | Letzter Beitrag |
| Anhänge in v4.5 nicht mehr sichtbar | Uli | Newsgroup de.comm.software.mailreader.pegasus | 7 | 11-02-2009 04:08 PM |
| fortlaufende Variable in VBA-Schleife einbinden | Walter Heying | Newsgroup microsoft.public.de.excel | 3 | 06-16-2009 01:15 PM |
| express6: Body nicht mehr sichtbar | Alberto Luca | Newsgroup microsoft.public.de.german.inetexplorer.ie6.outlookexpress | 7 | 07-19-2008 07:15 PM |
| Zeichnung nicht mehr sichtbar: GRUPPE | grote02 | Newsgroups microsoft.public.de.german.visio | 5 | 06-16-2008 05:33 PM |
| Clientregel nach Update von 2002 auf 2003 nicht mehr sichtbar aber aktiv | Wilfried Gintenstorfer | Newsgroup microsoft.public.de.outlook | 3 | 05-27-2008 10:04 AM |