我可以在不采购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。
tarrsalah

好了,您可以将信息写到文件中,然后再读回,但是采购似乎要容易得多。
jdigital

7
子进程无法更改其父级的环境。父母必须选择改变自己(用sourceeval或...)
格伦·杰克曼

1
要在源上阅读更多内容,man source因为sourcebash内置了该内容,将无法正常工作,您需要运行help source
peterchaula

Answers:


318

有什么方法可以$VAR通过执行export.bash而无需采购它来进行访问?

快速回答:不可以。

但是,有几种可能的解决方法。

您已经提到的最明显的一个是在调用shell的上下文中使用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文件,您可以随时执行上述操作...

无论如何回到其余的部分。

这样就可以全局使用它,然后执行脚本。

只需将其回显,然后对echo运行export即可!

猫出口

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

@vahid,您应该解释脚本的功能。
FDinoff

1
为什么在采购后不取消设置变量?它比您尝试造成的痛苦要容易得多,它会更新测试导出脚本
VH

我提供了另一种替代方法Tarrsalah
VH

好的最终更新-建议的方法和解决bashrc别名问题的方法可能是一个不错的方法
VH

22

执行

set -o allexport

此后从文件中获取的任何变量都将导出到您的Shell中。

source conf-file

完成后,执行。这将禁用allexport模式。

set +o allexport

7
问题的全部重点是“如何在没有源的情况下导出”。该答案使用源。
Gonen I

@ekkis是的,它并不能完全回答问题,但是每当我用谷歌搜索如何从文件中导出变量时,都会出现此线程。所以我有点把它放在那里。
mdornfe1

简单易用。这应该标记为答案。
QkiZ

1
我赞成这一点,因为最初的问题陈述使我理解这是我的基本解决方案。这里有关于allexport的官方文档:gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
将于

啊,+ 1。这个问题是bash source exportGoogle 关键字的最高结果
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
布莱克爵士(Sir Jo Black)

@布莱克爵士,是的,当然。export.bash文件的最后一行bash作为当前shell的子级调用。由于VAR之前已导出,因此该调用将包含该变量。当然,如果你输入exitVAR熄灭。你检查了吗
Gonmator

好!我还没有看到这样的调用...: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 }

由于外部使用变量,可以避免编写脚本文件。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.