Могу ли я экспортировать переменную в среду из скрипта bash, не используя ее?

282

Предположим, что у меня есть этот скрипт

export.bash :

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

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

echo $VAR

Есть ли какой-нибудь способ получить доступ к файлу,$VAR просто выполнив export.bash без его получения?

tarrsalah
источник
1
Вы можете попробовать использовать псевдоним вместо скрипта для определения вашей переменной.
jdigital
Скрипт, над которым я работаю, является своего рода виртуальным менеджером Java, я делаю некоторые вычисления, затем мне нужно экспортировать $ JAVA_HOME в env и добавить его в PATH.
tarrsalah
Ну, вы могли бы записать информацию в файл и затем прочитать ее обратно, но поиск источников кажется намного проще.
jdigital
7
дочерние процессы не могут изменить среду своего родителя. Родитель должен выбрать, чтобы изменить себя (или с sourceили evalили ...)
Гленн Джекман
1
Чтобы узнать больше об источнике, man sourceон не будет работать, потому что sourceвстроен в bash, вам нужно запуститьhelp source
peterchaula

Ответы:

319

Есть ли способ получить доступ к $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 есть несколько значений echo)

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, и вы можете сделать, как указано выше, в любое время ...

Во всяком случае вернемся к остальному ..

Это сделало его доступным во всем мире, а затем выполнил сценарий ..

просто сделайте вывод, а затем запустите экспорт!

кошка export.bash

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

Теперь внутри скрипта или вашей консоли запустите:

 export "$(./export.bash)"

Пытаться:

echo $VAR
HELLO THERE

Несколько значений, если вы знаете, что вы ожидаете в другом скрипте, используя метод выше:

кошка export.bash

#!/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


.

и окончательное окончательное обновление для автоматического назначения прочитайте переменные:

./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, выполняя файл, а не используя его.
tarrsalah
@vahid ты должен объяснить, что делает твой сценарий.
FDinoff
1
почему бы не сбросить переменную после поиска? это будет намного легче, чем боль, которую вы пытаетесь причинить себе, обновит скрипт test-export
VH
Я дал альтернативный способ сделать это Tarrsalah
VH
ОК, окончательные обновления - проблемы с предлагаемым методом и обходные пути, возможно, будет хорошим выходом для идеи псевдонима bashrc
VH
22

казнить

set -o allexport

Любые переменные, которые вы получите из файла после этого, будут экспортированы в вашу оболочку.

source conf-file

Когда вы закончите, выполните. Это отключит режим allexport.

set +o allexport
mdornfe1
источник
7
Весь вопрос в том, «Как экспортировать без источника». Этот ответ использует источник.
Гонен я
@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
Gonmator
источник
Вы уверены, что то, что вы написали, работает !? Я считаю, что вы должны выполнить командную строку:. ./export.bash
Сэр Джо Блэк
@ Сэр Джо Блэк, да, конечно. Последняя строка файла export.bash вызывается bashкак дочерняя для текущей оболочки. И так как ранее VARбыл экспортирован, этот вызов будет включать переменную. Конечно, если вы наберете выйдет. Вы проверяли? exitVAR
Gonmator
Хорошо! Я не видел этот призыв ...: p
Сэр Джо Блэк
1

Ответ - нет, но для меня я сделал следующее

скрипт: myExport

#! \bin\bash
export $1

псевдоним в моем .bashrc

alias myExport='source myExport' 

Тем не менее, вы получаете его, но, возможно, таким образом, он более полезен и интересен для кого-то еще.

Malcomar
источник
1

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

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

Из-за использования переменной снаружи, вы можете избежать записи скриптового файла.

zhi.yang
источник