398

假设我有这个脚本:

出口.bash

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

当我执行脚本并尝试访问 时$VAR,我没有得到任何价值!

echo $VAR

有没有办法$VAR通过只执行export.bash而不采购它来访问它?

4

9 回答 9

430

有没有什么方法可以$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

最后一种方法可能非常有用,尽管它不方便交互式使用,因为它没有为您提供当前 shell 中的设置(以及您建立的所有其他设置和历史记录)。

于 2013-05-17T23:36:24.763 回答
77

为了首先导出 VAR 变量,最合乎逻辑和最可行的方法是获取变量:

. ./export.bash

或者

source ./export.bash

现在,当从主 shell 回显时,它可以工作:

echo $VAR
HELLO, VARIABLE

我们现在将重置 VAR:

export VAR=""
echo $VAR

现在我们将执行一个脚本来获取变量然后取消设置它:

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

代码:文件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文件,您可以随时执行上述操作...

无论如何回到它的其余部分......

这使它在全球范围内可用,然后执行脚本......

只需将其回显并在回显上运行导出!

文件导出.bash

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

现在在脚本或您的控制台中运行:

export "$(./export.bash)"

尝试:

echo $VAR
HELLO THERE

多个值,只要您知道使用上述方法在另一个脚本中的期望:

文件导出.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

剧本:

文件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
于 2013-05-17T21:32:51.613 回答
38

执行

set -o allexport

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

source conf-file

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

set +o allexport
于 2018-06-04T04:39:29.873 回答
19

我发现了一种从文件中导出环境变量的有趣而简洁的方法:

在文件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. "--" stops processing options,
# key=value list given as parameters
export -- `cat env.vars`
echo $foo         # => test
sh -c 'echo $foo' # => test
于 2015-12-27T08:32:31.070 回答
9

另一种解决方法,视情况而定,它可能很有用:创建另一个继承导出变量的 bash 脚本。这是基思汤普森回答的一个特例,将所有这些缺点。

文件导出.bash:

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

现在:

./export.bash
echo $VAR
于 2015-12-08T14:44:39.510 回答
2

答案是否定的,但对我来说,我做了以下

剧本:

我的出口

#! \bin\bash
export $1

我的.bashrc 文件中的别名:

alias myExport='source myExport'

您仍然可以获取它,但也许以这种方式它更有用,并且对其他人来说很有趣。

于 2015-01-09T10:04:41.977 回答
2

也许您可以在~/.zshrc~/.bashrc中添加一个函数。

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

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

于 2016-05-21T14:32:21.223 回答
0

我不认为这是可以做到的,但我找到了使用alias. 仅当您将脚本放在脚本目录中时,它才会起作用。否则,您的别名将具有无效名称。

解决方法的唯一要点是能够在具有相同名称的文件中拥有一个函数,并且在使用它之前不必费心寻找它。将以下代码添加到文件中~/.bashrc

alias myFunction='unalias myFunction && . myFunction && myFunction "$@"'

您现在可以myFunction在不先获取它的情况下进行调用。

于 2021-01-09T00:27:54.363 回答
0

这种解决方法以某种方式暗示到其他地方,但可能不是那么清楚:

在您的脚本中,设置变量后,启动一个新的 shell,而不是返回。

我的用例是我打开了许多终端,其中一些我想要一些变量的值,而在另一些我想要其他值。

由于 usingsource可能更难记住,这种方法的一个小优点是当您需要一段时间才能意识到您忘记使用source,并且您必须从头开始。

(对我来说,使用 更有意义source script,因为丢失的变量会立即被发现。)

于 2022-01-08T08:20:18.670 回答