Problem mit der Gueltigkeit von Variablen??
Hallo, im u.a. skript wird in der while true; Schleife der Wert für FARBE geändert aber allem Anschein nach gilt dieser nur lokal in der Schleife denn die Ausgabe von osd_cat ist immer grün. Liege ich mit meiner Vermutung richtig? Wenn ja wie kann den Wert aus der Schleife an osd_cat übergeben? Gruß und Dank Michael #!/bin/bash SLEEP_OK=30 SLEEP_ALARM=5 FARBE_OK=darkgreen FARBE_WARNUNG=yellow FARBE_ALARM=red WERT_OK=+30 WERT_WARNUNG=+40 WERT_ALARM=+50 ######################################################### FARBE="$FARBE_OK" # Optimismus ist schliesslich alles SLEEP="$SLEEP_OK" while true ; do # Werte aus /proc lesen eval `sensors | sed -n ' /^MB Temp:/ s/MB Temp: [[:space:]]*\([^°]*\).*/MB_TEMP=\1/p ;/^CPU Temp:/ s/CPU Temp: [[:space:]]*\([^°]*\).*/CPU_TEMP=\1/p ; ' ` if [ "$CPU_TEMP" -gt "$WERT_WARNUNG" -a \ "$CPU_TEMP" -lt "$WERT_ALARM" ] ; then FARBE="$FARBE_WARNUNG"; fi if [ "$CPU_TEMP" -ge "$WERT_ALARM" ]; then FARBE="$FARBE_ALARM"; SLEEP="$SLEEP_ALARM"; fi if [ "$CPU_TEMP" -le "$WERT_OK" ] ; then FARBE="$FARBE_OK"; fi echo MB Temp: $MB_TEMP CPU Temp:$CPU_TEMP; sleep $SLEEP echo $FARBE; done |osd_cat -l 1 -A left -p bottom -f -adobe-helvetica-*-*-*-*-18-*-*-*-*-*-* -c $FARBE -s 5 -S lightgray -o 65 -d 60 -- Encrypted eMail welcome! Get my OpenPGP-Key ID: 0xE9B00731 from: wwwkeys.de.pgp.net
Am Die, den 27.07.2004 um 22:55 Uhr +0200 schrieb Michael Hoeller:
Hallo,
im u.a. skript wird in der while true; Schleife der Wert für FARBE geändert aber allem Anschein nach gilt dieser nur lokal in der Schleife denn die Ausgabe von osd_cat ist immer grün. Liege ich mit meiner Vermutung richtig? Wenn ja wie kann den Wert aus der Schleife an osd_cat übergeben?
[...] Ich hatte mal ein ähnliches Problem. Da habe ich jede Variabel mit 'export VARIABEL=Wert' exportiert. Allerdings ist das jetzt auch schon wieder 'ne Weile her. Sollte aber funktionieren. Gruß Marcus
Marcus Habermehl wrote:
Am Die, den 27.07.2004 um 22:55 Uhr +0200 schrieb Michael Hoeller:
Hallo,
im u.a. skript wird in der while true; Schleife der Wert für FARBE geändert aber allem Anschein nach gilt dieser nur lokal in der Schleife denn die Ausgabe von osd_cat ist immer grün. Liege ich mit meiner Vermutung richtig? Wenn ja wie kann den Wert aus der Schleife an osd_cat übergeben?
[...]
Ich hatte mal ein ähnliches Problem. Da habe ich jede Variabel mit 'export VARIABEL=Wert' exportiert.
Leider ohne Erfolg..., es muss eine Grund geben warum immer der selbe wert angezeigt wird... Michael -- Encrypted eMail welcome! Get my OpenPGP-Key ID: 0xE9B00731 from: wwwkeys.de.pgp.net
Hallo, Am Tue, 27 Jul 2004, Michael Hoeller schrieb:
im u.a. skript wird in der while true; Schleife der Wert für FARBE geändert aber allem Anschein nach gilt dieser nur lokal in der Schleife denn die Ausgabe von osd_cat ist immer grün.>
[..]
while true ; do [..] done |osd_cat [..]
Das Problem ist nicht die Schleife. Sondern die pipe. ==== man bash ==== Pipelines A pipeline is a sequence of one or more commands separated by the character |. [..] Each command in a pipeline is executed as a separate pro cess (i.e., in a subshell). ==== Der letzte Satz erklaert, warum du in der zweiten subshell nach der pipe keinen Zugriff auf die in der ersten subshell gesetze Variable hast. Aber ich verstehe sowieso nicht, wozu du die pipe brauchst. Liest "osd_cat" denn die Werte aus stdin? Dort schreibst du ja folgendes hinein: while ... echo MB Temp: $MB_TEMP CPU Temp:$CPU_TEMP; [sleep] echo $FARBE done | osd_cat ... -c $FARBE Ich kenne osd_cat nicht und weiss nicht wie es arbeitet, aber eine Moeglichkeit dein Problem zu umgehen ist die Verwendund eines FIFOs (bzw. einer "named pipe"): $ { echo "foo"; echo "bar" >/tmp/FIFO; } | xargs echo "err='-c $( ./myFIFO done | osd_cat ... -c "$(<./myFIFO)" ... BTW: /dev/stderr statt nem eigenen FIFO zu verwenden klappt leider nicht. Den FIFO solltest du entweder (aber nicht in /tmp (!)) permanent anlegen, oder per 'mktemp' einen sicheren Dateinamen erstellen und diesen dann verwenden (und anschliessend loeschen). Das erfordert dann aber auch ein 'trap', das beim Beenden und Abbruch des scripts den FIFO wieder loescht. Siehe 'man mknod' und 'man 1 mktemp'. Falls du dich fuer diese Variante entschliesst melde dich ggfs. nochmal. Andere Varianten moegen moeglich sein, mir faellt aber grad nix mehr ein ;( HTH, -dnh -- "Not available in the United Stated and many other third world countries." -- "Three Dead Trolls In A Baggie": "The Kyoto Accord"
Hallo David, leider habe ich immer noch ein kleines Problem... Michael@tamboti:~/tmp> sh osd_sensors osd_sensors: line 59: /tmp/FIFO14234: Datei oder Verzeichnis nicht gefunden bye... michael@tamboti:~/tmp> Ich habe nicht herausbekommen warum osd_cat da meckert denn die Werte im FIFO sind richtig und lassen sich mit echo ausgeben. Das Skript habe ich angehangen. David Haller wrote:
Ich kenne osd_cat nicht und weiss nicht wie es arbeitet, aber eine Moeglichkeit dein Problem zu umgehen ist die Verwendund eines FIFOs (bzw. einer "named pipe"):
$ { echo "foo"; echo "bar" >/tmp/FIFO; } | xargs echo "err='-c $(
Der Teil in den {} simuliert dabei die while-Schleife, der Teil danach deinen Aufruf von 'osd_cat'.
#!/bin/bash # Variabeln auf die Bedrfnisse anpassen SLEEP_OK=30 SLEEP_ALARM=5 FARBE_OK=darkgreen FARBE_WARNUNG=yellow FARBE_ALARM=red WERT_OK=+30 WERT_WARNUNG=+40 WERT_ALARM=+50 ################################################################################## FARBE="$FARBE_OK" # Optimismus ist schliesslich alles SLEEP="$SLEEP_OK" TMPDIR=/tmp/FIFO$$ # temp directory # trap erros trap "echo ; echo \"bye...\" ; rm -rf ${TMPDIR}; exit 1" 1 2 3 4 5 7 9 10 12 15 while true ; do # Werte aus /proc lesen eval `sensors | sed -n ' /^MB Temp:/ s/MB Temp: [[:space:]]*\([^°]*\).*/MB_TEMP=\1/p ;/^CPU Temp:/ s/CPU Temp: [[:space:]]*\([^°]*\).*/CPU_TEMP=\1/p ; ' ` if [ "$CPU_TEMP" -gt "$WERT_WARNUNG" -a \ "$CPU_TEMP" -lt "$WERT_ALARM" ] ; then FARBE="$FARBE_WARNUNG"; fi if [ "$CPU_TEMP" -ge "$WERT_ALARM" ]; then FARBE="$FARBE_ALARM"; SLEEP="$SLEEP_ALARM"; fi if [ "$CPU_TEMP" -le "$WERT_OK" ] ; then FARBE="$FARBE_OK"; fi echo MB Temp: $MB_TEMP CPU Temp:$CPU_TEMP; echo "$FARBE" > ${TMPDIR} sleep $SLEEP done |osd_cat -l 1 -A left -p bottom -f -adobe-helvetica-*-*-*-*-18-*-*-*-*-*-* -c "$(<${TMPDIR})" -s 5 -S lightgray -o 65 -d 60 -- Encrypted eMail welcome! Get my OpenPGP-Key ID: 0xE9B00731 from: wwwkeys.de.pgp.net
Hallo, Am Sat, 31 Jul 2004, Michael Hoeller schrieb:
leider habe ich immer noch ein kleines Problem...
Michael@tamboti:~/tmp> sh osd_sensors osd_sensors: line 59: /tmp/FIFO14234: Datei oder Verzeichnis nicht gefunden
Aeh, FIFO soll ein FIFO sein ("First In, First Out"), aka "named pipe". Und kein Verzeichnis (oder eine Datei). Siehe 'man mknod'.
#!/bin/bash [..] FN='-adobe-helvetica-*-*-*-*-18-*-*-*-*-*-*'
TMPDIR=/tmp/FIFO$$ # temp directory
Eben nicht! FIFO=`mktemp -u "/tmp/FIFO$$XXXXXX"` || exit 1 mknod -m 600 "$FIFO" p
# trap erros trap "echo ; echo \"bye...\" ; rm -rf ${TMPDIR}; exit 1" 1 2 3 4 5 7 9 10 12 15
trap "echo -e '\nbye...' ; rm -f "$FIFO"; exit 1" 1 2 3 4 5 7 9 10 12 15
while true ; do [..] echo MB Temp: $MB_TEMP CPU Temp:$CPU_TEMP; echo "$FARBE" > ${TMPDIR}
echo "$FARBE" > "$FIFO"
sleep $SLEEP
done |osd_cat -l 1 -A left -p bottom -f -adobe-helvetica-*-*-*-*-18-*-*-*-*-*-* -c "$(<${TMPDIR})" -s 5 -S lightgray -o 65 -d 60
done | osd_cat -l 1 -A left -p bottom -f "$FN" -c "$(<$FIFO)" \ -s 5 -S lightgray -o 65 -d 60 HTH, -dnh --
und was ist "Winter"? Ein Zeitraum, in dem von der Decke des grossen blauen Raum gelegentlich groessere oder kleinere Mengen kalten weissen Drecks fallen, der aus kristallinem Dihydrogenmonoxid besteht. -- Alexander Schreiber
MichaelHoeller@t-online.de (Michael Hoeller)
im u.a. skript wird in der while true; Schleife der Wert für FARBE geändert aber allem Anschein nach gilt dieser nur lokal in der Schleife denn die Ausgabe von osd_cat ist immer grün. Liege ich mit meiner Vermutung richtig? Wenn ja wie kann den Wert aus der Schleife an osd_cat übergeben?
Das Script verkürzt: FARBE=rot while true ; do ... FARBE=gruen ... done | cmd $FARBE das macht sicherlich nicht das gewünschte, denn die WHILE-Schleife wird als Sub-shell ausgeführt, also selbst FARBE=rot while true ; do ... FARBE=gruen ... done echo $FARBE wird immer nur rot ausgeben. was hilft ist FARBE=rot echo $FARBE > $TMP_FILE while true ; do ... FARBE=gruen echo $FARBE > $TMP_FILE ... done | cmd `cat $TMP_FILE` Bye Jürgen -- Dr.rer.nat. Juergen Vollmer, Viktoriastrasse 15, D-76133 Karlsruhe Tel: +49(721) 9204871 Fax: +49(721) 24874 Juergen.Vollmer@[informatik-vollmer.de|alumni.uni-karlsruhe.de|acm.org] www.informatik-vollmer.de
Am Mittwoch, 28. Juli 2004 09:43 schrieb Dr. Jürgen Vollmer:
Das Script verkürzt: FARBE=rot while true ; do ... FARBE=gruen ... done | cmd $FARBE
das macht sicherlich nicht das gewünschte, denn die WHILE-Schleife wird als Sub-shell ausgeführt, also selbst FARBE=rot while true ; do ... FARBE=gruen ... done echo $FARBE
wird immer nur rot ausgeben.
Einspruch! -> cat ttt FARBE=rot while [ $FARBE = "rot" ] ; do FARBE=gruen done echo $FARBE -> ./ttt gruen Ist meine bash kaputt? Gruß, Wolfgang
Hallo Wolfgang, hallo Jürgen, hallo Leute, Am Mittwoch, 28. Juli 2004 10:06 schrieb Wolfgang Hinsch:
Am Mittwoch, 28. Juli 2004 09:43 schrieb Dr. Jürgen Vollmer:
Das Script verkürzt: FARBE=rot while true ; do ... FARBE=gruen ... done | cmd $FARBE ^^^ Wie schon von vielen geschrieben: die Variable "überlebt" die Pipe nicht, weil eine Pipe gleichzeitig zu einer Subshell führt.
Ich habe mal eine schöne Lösung gebastelt, um dieses Problem zu umgehen, allerdings nur mit Ausgabe der Variable nach Pipe-Ende und nicht in den nächsten Prozess hinter der Pipe. http://www.cboltz.de/de/linux/bash/?sl Wenn Du das eval rechtzeitig beendest, sollte es auch mit der Pipe klappen. Also: ("...." bitte durch Code wie auf meiner Homepage erklärt ersetzen) eval `while true ; do echo "FARBE=rot" >&4 ; done 4>&1 >&3` | cmd $FARBE Möglicherweise musst Du den Block vor der Pipe wieder auf stdout umleiten, also { eval `while true ; do echo "FARBE=rot" >&4 ; done 4>&1 >&3` ; } 3>&1 | cmd $FARBE Die Scripte auf meiner Homepage sind getestet und funktionieren, die Ergänzungen in dieser Mail sind nur ein Braindump, also ungetestet. Feedback erwünscht, dann ergänze ich das auch noch auf meiner Homepage ;-) Alternative: den Code etwas umstrukturieren, nämlich den Output in eine Variable packen und diese anschließend per echo an den nächsten Befehl weiterreichen. Also erstmal alles wie auf Homepage beschrieben (erste Methode) und danach echo "$text_to_print" | befehl
Einspruch!
-> cat ttt FARBE=rot while [ $FARBE = "rot" ] ; do FARBE=gruen done echo $FARBE
-> ./ttt gruen
Ist meine bash kaputt?
Nö, Dein Testscript ist zu kurz. Da kommt nirgends eine Pipe und damit auch keine Subshell vor. Gruß Christian Boltz -- Was zum Henker is nu AMSN schon wieder? Is das IRC in der "take n-plus-1 die 42sten" Reinkarnation? Mannmannmann, diese Chat-Dinger vermehren sich ja wie die Karnickel, muss ich mir auch mal einen schreiben, um noch hip zu sein, oder was? [David Haller in suse-linux]
Hallo, Am Thu, 29 Jul 2004, Christian Boltz schrieb: [..]
http://www.cboltz.de/de/linux/bash/?sl [..] eval `while true ; do echo "FARBE=rot" >&4 ; done 4>&1 >&3` | cmd $FARBE
Weisst du, dass 'eval' Sicherheitsprobleme aufwirft? Also generell halte ich die Variante mit nem FIFO (oder ner temporaeren Datei) fuer besser. -dnh -- Du meinst, es gibt Menschen die vom Katzen so trainiert sind, das die die Katzen so erziehen das die machen was sie sowieso wollen, die Leute aber glauben lassen das die genau gehorchen. -- Rik Steenwinkel
Hallo Liste, Hallo Christian Am Donnerstag, 29. Juli 2004 00:30 schrieb Christian Boltz:
Hallo Wolfgang, hallo Jürgen, hallo Leute,
Am Mittwoch, 28. Juli 2004 10:06 schrieb Wolfgang Hinsch:
Am Mittwoch, 28. Juli 2004 09:43 schrieb Dr. Jürgen Vollmer:
Das Script verkürzt: FARBE=rot while true ; do ... FARBE=gruen ... done | cmd $FARBE
^^^ Wie schon von vielen geschrieben: die Variable "überlebt" die Pipe nicht, weil eine Pipe gleichzeitig zu einer Subshell führt.
Richtig, aber nicht das Problem der 2.Subshell. Zur Zeit des forks steht die Variable auf rot. Da die 2 Subshell die Variable als Parameter bekommt, wird sie zum Zeitpunkt des forks übergeben und deshalb sieht die 2. Subshell "rot". Richtig ist, dass die Variable aus der ersten Subshell "stirbt", sie wird nicht weitergegeben. Das könnte entweder dadurch umgangen werden, dass sie in die Pipe geschrieben wird und damit die 2 Subshell erreicht (falls diese dann aus stdin liest), oder durch eine Konstruktion wie: FARBE=`echo "gruen"` s/echo/irgendEinScriptDasAufStdoutGruenAusgibt/ [...]
Einspruch!
-> cat ttt FARBE=rot while [ $FARBE = "rot" ] ; do FARBE=gruen done echo $FARBE
-> ./ttt gruen
Ist meine bash kaputt?
Nö, Dein Testscript ist zu kurz. Da kommt nirgends eine Pipe und damit auch keine Subshell vor.
Jein, Du hast leider das (2.)Beispiel von Jürgen, auf das ich mich bezogen habe, nicht zitiert (überlesen?). Gruß, Wolfgang
Am Mittwoch, 28. Juli 2004 09:43 schrieb Dr. Jürgen Vollmer:
MichaelHoeller@t-online.de (Michael Hoeller)
im u.a. skript wird in der while true; Schleife der Wert für FARBE geändert aber allem Anschein nach gilt dieser nur lokal in der Schleife denn die Ausgabe von osd_cat ist immer grün. Liege ich mit meiner Vermutung richtig? Wenn ja wie kann den Wert aus der Schleife an osd_cat übergeben?
Das Script verkürzt: FARBE=rot while true ; do ... FARBE=gruen ... done | cmd $FARBE
das macht sicherlich nicht das gewünschte, denn die WHILE-Schleife wird als Sub-shell ausgeführt, also selbst FARBE=rot while true ; do ... FARBE=gruen ... done echo $FARBE
wird immer nur rot ausgeben.
Nein! Wie David schon schrieb (und ich hatte Dich neulich schon mal darauf hingewiesen): Nicht die Schleife ist das Problem sondern die Pipe. jan@jack:~> f=rot jan@jack:~> while true; do
f=gruen break done jan@jack:~> echo $f gruen jan@jack:~> f=rot jan@jack:~> while true; do f=gruen; break; done | echo $f rot
Jan -- Linux-Quickies: http://www.jan-trippler.de PingoS: http://www.pingos.org
Am Mittwoch, 28. Juli 2004 10:10 schrieb Jan Trippler:
Am Mittwoch, 28. Juli 2004 09:43 schrieb Dr. Jürgen Vollmer:
das macht sicherlich nicht das gewünschte, denn die WHILE-Schleife wird als Sub-shell ausgeführt, also selbst FARBE=rot while true ; do ... FARBE=gruen ... done echo $FARBE
wird immer nur rot ausgeben.
Nein! Wie David schon schrieb (und ich hatte Dich neulich schon mal darauf hingewiesen): Nicht die Schleife ist das Problem sondern die Pipe.
jan@jack:~> f=rot jan@jack:~> while true; do
f=gruen break done
jan@jack:~> echo $f gruen jan@jack:~> f=rot jan@jack:~> while true; do f=gruen; break; done | echo $f rot
Ist eigentlich logisch: Die bash forkt 2x für die beiden Teile der Pipe. Danach laufen beide in separaten subshells. Dann kann die 2. subshell (echo) nur den Wert "rot" für $f haben, weil der zu diesem Zeitpunkt noch nicht verändert war. Würde sie aus stdin lesen, was sicher mehr Sinn machen würde, bekäme sie den veränderten Wert der 1. subshell Gruß, Wolfgang.
Jan.Trippler@t-online.de (Jan Trippler)
Nein! Wie David schon schrieb (und ich hatte Dich neulich schon mal darauf hingewiesen): Nicht die Schleife ist das Problem sondern die Pipe.
aargghhh, man sollte scripte immer testen bevor man in antwortet ..... sorry jürgen -- Dr.rer.nat. Juergen Vollmer, Viktoriastrasse 15, D-76133 Karlsruhe Tel: +49(721) 9204871 Fax: +49(721) 24874 Juergen.Vollmer@[informatik-vollmer.de|alumni.uni-karlsruhe.de|acm.org] www.informatik-vollmer.de
participants (7)
-
Christian Boltz
-
David Haller
-
Dr. Jürgen Vollmer
-
Jan.Trippler@t-online.de
-
Marcus Habermehl
-
MichaelHoeller@t-online.de
-
Wolfgang Hinsch