假设我有这个脚本:
出口.bash:
#! /usr/bin/env bash
export VAR="HELLO, VARIABLE"
当我执行脚本并尝试访问 $VAR
时,我没有得到任何价值!
echo $VAR
有没有办法通过只执行 export.bash 而不获取它来访问 $VAR
?
source
或 eval
或 ...)
man source
将不起作用,因为 source
内置在 bash 中,您需要运行 help source
有什么方法可以通过执行 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 中的设置(以及您建立的所有其他设置和历史记录)。
为了首先导出 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 作业,我会像下面的控制台一样添加它...对于命令部分仍然值得怀疑:这是从 shell 运行的方式:
在您的命令提示符下(只要 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 file:
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
}
Source 您的 .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
执行
set -o allexport
在此之后您从文件中获取的任何变量都将导出到您的 shell 中。
source conf-file
完成后执行。这将禁用 allexport 模式。
set +o allexport
我发现了一种从文件中导出环境变量的有趣而简洁的方法:
在文件 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
另一种解决方法,视情况而定,它可能很有用:创建另一个继承导出变量的 bash 脚本。它是 Keith Thompson's answer 的一个特例,将所有这些缺点。
文件导出.bash:
# !/bin/bash
export VAR="HELLO, VARIABLE"
bash
现在:
./export.bash
echo $VAR
. ./export.bash
bash
作为当前 shell 的子级。并且由于之前已导出 VAR
,因此该调用将包含该变量。当然,如果您键入 exit
,则 VAR
将熄灭。你检查过吗?
答案是否定的,但对我来说,我做了以下
剧本:
我的出口
#! \bin\bash
export $1
我的 .bashrc file 中的别名:
alias myExport='source myExport'
您仍然source它,但也许这样它更有用并且对其他人来说很有趣。
也许你可以在 ~/.zshrc 或 ~/.bashrc 中添加一个函数。
# set my env
[ -s ~/.env ] && export MYENV=`cat ~/.env`
function myenv() { [[ -s ~/.env ]] && echo $argv > ~/.env && export MYENV=$argv }
由于使用了外部变量,可以避免使用脚本文件。
我认为这无法做到,但我找到了使用 alias
的解决方法。仅当您将脚本放在脚本目录中时,它才会起作用。否则,您的别名将具有无效名称。
解决方法的唯一要点是能够在具有相同名称的文件中拥有一个函数,并且在使用它之前不必费心寻找它。将以下代码添加到文件 ~/.bashrc
:
alias myFunction='unalias myFunction && . myFunction && myFunction "$@"'
您现在可以先调用 myFunction
而无需先调用 sourcing。
这种解决方法以某种方式暗示到其他地方,但可能不是那么清楚:
在您的脚本中,设置变量后,启动一个新的 shell,而不是返回。
我的用例是我打开了许多终端,其中一些我想要一些变量的值,而在另一些我想要其他值。
由于使用 source
可能更难记住,这种方法的一个小优势是当您需要一段时间才能意识到您忘记使用 source
,并且您必须从头开始。
(对我来说,使用 source script
更有意义,因为缺失的变量会立即被发现。)
我在 rsync 中由选项 -e 调用的脚本中调用 ssh-agent -s 时遇到了类似的问题。
在脚本 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 的脚本必须由源(源 backup.sh)调用。
我知道这不是问题(我使用两次源),但是如果有人对 rsync 有类似问题,我会放在这里。
不定期副业成功案例分享
exec "$@"
和printenv
的第三种方法?另外,在脚本需要一些参数的情况下,如何使用第 2 和第 3 方法?sudo . dd.sh $source $pathToUsb
command not found 或eval "$(sudo dd.sh $source $pathToUsb)"
sh: 1: eval: File: not found sh: 2: eval: File: not found 或如果尝试./dd.sh $source $pathToUsb printenv | grep line
can't exec "@" 。有任何想法吗 ?.
命令内置在 shell 中,因此对sudo
不可见。您的第二个命令将尝试eval
sudo dd.sh ...
命令的 输出,我不知道该输出是什么样的。dd.sh
是否打印可以由 shell 评估的命令?printenv
,它仅受环境变量的影响。但是,如果您调用交互式 shell 而不是printenv
,那么您将拥有一个新的 shell 进程,它不会继承当前 shell 的历史记录(可能通过$HISTFILE
除外)、未导出的变量、后台作业等。