Archiv verlassen und diese Seite im Standarddesign anzeigen : bash und Umgebungsvariablen
Um mit bash etwas warm zu werden, habe ich zwei Scripte geschrieben. Im ersten setze ich
a=5
b=7
und rufe das zweite Script auf. Dort rechne ich
let c=$a*$b
echo $c
Der echo-Befehl gibt aber 0 aus, und nicht 35. Wie bringe ich bash dazu, den Inhalt von Variablen zwischen Scripts zu halten?
Avalox
2010-11-19, 17:29:12
Um mit bash etwas warm zu werden, habe ich zwei Scripte geschrieben. Im ersten setze ich
a=5
b=7
und rufe das zweite Script auf. Dort rechne ich
let c=$a*$b
echo $c
Der echo-Befehl gibt aber 0 aus, und nicht 35. Wie bringe ich bash dazu, den Inhalt von Variablen zwischen Scripts zu halten?
Mit dem Befehl export [Name der Variable]
Variable sind immer lokal gültig.
Wenn du das machen musst solltest du vlt. dein Design überdenken. Parameterübergabe fände ich eleganter als einfach mal wild Variablen zu globalisieren.
Ja - nur Übungsskripts, schon klar.
Die einzige Möglichkeit wäre die Scripts eben nicht als eigenen Prozess auszuführen, sondern sie im selben Prozess zu sourcen (quasi ein include):
$ source script1
$ source script2
oder die Kurzvariante:
$ . script1
$ . script2
Damit werden die Inhalte der Scripts in der aktuellen Shell ausgeführt und damit bleiben auch die Variablen in dieser erhalten.
Brillus
2010-11-20, 15:23:35
Mit dem Befehl export [Name der Variable]
Variable sind immer lokal gültig.
Wenn er die beidne scipts nur so hintereinander ausführt bringt auhc export nocht weil standartmäßig scripts seinen neuen Bash-prozess starten der sie dann ausführt. Und wenn der dann endet sind alle variablen die er gesetzt hat weg.
sei laut
2010-11-20, 16:02:50
Man könnte natürlich auch ein tempfile nutzen, um eine Variable zu übergeben.
Schreiben mit dem > (also echo $a > tempfile).
Lesen mit cat (also a=`cat tempfile`).
Avalox
2010-11-20, 20:00:23
Wenn er die beidne scipts nur so hintereinander ausführt bringt auhc export nocht weil standartmäßig scripts seinen neuen Bash-prozess starten der sie dann ausführt. Und wenn der dann endet sind alle variablen die er gesetzt hat weg.
Der Variablen Export gilt für alle Prozesse, welche aus einer Shell gestartet werden. Wenn eben eine neue Shell aus der Shell gestartet wird, sind die Variable auch der neuen Shell bekannt.
Wird allerdings jeder initiierte Prozess oder die UrShell beendet, werden auch die Variable gelöscht.
Der Variablen Export gilt für alle Prozesse, welche aus einer Shell gestartet werden. Wenn eben eine neue Shell aus der Shell gestartet wird, sind die Variable auch der neuen Shell bekannt.
Wird allerdings jeder initiierte Prozess oder die UrShell beendet, werden auch die Variable gelöscht.
So einfach ist das nicht, AFAIK gibts eine Unterscheidung zwischen login-shells und interaktiven shells. Ein export CMAKE_MODULE_PATH in .bashrc ist z.b. sichtbar wenn ich den QtCreator aus einer Shell des DE (Konsole / Gnome Terminal) starte - klar da jede interactive shell üblicherweise .bashrc sourct. Starte ich hingegen den QtCreator über das Menü (also nicht "händisch" aus einer shell heraus) ist der CMAKE_MODULE_PATH nicht sichtbar. Damits funktioniert muss dasselbe export nochmal in .bash_profile. Das DE läuft anscheinend aus einer login-shell heraus und sieht die Variablen der .bashrc nicht.
Was mich eignetlich wundert denn in .bash_profile steht
# /etc/skel/.bash_profile
# This file is sourced by bash for login shells. The following line
# runs your .bashrc and is recommended by the bash info pages.
[[ -f ~/.bashrc ]] && . ~/.bashrc
Es müsste also auch alles was in .bashrc steht bekannt sein...
sun-man
2010-11-20, 23:35:33
Gibts unter Linux auch das "set -xv" am Anfang eines Scriptes ? Das hilft Fehler zu finden und zu erkennen weil der ablauf des Scriptes quasi debuggt da steht. So könnte man sehen das die Variablen die eingelesen werden sollen nicht belegt sind oder belegt werden.
Persönlich versuch ich die Variablen unter Solaris immer im Script zu halten bzw zu belegen. Sollte doch mal was übergeben werden ziehe ich irgendwas unter /tmp vor was man dann wieder löscht.
Brillus
2010-11-21, 22:12:38
Der Variablen Export gilt für alle Prozesse, welche aus einer Shell gestartet werden. Wenn eben eine neue Shell aus der Shell gestartet wird, sind die Variable auch der neuen Shell bekannt.
Wird allerdings jeder initiierte Prozess oder die UrShell beendet, werden auch die Variable gelöscht.
Das ist es ja aber, wenn du ein script ausführst wird ja standartmäßig eine subshell geöffnet in der dann die Variablen gesetzt werden, wenn das script dann zuende wird ist die subshell weg und auhc deine variablen
EL_Mariachi
2010-11-21, 22:36:54
hats denn nen speziellen Grund warum das in äh 2 Scripten stehen soll?
hier mal mein "ich würds so machen, wenn ichs machen wollen würde" script...
#!/bin/bash
clear
echo "Multiplizieren von 2 Zahlen"
echo "Gib die erste Zahl ein"
read A
sleep 1
clear
echo "Gib die 2. Zahl ein"
read B
sleep 1
clear
echo "Du hast $A und $B eingegeben"
echo "Berechnung laeuft..."
sleep 3
C=$(echo "scale=5 ; $A*$B" | bc)
echo "Das Ergebnis lautet:"
sleep 2
echo " "
echo "$C"
echo " "
hier villeicht noch ein Hinweis zu den exports...
http://www.tldp.org/LDP/abs/html/othertypesv.html#ENVREF
wenn es 2 sein sollen...
script1
#!/bin/bash
echo "Gib die erste Zahl ein"
read A
sleep 1
clear
echo "Gib die 2. Zahl ein"
read B
sleep 1
clear
export A
export B
sh script2.sh
script2
#!/bin/bash
clear
echo "Multiplizieren von 2 Zahlen"
echo "Du hast $A und $B eingegeben"
echo "Multiplikation laeuft..."
sleep 3
#let C=$((A))*$((B))
C=$(echo "scale=5 ; $A*$B" | bc)
clear
echo "Das Ergebnis lautet:"
sleep 2
echo " "
echo "$C"
echo " "
.
Danke für die Hinweise mit bc, bash selbst scheint nur Integer zu unterstützen. Im Moment, zum Testen, reicht Integer aber man will sicherlich auch mal genauer rechnen.
Wenn ich ein Script aus einem anderen aufrufe, bleibt das erste so lange inaktiv bis das aufgerufene Script sich beendet? Oder anders gefragt, wie kann ich festlegen ob er den Prozess parallel starten soll, oder ob das aufrufende Script warten soll? Ich glaube da gibts ein Zeichen was man vor oder nach dem Dateinamen setzt um das beim Aufruf festzulegen?
Persönlich versuch ich die Variablen unter Solaris immer im Script zu halten bzw zu belegen. Sollte doch mal was übergeben werden ziehe ich irgendwas unter /tmp vor was man dann wieder löscht.Das war auch meine erste Idee, aber ich will vom Stick arbeiten und daher unnötige Laufwerkzugriffe vermeiden. Zum Auslesen von Variablen aus einem File habe ich auch noch Fragen, aber das formuliere ich lieber in einem Extra-Posting.
Brillus
2010-11-22, 14:15:18
Danke für die Hinweise mit bc, bash selbst scheint nur Integer zu unterstützen. Im Moment, zum Testen, reicht Integer aber man will sicherlich auch mal genauer rechnen.
Wenn ich ein Script aus einem anderen aufrufe, bleibt das erste so lange inaktiv bis das aufgerufene Script sich beendet? Oder anders gefragt, wie kann ich festlegen ob er den Prozess parallel starten soll, oder ob das aufrufende Script warten soll? Ich glaube da gibts ein Zeichen was man vor oder nach dem Dateinamen setzt um das beim Aufruf festzulegen?
musst ein & dahinter setzen dann läuft der Aufgerufene Befehl im Hintergrund ab und das aktuelle läuft weiter.
Wenn du aber da mit Umgebungsvaribalen arbeiten willst aufpassen, wenn ein Program(oder Script) aufgerufen wird bekommt es eine Kopie der aktuellen exportieren Umgebungsvaribalen. Sprich nach dem aufrufen des Kindprozesse hat eine änderung der Umgebeungsvaribale im Elternprozess keine auswirkung mehr auf den Kindprozess.
EL_Mariachi
2010-11-22, 14:38:07
vielleicht hier mal kurz drüber lesen...
ich versteh grad nicht so wirklich was Du vor hast :confused:
http://www.linuxtopia.org/online_books/advanced_bash_scripting_guide/internal.html
und hier mal noch was ausm ubuntu forum zum thema parallele prozesse...
http://ubuntuforums.org/showthread.php?t=382330
.
musst ein & dahinter setzen dann läuft der Aufgerufene Befehl im Hintergrund ab und das aktuelle läuft weiter.
Wenn du aber da mit Umgebungsvaribalen arbeiten willst aufpassen, wenn ein Program(oder Script) aufgerufen wird bekommt es eine Kopie der aktuellen exportieren Umgebungsvaribalen. Sprich nach dem aufrufen des Kindprozesse hat eine änderung der Umgebeungsvaribale im Elternprozess keine auswirkung mehr auf den Kindprozess.Kann man ohne dem Umweg, den Inhalt in eine Temp-Datei zu schreiben, Variablen in einem "Unterscript" ändern, so dass sie nach dessen Beendingung, wenn wieder das "Mutterscript" aktiv ist, dort gelesen werden können? Das scheint leider nicht zu gehen, wenn ich mit export eine Variable für das Unterscript lesbar mache und dort ändere, hat es danach im aufrufenden Script wieder den alten Wert.
Brillus
2010-11-22, 17:06:24
Kann man ohne dem Umweg, den Inhalt in eine Temp-Datei zu schreiben, Variablen in einem "Unterscript" ändern, so dass sie nach dessen Beendingung, wenn wieder das "Mutterscript" aktiv ist, dort gelesen werden können? Das scheint leider nicht zu gehen, wenn ich mit export eine Variable für das Unterscript lesbar mache und dort ändere, hat es danach im aufrufenden Script wieder den alten Wert.
Genau das habe ich ja gemeint das Unterscript bekommt nur eine Kopie davon.
Könntest es evtl mit trap und signalen probieren:
trap/signale
http://linuxcommand.org/wss0160.php
Oder halt irgendwelche arten von Interprozess Kommunikation(IPC) namedpipes unamedpipes. Da müsstest du aber selber schauen.
Parameterübergabe und Rückgabewerte kommen nicht in Frage? Oder, da Script 2 im "Mutterscript" aufgerufen wird, im Script 2 eine Ausgabe der relevanten Werte machen, und im Mutterscript den String auseinanderfriemeln.
vBulletin®, Copyright ©2000-2024, Jelsoft Enterprises Ltd.