Czy mogę wyeksportować zmienną do środowiska ze skryptu bash bez jej pozyskiwania?

282

Załóżmy, że mam ten skrypt

export.bash :

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

Kiedy wykonuję skrypt i próbuję uzyskać do niego dostęp $VAR, nie otrzymuję żadnej wartości!

echo $VAR

Czy jest jakiś sposób na uzyskanie dostępu do pliku$VAR poprzez wykonanie export.bash bez jego pozyskiwania?

tarrsalah
źródło
1
Możesz spróbować użyć aliasu zamiast skryptu do zdefiniowania zmiennej.
jdigital
Skrypt, nad którym pracuję, jest pewnego rodzaju wirtualnym menedżerem Java, wykonuję obliczenia, a następnie powinienem wyeksportować $ JAVA_HOME do env i dołączyć go do PATH.
tarrsalah
Cóż, możesz zapisać informacje do pliku, a następnie przeczytać je ponownie, ale pozyskiwanie wydaje się znacznie łatwiejsze.
jdigital
7
procesy potomne nie mogą zmieniać środowiska swoich rodziców. Rodzic musi wybrać, aby zmienić sam (albo z sourcealbo evalalbo ...)
Glenn Jackman
1
Aby przeczytać więcej na temat źródła, man sourcenie będzie działać, ponieważ sourcejest wbudowany w bash, musisz uruchomićhelp source
peterchaula

Odpowiedzi:

318

Czy jest jakiś sposób na dostęp do tego, $VARpo prostu wykonując go export.bashbez jego pozyskiwania?

Szybka odpowiedź: nie

Istnieje jednak kilka możliwych obejść.

Najbardziej oczywistym, o którym już wspomniałeś, jest użycie sourcelub .wykonanie skryptu w kontekście powłoki wywołującej:

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

Innym sposobem jest użycie skryptu zamiast ustawiania zmiennej środowiskowej, komendy drukowania, które ustawią zmienną środowiskową:

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

Trzecim podejściem jest posiadanie skryptu, który wewnętrznie ustawia zmienne środowiskowe, a następnie wywołuje określone polecenie w tym środowisku:

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

To ostatnie podejście może być całkiem użyteczne, chociaż jest niewygodne do użytku interaktywnego, ponieważ nie daje ustawień w bieżącej powłoce (z wszystkimi innymi ustawieniami i historią, którą zbudowałeś).

Keith Thompson
źródło
57

Aby najpierw wyeksportować zmienną VAR, najbardziej logicznym i najwyraźniej działającym sposobem jest źródło zmiennej:

. ./export.bash

lub

source ./export.bash

Teraz, gdy echo z głównej powłoki działa

 echo $VAR
HELLO, VARABLE

Zresetujemy teraz VAR

export VAR=""
echo $VAR

Teraz wykonamy skrypt, aby pobrać zmienną, a następnie ją rozbroić:

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

kod: 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

Oto jeden sposób

UWAGA: Eksport jest ograniczony do skryptu, który wykonuje eksport w głównej konsoli - jeśli chodzi o zadanie crona, dodałbym go tak jak w konsoli jak poniżej ... dla części poleceń wciąż wątpliwej: oto jak byś uruchom z powłoki:

W wierszu polecenia (o ile export.bash ma wiele wartości echa)

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

cat v1.sh

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

Teraz, pod warunkiem, że jest to do użytku - możesz udostępnić zmienne dla swoich skryptów w dowolnym momencie, wykonując alias bash:

myvars ./v1.sh
HELLO THERE
HI THERE

echo $VAR

.

dodaj to do swojego .bashrc

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

}

źródło pliku bashrc i możesz zrobić jak wyżej w dowolnym momencie ...

W każdym razie wracając do reszty…

Dzięki temu jest on dostępny na całym świecie, a następnie wykonuje skrypt.

po prostu uruchom echo, a następnie uruchom eksport na echu!

eksport kotów. bash

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

Teraz w ramach skryptu lub uruchomionej konsoli:

 export "$(./export.bash)"

Próbować:

echo $VAR
HELLO THERE

Wiele wartości, o ile wiesz, czego oczekujesz w innym skrypcie przy użyciu powyższej metody:

eksport kotów. 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

Teraz wyniki

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


.

i ostatnia końcowa aktualizacja do automatycznego przypisania, przeczytaj ZMIENNE:

./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

Skrypt: 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
źródło
Chcę wyeksportować VAR, uruchamiając plik, a nie go pozyskując.
tarrsalah
@ vahid powinieneś wyjaśnić, co robi twój skrypt.
FDinoff
1
dlaczego nie rozbroić zmiennej po sourcingu? będzie o wiele łatwiejsze niż ból, który próbujesz sobie wyrządzić, zaktualizuje skrypt test-eksport
VH
Podałem alternatywny sposób na zrobienie tego Tarrsalah
VH
ok końcowe aktualizacje - problemy z sugerowaną metodą i obejście pomysłu na alias bashrc byłyby prawdopodobnie dobrym rozwiązaniem
VH
22

Wykonać

set -o allexport

Wszelkie zmienne, które następnie pobierzesz z pliku, zostaną wyeksportowane do powłoki.

source conf-file

Po zakończeniu uruchom. Spowoduje to wyłączenie trybu allexport.

set +o allexport
mdornfe1
źródło
7
Cały punkt pytania brzmi: „Jak eksportować bez źródła”. Ta odpowiedź używa źródła.
Gonen I
@ekkis Tak, to nie odpowiada dokładnie na pytanie, ale za każdym razem, gdy szukałem sposobu eksportowania zmiennych z pliku, pojawiał się ten wątek. Więc po prostu umieściłem to dla siebie.
mdornfe1
prosty i łatwy w użyciu. należy to zaznaczyć jako odpowiedź.
QkiZ
1
Głosowałem za tym, ponieważ oryginalne stwierdzenie problemu doprowadziło mnie do zrozumienia, że ​​to było moje podstawowe rozwiązanie. Oficjalne dokumenty na allexport są tutaj: gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
benjaoming
ahh +1. To pytanie jest najwyższym wynikiem słowa kluczowego bash source exportw Google
ttimasdf
14

Znaleziono ciekawy i schludny sposób na eksport zmiennych środowiskowych z pliku:

w env.vars:

foo=test

skrypt testowy:

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
Awangarda
źródło
7

Kolejne obejście, które, w zależności od przypadku, może być przydatne: tworzenie kolejnego basha, który dziedziczy eksportowaną zmienną. Jest to szczególny przypadek odpowiedzi @Keith Thompson, wszystkie te wady.

export.bash:

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

Teraz:

./export.bash
echo $VAR
Gonmator
źródło
Czy jesteś pewien, że to, co napisałeś, działa !? Uważam, że musisz wykonać polecenie liniowe:. ./export.bash
Sir Jo Black,
@ Sir Jo Black, tak, jasne. Ostatni wiersz pliku export.bash wywołuje bashjako element potomny bieżącej powłoki. A ponieważ VARbył wcześniej eksportowany, to wywołanie obejmie zmienną. Oczywiście, jeśli wpiszesz zgaśnie. Czy sprawdziłeś? exitVAR
Gonmator,
Dobrze! Nie widziałem tej inwokacji ...: p
Sir Jo Black
1

Odpowiedź brzmi: nie, ale dla mnie zrobiłem następujące

skrypt: myExport

#! \bin\bash
export $1

alias w moim .bashrc

alias myExport='source myExport' 

Nadal go pozyskujesz, ale może w ten sposób jest bardziej użyteczny i interesujący dla kogoś innego.

Malcomar
źródło
1

Może możesz napisać funkcję w ~ / .zshrc, ~ / .bashrc.

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

Ze względu na użycie zmiennej na zewnątrz można uniknąć zapisu pliku skryptu.

zhi.yang
źródło