• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

Umgebungsvariable mit Script verändern

hallo comunity,
ich möchte gern mit einem Script, welches von einer openSuSE Konsule (bash) mit Userrechten
gestartet wird, eine Umgebungsvariable modifiziert.
Die Umgebungsvariable habe ich in /etc/environment mit
Code:
RUNBITD=1
eingetragen.
Die Umgebungsvariabe ist in der Konsule mit
Code:
xxxxxxx@xxxxxxx:~> echo $RUNBITD
1
auch sichtbar.
Mit nachfolgenden Script lässt sich die Umgebungsvariable auch modifizieren.
Code:
echo "RUNBITD "$RUNBITD		        #--- einlesen -> ok
export runBitdefender=0                             #--- Variable moifizieren
echo "RUNBITD "$RUNBITD         #--- Variable -> ok
Wird anschliessend die Umgebungsvariable in der Konsle mit
Code:
xxxxxxx@xxxxxxx:~> echo $RUNBITD
1
angezeigt, ist die Modifizierung mittels des Scriptes unwirksam.
Was mache ich da falsch ? :-?

Würde mich über einen Tipp von Euch sehr freuen. :)

viele grüsse aus dem winterlichen Oberbayern
vom bayernherz
 
OP
B

bayernherz

Hacker
danke josef-wien,
ich weiss garnicht ob mein openSuSE 11.4 dieses Advanced Bash-Scripting beherscht.
Eigentlich wollte ich nicht noch zusätzlich eine neue Scriptsprache lernen,
da ich mich momentan mit Qt-GUI Programmierung übe.
Und dieses Scripting Problem nur ein Nebenpordukt ist.
Gibt es denn da keine konventionelle Lösung für mein Problem,
oder ist das ein generelles Problem, was sich so nicht lösen lässt.

Ich könnte erklären wozu ich dieses Script, wo drin noch einiges mehr enthalten ist als
nur das setzen einer Umgebungsvariable im Detail benötigt wird.
Ich denke das würde den Rahmen dieses Threads sprengen.

Über einen einfachen Tipp für dieses Problem würde ich mich sehr freuen.

viele grüsse aus dem abendlichen Oberbayern
vom bayernherz :)
 

marce

Guru
ich verstehe das Problem, welches Du mit der einfachen und völlig dem Standard entsprechenden Lösung hast, nicht. Da ist nichts besonderes dabei. Standard-Bash. Seit gefühlt 2 Mio Jahren.

Um Umgebungsvariablen zu setzen musst Du es eben so tun, daß sie in der aktiven Shell und ihren Subshells bekannt sind. Entweder stellst Du also beim Instanzieren der Shell die Variablen schon bereit (z.B. über die .bashrc) oder Du sorgst dafür, daß sie in der bereits aktiven Shell bekannt sind. Und das macht eben das source. Nicht mehr und nicht weniger.
 

josef-wien

Ultimate Guru
Ich habe Dich auf die Anleitung für Fortgeschrittene verwiesen, da ich sie bei Dir für sinnvoller halte als die Anleitung für Anfänger. Ich hätte auch
Code:
info BashBuiltins
nennen können. Ist hinsichtlich source noch etwas unklar?

bayernherz schrieb:
Ich hoffe, Du meinst die Evergreen-Variante, die noch bis Juli dieses Jahres ein bißchen unterstützt wird. Die normale Variante ist seit November 2012 tot.
 
OP
B

bayernherz

Hacker
hallo comunity,
leider bin ich nicht erfolgreich.

Advanced Bash-Scripting Guide:
-x export
declare -x var3
This declares a variable as available for exporting outside the environment of the script itself.
Nachfolgend mein Testscript:
Code:
echo "Environment RUNBITD: " $RUNBITD
RUNBITD=0
echo "Environment RUNBITD: " $RUNBITD
declare -x RUNBITD
echo "Environment RUNBITD: " $RUNBITD
Ausgabe Testscript:
Code:
 ---------------------------------------
|     Start Skript Test Environment     |
 ---------------------------------------
Environment RUNBITD:  1
Environment RUNBITD:  0
Environment RUNBITD:  0
Test nach beenden des Scripts
Code:
~/bin> echo $RUNBITD
1
Hinweis:
Umgebungsvariable RUNBITD wurde in
/etc/environment mit RUNBITD=1 definiert.

Ich möchte doch nur diese Umgebungsvariable mit dem Script dauerhaft auf 0 setzen.
:-?
 

marce

Guru
dann wirst Du wohl oder übel die Datei entsprechend bearbeiten müssen.

Variablen vererben nur nach unten.
 

josef-wien

Ultimate Guru
Du kannst aus einer Instanz der Bash keine Umgebungsvariablen einer anderen Instanz bearbeiten. Aber Du kannst dafür sorgen, daß keine neue Instanz erzeugt wird, und genau dafür ist source vorgesehen. Wenn Du dagegen den sich ändernden Wert einer bestimmten Umgebungsvariablen für eine neue Instanz zur Verfügung stellen willst, mußt Du diese Information in einer Datei speichern und diese Datei (selektiv oder generell) verwenden.

Lösungen gibt es viele, in der folgenden einfachen (selektiven) Variante wird ebenfalls source (in der Abkürzung als simpler Punkt) verwendet. Datei bayernherz.sh:
Code:
#!/bin/bash
export bayernherz="ex Skript"
echo $bayernherz
echo Textdatei wird einbezogen.
. /pfad/zu/bayernherz.txt
echo Hier ist wieder bayernherz.sh.
echo $bayernherz
Datei bayernherz.txt:
Code:
export bayernherz="ex Textdatei"
Wenn die Variable generell in jeder neuen Instanz zur Verfügung stehen soll, wird die Zeile
Code:
. /pfad/zu/bayernherz.txt
je nach Anforderung allgemein in /etc/bash.bashrc.local bzw. benutzerspezifisch in ~/.bashrc eingetragen.

Für den passenden Inhalt von bayernherz.txt mußt Du sorgen, aber das ist mit einem einfachen
Code:
echo 'export bayernherz="gewünschter Wert"' > /pfad/zu/bayernherz.txt
zu bewerkstelligen. Mit Programmierkenntnissen (auch awk und sed zähle ich dazu) ist es selbstverständlich eleganter, jeweils den Eintrag in (bei Deiner Variante) /etc/environment zu modifizieren.
 
OP
B

bayernherz

Hacker
hallo josef-wien
ich glaube ich muss jetzt doch mir die Muss nehmen und
erklären wofür das verändern der Umgebungsvariable in
dem Script verwendet wird.

Ich habe ein Qt-GUI Programm als Bedienoberfläche für
einen Virenscanner beschrieben.
Der Virenscanner ist ein Konsolenprogramm und wird von dem
Qt-Programm als Process gestartet.
Es gibt Konsolenprogramme ,die lassen sich ausschliesslich nur
mittels startDetached starten.
D.h. wiederum, ich kann den Process vom Mutterprocess weder
abbrechen noch detektieren, da er als komplett eigenständiger
Process auf dem Betriebssystm abläuft.
Allerdings muss ich im Qt-Programm wissen, wann der Virenscanner
seine Arbeit beendet hat, um die Sperrung einiger Tasten aufzuheben
und eine Anzeige zu steuern.
Es gibt da 2 Lösungen, die eine habe ich realisiert und funktioniert
perfekt. Die zweite, die elegantere, ist die mit der Umgebungsvariable.

So, um dieses Problem mit der Detektierung zu lösen, starte ich
vom Qt-Programm ein Script, welches den Scanner startet.
Da das Script sequneziell abläuft, kann ich darin Flags setzten.
Die 1. Lösung besteht darin ein File zu eröffnen u. bei beenden zu
schliessen. Das File vom Qt-Programm zu detekieren funktioniert perfekt.
Ist allerdings nicht so elegant, wie mit einer Umgebungsvariabelen,
die vom Qt-Programm gesetzt wird und am Ende des Startscripts zurückgesetzt
wird. Leider kann die Umgebungsvariable nicht ohne weiteres aus dem
bash-Script exportiert werden, so das es das Qt-Programm sieht.

Das ist die Problematik mit der ich kämpfe.
Sollte der Lösungsweg mit der Umgebungsvariable nicht zu
realisieren sein, ist es auch kein Beinbruch.
Es war dann ein Lösungsansatz der leider nicht funktioniert hat,
denn für mein Qt - Programm gibt es bereits eine funktionierende Lösung.

So jetzt habe ich eine Menge Text produziert, wo ich hoffe das es Euch
nicht zu viel zum lesen ist.

Aber ich denke, wir können hiernach klar entscheiden, den Weg mit der
Umgebungsvariablen weiter zu verfolgen oder zu verwerfen.

viele grüsse aus dem winterlichen Oberbayer
vom bayenherz :-/
 
OP
B

bayernherz

Hacker
hallo comunity,

Bei dem Szenario muß ich passen.
Ich werde es noch mal in einen Einzeiler zusammenfassen.
Eine Umgebungsvariable, die in
Code:
/etc/environment
mit
Code:
RUNBITD=1
festgelegt ist, wird in einem Script auf
Code:
RUNBITD=0
gesetzt.
Der Wert der Variable soll auch nach Beendigung des Scripts erhalten bleiben.
Fazit ist:
Nach Beendigung des Scripts steht die Variable wieder auf dem Wert 1
Anmerkung: Da hilft auch kein
Code:
export RUNBITD

viele grüsse aus dem winterlichen Oberbayern
vom bayernherz
 

josef-wien

Ultimate Guru
Du vereinfachst schon wieder.

Wenn Du aus der Konsole oder aus dem Skript A das Skript B startest, bleiben beim Start des Skripts B mittels source auch nach Beendigung von Skript B die von Skript B geänderten Umgebungsvariablen in dieser Konsole bzw. im Skript A erhalten.

Du jedoch startest das Skript B von einem in irgendeiner Programmiersprache geschriebenen Programm, und genau zu diesem Szenario, das Du uns erst gestern verraten hast, kann ich nichts beitragen. Je nach Programmiersprache mag es hier Möglichkeiten geben oder eben auch nicht.
 

marce

Guru
wie gesagt - wenn Du das dauerhaft haben willst musst Du die /etc/environment anpassen.

Aber für den von die oben genannten Anwendungszweck würde ich eh nicht auf Variablen setzen sondern generell auf Status-Files oder anderweitige, dauerhaftere Methoden.
 
OP
B

bayernherz

Hacker
hallo marce,
Aber für den von die oben genannten Anwendungszweck würde ich eh nicht auf Variablen setzen sondern generell auf Status-Files oder anderweitige, dauerhaftere Methoden
Was meinst Du mit Statusfile?
Die von mir bereits realisierte Methode mit dem File funktioniert bestens!
Ich dachte halt mit einer Umgebungsvariable sei das eleganter.
Entpuppt sich aber scheinbar als unlösbar.
Oder?

hallo josef-wien,
ich rufe aus einem Qt - Programm ein Script auf, das den Virenscanner startet und wenn der Virenscanner fertig ist
setze ich die Umgebungsvariable auf 0 und beende das Script.
Leider exportiert das Script die Umgebungsvariable nicht, denn diese ist nach verlassen des Scripts unverändert.
D.h. sie hat noch den Wert vor dem Scriptstart.

Fazit:
Sagt mir bitte ist der Lösungsansatz mit der Umgebungsvariable ein Irrweg.
Wenn ja, dann vergessen wir das Problem und ich bleibe bei der Lösung mit dem File.

viel grüsse aus dem tief verschneitem Oberbayern
vom bayernherz
 

josef-wien

Ultimate Guru
Standardmäßig läuft das Skript in einer separaten Umgebung, die nichts mit der Umgebung des Qt-Programms zu tun hat. Beide Umgebungen haben ihren eigenen Satz an Umgebungsvariablen. Wenn das Skript beendet wird, verschwindet auch dessen Umgebung.

Eine Lösung mit einer Umgebungsvariablen kann nur dann funktionieren, wenn das Qt-Programm in der Lage ist, das Skript innerhalb der Umgebung des Qt-Programms auszuführen. Ob bzw. wie so etwas möglich ist, entzieht sich meiner Kenntnis.

P. S. Wenn der Virenscanner einen pid file in /run anlegt, beweist dessen Existenz, daß das Programm noch läuft. Ansonsten würde ich so lange mit pidof die Existenz des Programms abfragen, bis der exit status 1 dessen Nicht-Existenz dokumentiert (falls Qt nicht über eine entsprechende Möglichkeit verfügt). Die Notwendigkeit für ein Skript sehe ich nicht.
 

TomcatMJ

Guru
Hm,ich würde da wohl auch eher mit einem Statusfile rangehen bei dieser Aufgabenstellung...
Dazu würde ich dann eben
1.) das Script was den Virenscanner startet um das Anlegen eines Statusfiles erweitern,dort in dises File erstmal "1" eintragen als "Virenscanner läuft"-Status.
2.) Im Script dann festlegen daß der Inhalt des Stausfiles auf 0 gesetzt wird wenn der Virenscanner ohne Fund problemlos durchgelaufen ist und auf 2 Wenn der Lauf abgebrochen wurde oder was verdächtiges gefunden wurde.
3.) Dann anschließend im qt-Programm das Statusfile auswerten und eine Fehlermeldung ausgeben wenn das Virenscanneraufrufscript und somit wohl auch der Virenscanner noch bzw. bereits läuft (das Statusfile also 1 als Inhalt hat), eine Alarmmeldung wenn der Virenscanner was gefunden hat oder abgebrochen wurde (also 2 im Statusfile steht) oder eben eine Erfolgs-/Erledigtmeldung ausgeben wenn der Virenscan ohne Fund problemlos durchgelaufen ist (das Statusfile also 0 enthält) und das qt-Programm dann das Statusfile löschen lassen.

(Und das obwohl ich mit Programmierung eigentlich nicht viel am Hut habe :D )
 
OP
B

bayernherz

Hacker
hallo TomcatMJ,
in vereinfachter Form, wie Du es vorgeschlagen hasst, habe ich es im Moment bereits realisiert.
Ich eröffne vom Script wärend der Scannerlaufzeit ein File (mit Dummyinhalt), was nach Beendigung des Scannerdurchlaufs wieder gelöscht wird. Funktioniert 1a.
Statusmeldung bekomme ich in einem Logfile von Scanner.
Hierfür gibt es auch einen extra Button in der Bedienoberfläche um dieses anzuschauen.

Du bestätigst mich mit Deiner Aussage, bei dem Konzept mit dem Statusfile zu bleiben.
Ich danke Dir für die Hilfe.

hallo josef-wien,
P. S. Wenn der Virenscanner einen pid file in /run anlegt, beweist dessen Existenz, daß das Programm noch läuft. Ansonsten würde ich so lange mit pidof die Existenz des Programms abfragen, bis der exit status 1 dessen Nicht-Existenz dokumentiert (falls Qt nicht über eine entsprechende Möglichkeit verfügt). Die Notwendigkeit für ein Skript sehe ich nicht.
Du hasst mich neugierig gemacht. Das werde ich mir unbedingt anschauen.
Wenn das funktioniert, wie es mir vorstelle, brauche ich garkein Startscript mehr.
Dann kann ich die Laufzeitdetektierung mit dem pid file in /run durchführen.

viele grüsse aus dem morgendliche oberbayern
vom bayernherz
 
Oben