Kann ich eine Variable aus einem Bash-Skript in die Umgebung exportieren, ohne sie zu beziehen?

282

Angenommen, ich habe dieses Skript

export.bash :

#! /usr/bin/env bash
export VAR="HELLO, VARIABLE"

Wenn ich das Skript ausführe und versuche, auf das zuzugreifen $VAR, erhalte ich keinen Wert!

echo $VAR

Gibt es eine Möglichkeit, auf die Datei zuzugreifen, $VARindem Sie export.bash ausführen, ohne sie zu beziehen ?

Tarrsalah
quelle
1
Sie können versuchen, einen Alias ​​anstelle eines Skripts zu verwenden, um Ihre Variable zu definieren.
jdigital
Das Skript, an dem ich arbeite, ist eine Art virtueller Java-Manager. Ich berechne etwas, dann sollte ich ein $ JAVA_HOME in die Umgebung exportieren und es an PATH anhängen.
Tarrsalah
Nun, Sie könnten die Informationen in eine Datei schreiben und sie dann wieder einlesen, aber die Beschaffung scheint viel einfacher zu sein.
jdigital
7
Untergeordnete Prozesse können die Umgebung ihrer Eltern nicht ändern. Der Elternteil muss sich entscheiden, sich selbst zu ändern (entweder mit sourceoder evaloder ...)
Glenn Jackman
1
Um mehr über die Quelle zu lesen, man sourcefunktioniert es nicht, weil sourcees in Bash eingebaut ist. Sie müssen laufenhelp source
Peterchaula

Antworten:

318

Gibt es eine Möglichkeit, auf das zuzugreifen, $VARindem Sie es einfach ausführen, export.bashohne es zu beschaffen?

Schnelle Antwort: Nein.

Es gibt jedoch mehrere mögliche Problemumgehungen.

Das offensichtlichste, das Sie bereits erwähnt haben, ist die Verwendung sourceoder .Ausführung des Skripts im Kontext der aufrufenden Shell:

$ cat set-vars1.sh 
export FOO=BAR
$ . set-vars1.sh 
$ echo $FOO
BAR

Eine andere Möglichkeit besteht darin, dass das Skript anstelle des Festlegens einer Umgebungsvariablen Befehle druckt, mit denen die Umgebungsvariable festgelegt wird:

$ cat set-vars2.sh
#!/bin/bash
echo export FOO=BAR
$ eval "$(./set-vars2.sh)"
$ echo "$FOO"
BAR

Ein dritter Ansatz besteht darin, ein Skript zu haben, das Ihre Umgebungsvariablen intern festlegt und dann einen angegebenen Befehl mit dieser Umgebung aufruft:

$ cat set-vars3.sh
#!/bin/bash
export FOO=BAR
exec "$@"
$ ./set-vars3.sh printenv | grep FOO
FOO=BAR

Dieser letzte Ansatz kann sehr nützlich sein, ist jedoch für die interaktive Verwendung unpraktisch, da Sie nicht die Einstellungen in Ihrer aktuellen Shell erhalten (mit allen anderen Einstellungen und dem Verlauf, die Sie erstellt haben).

Keith Thompson
quelle
57

Um die VAR-Variable zuerst zu exportieren, ist es am logischsten und sinnvollsten, die Variable als Quelle zu verwenden:

. ./export.bash

oder

source ./export.bash

Jetzt funktioniert es beim Echo von der Haupt-Shell

 echo $VAR
HELLO, VARABLE

Wir werden jetzt VAR zurücksetzen

export VAR=""
echo $VAR

Jetzt führen wir ein Skript aus, um die Variable zu beschaffen, und deaktivieren sie dann:

./test-export.sh 
HELLO, VARABLE
--
.

der Code: cat test-export.sh

    #!/bin/bash
    # Source env variable
    source ./export.bash

    # echo out the variable in test script
    echo $VAR

    # unset the variable 
    unset VAR
    # echo a few dotted lines
    echo "---"
    # now return VAR which is blank
    echo $VAR

Hier ist ein Weg

BITTE BEACHTEN SIE: Die Exporte beschränken sich auf das Skript, das die Exporte in Ihrer Hauptkonsole ausführt. Soweit es sich um einen Cron-Job handelt, würde ich ihn wie die Konsole wie unten hinzufügen ... für den Befehlsteil noch fraglich: So würden Sie vorgehen renn von deiner Shell herein:

An Ihrer Eingabeaufforderung (solange die Datei export.bash mehrere Echowerte enthält)

IFS=$'\n'; for entries in $(./export.bash); do  export $entries;  done; ./v1.sh 
HELLO THERE
HI THERE

Katze v1.sh.

#!/bin/bash
echo $VAR
echo $VAR1

Solange dies für Ihre Verwendung bestimmt ist, können Sie die Variablen jederzeit für Ihre Skripte verfügbar machen, indem Sie einen Bash-Alias ​​wie den folgenden ausführen:

myvars ./v1.sh
HELLO THERE
HI THERE

echo $VAR

.

füge dies zu deiner .bashrc hinzu

function myvars() { 
    IFS=$'\n'; 
    for entries in $(./export.bash); do  export $entries;  done; 

    "$@"; 

    for entries in $(./export.bash); do variable=$(echo $entries|awk -F"=" '{print $1}'); unset $variable;
done

}

Quelle Ihre bashrc-Datei und Sie können wie oben jederzeit tun ...

Wie auch immer, zurück zum Rest.

Dies hat es global verfügbar gemacht und dann das Skript ausgeführt.

Echo es einfach aus und starte den Export für das Echo!

cat export.bash

#!/bin/bash
echo "VAR=HELLO THERE"

Jetzt im Skript oder auf Ihrer Konsole ausführen:

 export "$(./export.bash)"

Versuchen:

echo $VAR
HELLO THERE

Mehrere Werte, solange Sie mit der obigen Methode wissen, was Sie in einem anderen Skript erwarten:

cat export.bash

#!/bin/bash
echo "VAR=HELLO THERE"
echo "VAR1=HI THERE"

cat test-export.sh

#!/bin/bash

IFS=$'\n'
for entries in $(./export.bash); do
   export $entries
done

echo "round 1"
echo $VAR
echo $VAR1

for entries in $(./export.bash); do
     variable=$(echo $entries|awk -F"=" '{print $1}');
     unset $variable
done

echo "round 2"
echo $VAR
echo $VAR1

Nun die Ergebnisse

 ./test-export.sh 
round 1
HELLO THERE
HI THERE
round 2


.

und das letzte endgültige Update für die automatische Zuweisung lesen Sie die VARIABLEN:

./test-export.sh 
Round 0 - Export out then find variable name - 
Set current variable to the variable exported then echo its value
$VAR has value of HELLO THERE
$VAR1 has value of HI THERE
round 1 - we know what was exported and we will echo out known variables
HELLO THERE
HI THERE
Round 2 - We will just return the variable names and unset them 
round 3 - Now we get nothing back

Das Skript: cat test-export.sh

#!/bin/bash

IFS=$'\n'
echo "Round 0 - Export out then find variable name - "
echo "Set current variable to the variable exported then echo its value"
for entries in $(./export.bash); do
 variable=$(echo $entries|awk -F"=" '{print $1}');
 export $entries
 eval current_variable=\$$variable
 echo "\$$variable has value of $current_variable"
done


echo "round 1 - we know what was exported and we will echo out known variables"
echo $VAR
echo $VAR1

echo "Round 2 - We will just return the variable names and unset them "
for entries in $(./export.bash); do
 variable=$(echo $entries|awk -F"=" '{print $1}');
 unset $variable
done

echo "round 3 - Now we get nothing back"
echo $VAR
echo $VAR1
VH
quelle
Ich möchte VAR exportieren, indem ich die Datei ausführe, nicht indem ich sie beschaffe.
Tarrsalah
@vahid sollten Sie erklären, was Ihr Skript tut.
FDinoff
1
Warum nicht die Variable nach dem Sourcing deaktivieren? Es ist viel einfacher als der Schmerz, den Sie selbst verursachen wollen, um das Test-Export-Skript zu aktualisieren
VH
Ich gab eine alternative Möglichkeit, es zu tun Tarrsalah
VH
ok abschließende Updates - Probleme mit der vorgeschlagenen Methode und Umgehung der bashrc-Alias-Idee wären wahrscheinlich ein guter Weg
VH
22

Ausführen

set -o allexport

Alle Variablen, die Sie danach aus einer Datei beziehen, werden in Ihre Shell exportiert.

source conf-file

Wenn Sie fertig sind, führen Sie aus. Dadurch wird der Allexport-Modus deaktiviert.

set +o allexport
mdornfe1
quelle
7
Der ganze Punkt der Frage ist "Wie man ohne Quelle exportiert". Diese Antwort verwendet Quelle.
Gonen I
@ekkis Ja, es beantwortet die Frage nicht genau, aber wann immer ich gegoogelt habe, wie man Variablen aus einer Datei exportiert, ist dieser Thread aufgetaucht. Also habe ich es einfach für mich selbst dort hingelegt.
mdornfe1
einfach und leicht zu bedienen. Dies sollte als Antwort markiert werden.
QkiZ
1
Ich habe dies positiv bewertet, weil die ursprüngliche Problemstellung mich zu dem Verständnis führte, dass dies meine grundlegende Lösung war. Es gibt offizielle Dokumente auf allexport hier: gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
benjaoming
ahh, +1. Diese Frage ist das Top-Ergebnis des bash source export
Keywords
14

Es wurde eine interessante und übersichtliche Möglichkeit gefunden, Umgebungsvariablen aus einer Datei zu exportieren:

in env.vars:

foo=test

Testskript:

eval `cat env.vars`
echo $foo         # => test
sh -c 'echo $foo' # => 

export eval `cat env.vars`
echo $foo         # => test
sh -c 'echo $foo' # => test

# a better one
export `cat env.vars`
echo $foo         # => test
sh -c 'echo $foo' # => test
Van
quelle
7

Eine weitere Problemumgehung, die je nach Fall nützlich sein kann: Erstellen einer weiteren Bash, die die exportierte Variable erbt. Es ist ein besonderer Fall von @Keith Thompson Antwort, werden all diese Nachteile.

export.bash:

# !/bin/bash
export VAR="HELLO, VARIABLE"
bash

Jetzt:

./export.bash
echo $VAR
Gonmator
quelle
Bist du sicher, dass das, was du geschrieben hast, funktioniert? Ich glaube, dass Sie den Zeilenbefehl ausführen müssen:. ./export.bash
Sir Jo Black
@ Sir Jo Black, ja, sicher. Die letzte Zeile der Datei export.bash wird bashals untergeordnetes Element der aktuellen Shell aufgerufen . Und da VARzuvor exportiert wurde, enthält dieser Aufruf die Variable. Wenn Sie tippen, wird exitdas natürlich VARausgehen. Hast du kontrolliert?
Gonmator
OK! Ich habe diese Anrufung nicht gesehen ...: p
Sir Jo Black
1

Die Antwort ist nein, aber für mich habe ich folgendes getan

das Skript: myExport

#! \bin\bash
export $1

ein Alias ​​in meinem .bashrc

alias myExport='source myExport' 

Sie beziehen es immer noch, aber vielleicht ist es auf diese Weise benutzerfreundlicher und für jemand anderen interessant.

Malcomar
quelle
1

Vielleicht können Sie eine Funktion in ~ / .zshrc, ~ / .bashrc schreiben.

# set my env
[ -s ~/.env ] && export MYENV=`cat ~/.env`
function myenv() { [[ -s ~/.env ]] && echo $argv > ~/.env && export MYENV=$argv }

Da die Variable außerhalb verwendet wird, können Sie das Schreiben von Skriptdateien vermeiden.

zhi.yang
quelle