如何编写bash脚本来设置全局环境变量?

时间:2012-09-10 12:26:19

标签: bash shell environment-variables

最近我编写了一个设置环境变量的脚本,看看:

#!/bin/bash

echo "Pass a path:"
read path
echo $path

defaultPath=/home/$(whoami)/Desktop

if [ -n "$path" ]; then
    export my_var=$path
else
    echo "Path is empty! Exporting default path ..."
    export my_var=$defaultPath
fi

echo "Exported path: $my_var"

它工作得很好,但问题是my_var只在本地可用,我的意思是在我运行脚本的控制台窗口中。

如何编写一个允许我导出全局环境变量的脚本,这个变量可以在任何地方看到?

13 个答案:

答案 0 :(得分:85)

只需运行您的shell脚本,前面带有" ." (点空间)。

这会导致脚本运行原始shell中的指令。因此,在脚本完成后,变量仍然存在

例如:

cat setmyvar.sh
export myvar=exists

. ./setmyvar.sh

echo $myvar
exists

答案 1 :(得分:35)

每个shell都有自己的环境。没有通用环境可以神奇地出现在所有控制台窗口中。在一个shell中创建的环境变量无法在另一个shell中访问。

它更具限制性。如果一个shell生成一个子shell,那个子shell可以访问父的环境变量,但如果该子shell创建了一个环境变量,那么它在父shell中是不可访问的。

如果所有shell都需要访问同一组变量,则可以创建一个启动文件,为您设置它们。这是通过$HOME/.bash_profile$HOME/.bashrc文件在BASH中完成的,如果$HOME/.profile不存在则通过$HOME/.bash_profile完成。其他shell有自己的一组启动文件。一个用于登录,一个用于生成没有登录的shell。请参阅联机帮助页以了解确切使用的启动脚本以及执行的顺序。

你可以尝试使用共享内存,但我相信只有在进程运行时才有效,所以即使你找到了设置一块共享内存的方法,它也会在命令完成后立即消失。 (除了命名管道,我很少使用共享内存)。否则,实际上没有办法在一个shell中设置环境变量,并让另一个shell自动获取它。您可以尝试使用named pipes或将该环境变量写入文件以供其他shell使用。

想象一下如果有人在我不知情的情况下改变一个shell的环境就可能发生的问题。

答案 2 :(得分:2)

你必须在位于/home/$USER/.profile的.profile中添加变量

Yo可以使用此命令执行此操作:

echo 'TEST="hi"' >> $HOME/.profile

或者通过使用emacs编辑文件。 如果要为所有用户设置此变量,则必须编辑/ etc / profile(root)

答案 3 :(得分:2)

以下内容摘自David W.回答的第2段:“如果一个shell生成一个子shell,那个子shell可以访问父级的环境变量,但如果该子shell创建了一个环境变量,那么它就无法访问父贝壳。“

如果用户需要让父shell访问新的环境变量,只需在父shell中发出以下命令:

source <your_subshell_script>

或使用快捷方式

. <your_subshell_script>

答案 4 :(得分:1)

在UNIX中,确实没有全局环境。

每个进程都有一个最初从父进程继承的环境,但它在初始创建后是进程的本地环境。

除非您使用调试器在此过程中进行挖掘,否则您只能修改自己的。

答案 5 :(得分:1)

环境变量始终是“本地”的流程执行,导出命令允许为子流程设置环境变量。您可以查看.bashrc以在bash shell的开头设置环境变量。您尝试做的似乎不可能,因为进程无法修改(或访问?)另一个进程的环境变量。

答案 6 :(得分:1)

您可以更新用于初始化环境的〜/ .bashrc或〜/ .bash_profile文件。

答案 7 :(得分:1)

看一下shell的加载行为(在联机帮助页中解释,通常是指.XXXshrc或.profile)。某些配置文件在交互式shell的登录时加载,有些配置文件在每次运行shell时都会加载。将变量放在后者中可能会导致您想要的行为,例如:总是使用不同的shell设置变量(例如bash)。

答案 8 :(得分:1)

~/.bin/SOURCED/lazy脚本将数据保存并加载为系统的平面文件。

[ ! -d ~/.megadata ] && mkdir ~/.megadata

function save_data {
[ -z "$1" -o -z "$2" ] && echo 'save_data [:id:] [:data:]' && return
local overwrite=${3-false}
[ "$overwrite" = 'true' ] && echo "$2" > ~/.megadata/$1 && return
[ ! -f ~/.megadata/$1 ]   && echo "$2" > ~/.megadata/$1 || echo ID TAKEN set third param to true to overwrite
}

save_data computer engine
cat ~/.megadata/computer
save_data computer engine
save_data computer megaengine true

function get_data {
[ -z "$1" -o -f $1 ] && echo 'get_data [:id:]' && return


[ -f ~/.megadata/$1 ]   && cat ~/.megadata/$1 || echo ID NOT FOUND
:
}

get_data computer
get_data computer

答案 9 :(得分:1)

如果需要在shell脚本中动态设置和引用环境变量,可以解决这个问题。判断自己是否值得做,但现在就是。

该策略涉及一个“set”脚本,该脚本动态编写一个“load”脚本,该脚本具有设置和导出环境变量的代码。然后,“load”脚本由需要引用变量的其他脚本定期执行。顺便说一句,同样的策略可以通过编写和读取文件而不是变量来完成。

这是一个简单的例子......

Set_Load_PROCESSING_SIGNAL.sh

#!/bin/bash
PROCESSING_SIGNAL_SCRIPT=./Load_PROCESSING_SIGNAL.sh
echo "#!/bin/bash" > $PROCESSING_SIGNAL_SCRIPT
echo "export PROCESSING_SIGNAL=$1" >> $PROCESSING_SIGNAL_SCRIPT
chmod ug+rwx $PROCESSING_SIGNAL_SCRIPT

Load_PROCESSING_SIGNAL.sh(在运行上述内容时动态创建)

#!/bin/bash
export PROCESSING_SIGNAL=1

你可以测试一下 Test_PROCESSING_SIGNAL.sh

#!/bin/bash
PROCESSING_SIGNAL_SCRIPT=./Load_PROCESSING_SIGNAL.sh
N=1
LIM=100
while [ $N -le $LIM ]
do
# DO WHATEVER LOOP PROCESSING IS NEEDED
echo "N = $N"
sleep 5
N=$(( $N + 1 ))

# CHECK PROCESSING_SIGNAL
source $PROCESSING_SIGNAL_SCRIPT
if [[ $PROCESSING_SIGNAL -eq 0 ]]; then
# Write log info indicating that the signal to stop processing was detected
# Write out all relevent info
# Send an alert email of this too
# Then exit
echo "Detected PROCESSING_SIGNAL for all stop. Exiting..."
exit 1
fi
done

答案 10 :(得分:1)

将其写入临时文件,让我们说〜/ .myglobalvar并从任何地方读取

echo "$myglobal" > ~/.myglobalvar

答案 11 :(得分:1)

实际上我找到了一种方法来实现这一点(在我的例子中是使用bash脚本来设置一些安全凭证)

我只是从脚本内部调用bash,而衍生的shell现在具有导出值

export API_USERNAME=abc
export API_PASSWORD=bbbb
bash

现在使用~/.app-x-setup.sh调用该文件将为我提供一个包含这些环境值设置的交互式shell

答案 12 :(得分:0)

也许有点跑题,但是当你真的需要临时设置它来执行一些脚本并最终在这里寻找答案时:

如果您需要使用某些在执行后不需要保留的环境变量来运行脚本,您可以执行以下操作:

#!/usr/bin/env sh

export XDEBUG_SESSION=$(hostname);echo "running with xdebug: $XDEBUG_SESSION";$@

在我的示例中,我只使用带有主机名的 XDEBUG_SESSION,但您可以使用多个变量。用分号将它们分开。执行如下(假设你调用了脚本 debug.sh 并将其与你的 php 脚本放在同一目录下):

$ debug.sh php yourscript.php