Чи можу я експортувати змінну в навколишнє середовище із скрипту bash, не використовуючи її?


282

Припустимо, у мене є цей сценарій

export.bash :

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

Коли я виконую скрипт і намагаюся отримати доступ до $VAR, я не отримую ніякого значення!

echo $VAR

Чи є якийсь спосіб отримати доступ до $VAR, просто виконавши export.bash, не використовуючи його?


1
Ви можете спробувати використовувати псевдонім замість сценарію, щоб визначити свою змінну.
jdigital

Сценарій, над яким я працюю, - це якийсь віртуальний менеджер Java, я роблю деякі обчислення, тоді я повинен експортувати $ JAVA_HOME до env і додати його до PATH.
тарсала

Ну, ви можете написати інформацію у файл, а потім прочитати її назад, але пошук здається набагато простішим.
jdigital

7
дочірні процеси не можуть змінити середовище батьків. Батько повинен вибрати , щоб змінити сам (або з sourceабо evalабо ...)
Glenn Джекман

1
Щоб прочитати більше про джерело, man sourceне вийде, тому що sourceвбудований в bash, вам потрібно запуститиhelp source
peterchaula

Відповіді:


318

Чи є якийсь спосіб отримати доступ до цього $VARпросто виконувати, export.bashне використовуючи його?

Швидка відповідь: Ні.

Але існує кілька можливих шляхів вирішення.

Найбільш очевидним, про який ви вже згадували, є використання sourceабо .виконання сценарію в контексті оболонки виклику:

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

Інший спосіб - це сценарій, а не встановлення змінної середовища, команд друку, які встановлюють змінну середовища:

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

Третій підхід - це створення сценарію, який встановлює внутрішню змінну (-и) середовища, а потім викликає вказану команду з цим середовищем:

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

Цей останній підхід може бути дуже корисним, хоча він є незручним для інтерактивного використання, оскільки він не дає вам налаштувань у вашій поточній оболонці (з усіма іншими налаштуваннями та історією, яку ви створили).


57

Для експорту змінної VAR спочатку найбільш логічним і, здається, працюючим способом є джерело змінної:

. ./export.bash

або

source ./export.bash

Тепер, коли лунає з головної оболонки, вона працює

 echo $VAR
HELLO, VARABLE

Зараз ми скинемо VAR

export VAR=""
echo $VAR

Тепер ми виконаємо скрипт для джерела змінної, а потім скасуємо її:

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

код: 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

Ось один із способів

ВВАГА: Примітка: Експорт обмежується сценарієм, який виконує експорт у вашій головній консолі - так що, як робота з cron, я додав би її як консоль, як показано нижче ... для командної частини все ще сумнівно: ось як би ви запустіть із своєї оболонки:

У вашому командному рядку (до тих пір, поки export.bash має кілька значень відлуння)

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

кіт v1.sh

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

Тепер, поки це для вашого використання - ви можете в будь-який час зробити доступними змінні для ваших сценаріїв, зробивши bash псевдонім на зразок цього:

myvars ./v1.sh
HELLO THERE
HI THERE

echo $VAR

.

додайте це до свого .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

}

джерело вашого файлу bashrc, і ви можете робити, як вище, будь-коли ...

Як би там не було,

Це зробило його доступним у всьому світі, а потім виконав сценарій.

просто відлучіть його, а потім запустіть експорт на ехо!

котячий експорт.баш

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

Тепер у сценарії чи консолі запустіть:

 export "$(./export.bash)"

Спробуйте:

echo $VAR
HELLO THERE

Кілька значень, якщо ви знаєте, що ви очікуєте в іншому сценарії, використовуючи вищевказаний метод:

котячий експорт.баш

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

кішка 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

Тепер результати

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


.

і остаточне остаточне оновлення для автоматичного присвоєння читання VARIABLES:

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

Сценарій: 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

Я хочу експортувати VAR шляхом виконання файлу, а не шляхом його пошуку.
тарсала

@vahid, ви повинні пояснити, що робить ваш сценарій.
FDinoff

1
чому б не зняти змінну після джерела? це буде набагато простіше, ніж біль, яку намагаються завдати собі, оновить сценарій тестування-експорту
VH

Я дав альтернативний спосіб зробити це Тарсала
VH

ОК остаточні оновлення - проблеми з запропонованим методом і робота оточує ідею псевдоніма bashrc, мабуть, буде чудовим виходом
VH

22

Виконати

set -o allexport

Будь-які змінні, які ви отримуєте з файлу після цього файлу, будуть експортовані у вашій оболонці.

source conf-file

Коли ви закінчите виконати. Це відключить режим алекспорту.

set +o allexport

7
Вся суть питання - «Як експортувати без джерела». У цій відповіді використовується джерело.
Gonen I

@ekkis Так, це не точно відповідає на запитання, але щоразу, коли я гуглив, як експортувати змінні з файлу, з'явилася ця нитка. Тож я свого роду просто поклав її там для себе.
mdornfe1

простий і простий у використанні. це слід позначити як відповідь.
QkiZ

1
Я підтримав це, оскільки оригінальна постановка проблеми дозволила зрозуміти, що це було моє основне рішення. Тут є офіційні документи про allexport: gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
benjaoming

ах, +1. Це питання - найкращий результат ключового слова bash source exportв Google
ttimasdf

14

Знайшов цікавий і акуратний спосіб експорту змінних середовища з файлу:

в env.vars:

foo=test

тестовий сценарій:

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

7

Інше рішення, яке, залежно від випадку, може бути корисним: створення іншого bash, який успадковує експортовану змінну. Це окремий випадок відповіді @Keith Thompson, чи будуть усі ці недоліки.

export.bash:

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

Зараз:

./export.bash
echo $VAR

Ви впевнені, що те, що ви написали, працює !? Я вважаю, що вам потрібно виконати команду рядка:. ./export.bash
Сер Джо Блек

@ Сир Джо Блек, так, звичайно. Останній рядок файлу export.bash викликає bashдочірню частину поточної оболонки. А оскільки VARекспортувався раніше, це виклик буде включати змінну. Звичайно, якщо ви наберете вийде. Ви перевірили? exitVAR
Гонматор

Гаразд! Я не бачив цього виклику ...: p
Сер Джо Блек

1

Відповідь - ні, але для мене я зробив наступне

сценарій: myExport

#! \bin\bash
export $1

псевдонім у моєму .bashrc

alias myExport='source myExport' 

Все-таки ви його джерело, але, можливо, таким чином він є більш корисним і цікавим для когось іншого.


1

Можливо, ви можете написати функцію в ~ / .zshrc, ~ / .bashrc.

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

Через використання змінної зовні, ви можете уникнути написання файлу сценарію.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.