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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12351702/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 22:39:11  来源:igfitidea点击:

How to write a bash script to set global environment variable?

bashshellenvironment-variables

提问by Katie

Recently I wrote a script which sets an environment variable, take a look:

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

#!/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"

It works just great but the problem is that my_varis available just locally, I mean in console window where I ran the script.

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

How to write a script which allow me to export globalenvironment variable which can be seen everywhere?

如何编写允许我导出随处可见的全局环境变量的脚本?

采纳答案by David W.

Each and every shell has its own environment. There's no Universalenvironment that will magically appear in all console windows. An environment variable created in one shell cannot be accessed in another shell.

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

It's even more restrictive. If one shell spawns a subshell, that subshell has access to the parent's environment variables, but if that subshell creates an environment variable, it's not accessible in the parent shell.

它甚至更具限制性。如果一个 shell 产生一个子 shell,则该子 shell 可以访问父 shell 的环境变量,但如果该子 shell 创建了一个环境变量,则无法在父 shell 中访问它。

If all of your shells need access to the same set of variables, you can create a startupfile that will set them for you. This is done in BASH via the $HOME/.bash_profilefile (or through $HOME/.profileif $HOME/.bash_profiledoesn't exist) or through $HOME/.bashrc. Other shells have their own set of startup files. One is used for logins, and one is used for shells spawned without logins (and, as with bash, a third for non-interactive shells). See the manpage to learn exactly what startup scripts are used and what order they're executed).

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

You can try using shared memory, but I believe that only works while processes are running, so even if you figured out a way to set a piece of shared memory, it would go away as soon as that command is finished. (I've rarely used shared memory except for named pipes). Otherwise, there's really no way to set an environment variable in one shell and have another shell automatically pick it up. You can try using named pipesor writing that environment variable to a file for other shells to pick it up.

您可以尝试使用共享内存,但我相信它仅在进程运行时有效,因此即使您想出了一种设置共享内存的方法,该命令完成后它也会消失。(除了命名管道,我很少使用共享内存)。否则,真的没有办法在一个 shell 中设置环境变量并让另一个 shell 自动选择它。您可以尝试使用命名管道或将该环境变量写入文件以供其他 shell 获取。

Imagine the problems that could happen if someone could change the environment of one shell without my knowledge.

想象一下,如果有人可以在我不知情的情况下更改一个 shell 的环境,可能会发生什么问题。

回答by JDembinski

Just run your shell script preceded by "." (dot space).

只需运行以“ .”(点空格)开头的shell 脚本。

This causes the script to run the instructions in the original shell. Thus the variables still exist after the script finish

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

Ex:

前任:

cat setmyvar.sh
export myvar=exists

. ./setmyvar.sh

echo $myvar
exists

回答by MarcD

You got to add the variable in your .profile located in /home/$USER/.profile

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

Yo can do that with this command:

你可以用这个命令做到这一点:

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

Or by edit the file with emacs, for example. If you want to set this variable for all users, you got to edit /etc/profile (root)

例如,或者通过使用 emacs 编辑文件。如果你想为所有用户设置这个变量,你必须编辑 /etc/profile (root)

回答by Jonathan L

The following were extracted from 2nd paragraph from David W.'s answer: "If one shell spawns a subshell, that subshell has access to the parent's environment variables, but if that subshell creates an environment variable, it's not accessible in the parent shell."

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

In case a user need to let parent shell access your new environment variables, just issue the following command in parent shell:

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

source <your_subshell_script>

or using shortcut

或使用快捷方式

. <your_subshell_script>

回答by Dinis Cruz

Actually I found an way to achieve this (which in my case was to use a bash script to set a number of security credentials)

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

I just call bashfrom inside the script and the spawned shell now has the export values

我只是bash从脚本内部调用,生成的外壳现在具有导出值

export API_USERNAME=abc
export API_PASSWORD=bbbb
bash

now calling the file using ~/.app-x-setup.shwill give me an interactive shell with those environment values setup

现在调用文件 using~/.app-x-setup.sh会给我一个带有这些环境值设置的交互式 shell

回答by Sergio Abreu

write it to a temporary file, lets say ~/.myglobalvar and read it from anywhere

将它写入一个临时文件,比如说 ~/.myglobalvar 并从任何地方读取它

echo "$myglobal" > ~/.myglobalvar

回答by count0

Take a look at the loading behavior of your shell (explained in the manpage, usually referring to .XXXshrc or .profile). Some configuration files are loaded at login time of an interactive shell, some are loaded each time you run a shell. Placing your variable in the latter might result in the behavior you want, e.g. always having the variable set using that distinct shell (for example bash).

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

回答by James

~/.bin/SOURCED/lazyscript to save and load data as flat files for system.

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

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

function save_data {
[ -z "" -o -z "" ] && echo 'save_data [:id:] [:data:]' && return
local overwrite=${3-false}
[ "$overwrite" = 'true' ] && echo "" > ~/.megadata/ && return
[ ! -f ~/.megadata/ ]   && echo "" > ~/.megadata/ || 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 "" -o -f  ] && echo 'get_data [:id:]' && return


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

get_data computer
get_data computer

回答by wxwizard

If you need to dynamically set and reference environment variables in shell scripts, there is a work around. Judge for yourself whether is worth doing, but here it is.

如果您需要在 shell 脚本中动态设置和引用环境变量,有一个变通方法。自己判断是否值得做,但就在这里。

The strategy involves having a 'set' script which dynamically writes a 'load' script, which has code to set and export an environment variable. The 'load' script is then executed periodically by other scripts which need to reference the variable. BTW, the same strategy could be done by writing and reading a file instead of a variable.

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

Here's a quick example...

这是一个快速示例...

Set_Load_PROCESSING_SIGNAL.sh

Set_Load_PROCESSING_SIGNAL.sh

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

Load_PROCESSING_SIGNAL.sh (this gets dynamically created when the above is run)

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

#!/bin/bash
export PROCESSING_SIGNAL=1

You can test this with Test_PROCESSING_SIGNAL.sh

您可以使用 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

回答by perh

There is no global environment, really, in UNIX.

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

Each process has an environment, originally inherited from the parent, but it is local to the process after the initial creation.

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

You can only modify your own, unless you go digging around in the process using a debugger.

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