我可以从Bash脚本导出一个变量到环境中而不需要获取它吗?

假设我有这样的脚本:

export.bash:

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

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

echo $VAR

是否有一种方法可以通过只执行export.bash而不提供源代码来访问$VAR ?

445549 次浏览

为了先导出VAR变量,最合理、最合适的工作方式是对变量进行source:

. ./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作业而言,我会像下面这样将它添加到控制台…对于命令部分仍然有问题:下面是你如何从你的shell运行:

在您的命令提示符(只要导出。bash 文件有多个回显值)

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

现在,只要这是为你的使用-你可以让变量在任何时候为你的脚本可用,做一个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 !

文件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

脚本:

文件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

是否有任何方法可以通过只执行export.bash而不提供源代码来访问$VAR ?

快速回答:不。

但也有几种可能的变通办法。

最明显的一个,你已经提到过,是使用source.在调用shell的上下文中执行脚本:

$ 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中的设置(以及您已建立的所有其他设置和历史)。

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

脚本:

myExport

#! \bin\bash
export $1

. bashrc文件中的别名:

alias myExport='source myExport'

你仍然它,但也许这样它更有用,对其他人来说是有趣的。

另一种变通方法(取决于具体情况)可能很有用:创建另一个继承导出变量的bash脚本。这是基斯·汤普森的回答的一个特殊情况,将所有这些缺点。

文件export.bash:

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

现在:

./export.bash
echo $VAR

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

在文件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

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

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

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

执行

set -o allexport

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

source conf-file

当你完成时执行。这将禁用alleexport模式。

set +o allexport

我不认为这可以做到,但我找到了一个使用alias的解决方案。只有当您将脚本放在scripts目录中时,它才会工作。否则,您的别名将具有无效的名称。

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

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

你现在可以在没有采购的情况下调用myFunction

这个变通方法在其他地方也有暗示,但可能不是那么清楚:

在你的脚本中,设置变量开始一个新shell后,而不是返回。

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

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

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

我有类似的问题调用ssh-agent -s在rsync的选项-e调用的脚本。

在脚本中,eval $(ssh-agent -s)不为下一次调用保留环境变量。

rsync -e 'source ssh-check-agent.sh -p 8022'不起作用,所以我做了一个变通方案。在脚本中,我在调用ssh-agent后将变量保存在一个临时文件中,如下:

echo "export SSH_AUTH_SOCK=$SSH_AUTH_SOCK;" > /tmp/ssh-check-agent.vars
echo "export SSH_AGENT_PID=$SSH_AGENT_PID;" >> /tmp/ssh-check-agent.vars

然后在调用rsync (backup.sh)的脚本中调用:

source /tmp/ssh-check-agent.vars

问题是调用rsync的脚本必须由source (source backup.sh)调用。

我知道这不是问题(我使用两次源),但如果有人在rsync上有类似的问题,我在这里放了。

使用脚本文件导出环境变量

< p > <强>问题:< / >强
当您运行一个脚本时,它在子shell中执行,并在执行后返回到父shell。导出变量只适用于子shell,不能将子shell的变量导出回父shell < p > <强>解决方案:< / >强
从你的脚本文件中调用一个带有你想要导出的变量的子shell,这将创建一个新的子shell,并导出你的变量

script.sh

bash -c 'export VAR=variable; exec bash'

:: ciph3r

Export Variables using script

简单幼稚的方法有效:

脚本1:

echo "something" > /tmp/myvar

脚本2:

myvar=$(cat /tmp/myvar)