Wie kann eine Umgebungsvariable nur für die Dauer des Skripts festgelegt werden?

127

Ist es unter Linux (Ubuntu 11.04) in bash möglich, vorübergehend eine Umgebungsvariable festzulegen, die sich nur für die Dauer des Skripts von der normalen Variablen unterscheidet? Beispiel: Erstellen Sie in einem Shell-Skript eine App, die in HOME gespeichert wird, portabel, indem Sie HOME vorübergehend in einem Ordner im aktuellen Arbeitsverzeichnis festlegen und dann die App starten.

suchipi
quelle
5
Es wäre schwieriger, wenn Sie möchten, dass die Einstellung über die Dauer des Skripts hinausgeht
Nemo

Antworten:

119
VAR1=value1 VAR2=value2 myScript args ...
Rockallite
quelle
2
Ich habe das schon viele Male selbst gemacht, um zu rennen vblank_mode=0 glxgears. Es funktioniert, aber es heißt auch vblank_mode=0: command not foundnach dem Ausführen, während das Voranstellen envdies nicht verursacht. [Testen ...] Anscheinend mag zsh es nicht (verwendet es aber immer noch richtig), aber bash ist damit einverstanden. Ich denke, ich werde envvon nun an mit der Methode weitermachen .
Chinoto Vokro
2
mit Skripten funktioniert es, aber wie wäre es, wenn Sie VAR1="hello" echo $VAR1nichts zurückgeben?
Zibri
2
@ Zibri es geht darum, wann die Erweiterung stattfindet. Wahrscheinlich können Sie so etwas tun:VAR1="hello" bash -c 'echo $VAR1'
Cybergrind
Upvoted für den Nachweis, dass dies auch für mehrere Umgebungsvariablen möglich ist.
Binarus
70
env VAR=value myScript args ...
Glenn Jackman
quelle
18
OderVAR=value myScript args ...
Rockallite
9
1. Wie kommt PATH=$PATH:XYZ echo $PATH | grep XYZes, dass es keine Ausgabe gibt? 2. Was ist der Unterschied zwischen Verwenden und Nichtverwenden env?
Qubodup
18
weil die Shell die Variable PATH erweitert, bevor der Befehl echo ausgeführt wird. Sie müssen diese Erweiterung verzögern. Ein Weg: PATH=$PATH:XYZ sh -c 'echo $PATH' | grep XYZ- Die einfachen Anführungszeichen sind der Schlüssel hier
Glenn Jackman
14
Was ist der Unterschied zwischen Verwenden envund Nichtverwenden?
Mohammed Noureldin
Dies scheint nicht in einem Oneliner wieIFS=$'\n' for l in lines; do ... done
Drevicko
31

Einfach gesagt

export HOME=/blah/whatever

an der Stelle im Skript, an der die Änderung erfolgen soll. Da jeder Prozess seine eigenen Umgebungsvariablen hat, hat diese Definition beim Beenden des Skripts (und damit der Bash-Instanz mit einer geänderten Umgebung) automatisch keine Bedeutung mehr.

hmakholm hat Monica verlassen
quelle
11
Das ist irreführend. exportÜbergibt die Variable an Subshells, steuert jedoch nicht die übergeordnete Shell. Wenn Sie ein Skript schreiben, das mit "#! / Bin / sh" oder ähnlichem beginnt, verschwindet JEDE von Ihnen festgelegte Variable beim Beenden des Skripts.
Brightlancer
1
@brightlancer, das ist wahr, scheint aber nichts zu widersprechen, was ich geschrieben habe. (Mit Ausnahme der Möglichkeit, dass das Skript einen Hintergrundprozess startet, aber ich denke, dass dies über den Grad der Raffinesse des OP hinausgeht und nur verwirren würde).
Hmakholm verließ Monica
5
Der Export ist nicht erforderlich. Außerdem funktioniert Ihre Antwort nur, wenn sein Skript einen Interpreter aufruft (#! / Bin / sh oder dergleichen). Wenn sein "Skript" dies nicht tut, bleibt das, was Sie ihm gerade gesagt haben, über das Ende seines Skripts hinaus bestehen. Deshalb habe ich gesagt, dass Ihre Antwort irreführend ist - es könnte richtig sein, es könnte nicht, aber es hat definitiv einen Teil, der unnötig und verwirrend ist, weil es jemanden veranlassen könnte, zu denken, dass "Export" das notwendige Element ist, nach dem er gesucht hat.
Brightlancer
7
@brightlancer: Der Export ist notwendig, wenn das OP-Skript Unterskripte aufruft, die selbst von $ HOME abhängen, und ich wagte nicht anzunehmen, dass dies nicht der Fall war. Darüber hinaus erzeugt bash eine Subshell, um ein Skript auszuführen, selbst wenn das Skript keine Shebang-Zeile enthält, sondern nur eine Textdatei mit gesetztem Ausführungsbit ist. Probieren Sie es aus - Variablenzuweisungen im Skript sind in der Shell, von der aus Sie sie aufrufen, nicht sichtbar. Nur wenn Sie sourcedas Skript explizit verwenden , wird es von derselben Shell ausgeführt, in die Sie den Befehl eingeben.
Hmakholm verließ Monica
4
@brightlancer: Der Export ist erforderlich, wenn er $HOMEvon Befehlen geerbt werden soll, die vom Skript ausgeführt werden. Und wenn er dies nicht tut und die Einstellung $HOMEnur dem Skript selbst zugute kommt, ist es wahrscheinlich besser, das Skript so zu ändern, dass es sich auf etwas anderes bezieht als $HOME.
Keith Thompson