Linux 在不重启 Ubuntu 的情况下全局设置环境变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8677504/
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
Setting environment variable globally without restarting Ubuntu
提问by Abhijeet Pathak
I know that system wide environment variables can be set by adding entries into
我知道可以通过将条目添加到系统范围内来设置环境变量
/etc/environment
or
或者
/etc/profile
But that requires system restart or X restart.
但这需要系统重启或 X 重启。
Is it possible to set an environment variable in Ubuntu / Linux so that immediately available system wide without restarting OS or logging out the user?
是否可以在 Ubuntu / Linux 中设置一个环境变量,以便在不重新启动操作系统或注销用户的情况下立即可用的系统范围?
采纳答案by Vorsprung
This perl program uses gdb to change the USER variable in all currently running bash shells to whatever is given as the program arg. To set a new variable the internal bash call "set_if_not" could be used
这个 perl 程序使用 gdb 将所有当前正在运行的 bash shell 中的 USER 变量更改为作为程序 arg 给出的任何变量。要设置新变量,可以使用内部 bash 调用“set_if_not”
#!/usr/bin/perl
use strict;
use warnings;
my @pids = qx(ps -C bash -o pid=);
my $foo = $ARGV[0];
print "changing user to $foo";
print @pids;
open( my $gdb, "|gdb" ) || die "$! gdb";
select($gdb);
$|++;
for my $pid ( @pids ) {
print "attach $pid\n";
sleep 1;
print 'call bind_variable("USER","' . $foo . '",0)' . "\n";
sleep 1;
print "detach\n";
}
This onlyworks with bash ( I onlytested it with version 4.1 on Ubuntu 10.04 LTS) and does not alter the environment for arbitrary already running programs. Obviously it must be run as root.
这仅适用于 bash(我仅在 Ubuntu 10.04 LTS 上使用 4.1 版对其进行了测试)并且不会改变任意已运行程序的环境。显然,它必须以 root 身份运行。
回答by earl
The simple answer is: you cannotdo this in general.
简单的答案是:一般情况下你不能这样做。
Why can there be no general solution?
为什么不能有通用的解决方案?
The "why?" needs a more detailed explanation. In Linux, the environment is process-specific. Each process environment is stored in a special memory area allocated exclusively for this process.
“为什么?” 需要更详细的解释。在 Linux 中,环境是特定于进程的。每个进程环境都存储在专门为此进程分配的特殊内存区域中。
As an aside: To quickly inspect the environment of a process, have a look at
/proc/<pid>/env
(or try/proc/self/env
for the environment of the currently running process, such as your shell).
顺便说一句:要快速检查进程的环境,请查看
/proc/<pid>/env
(或尝试/proc/self/env
查看当前正在运行的进程的环境,例如您的 shell)。
When a ("parent") process starts another ("child") process (via fork(2)
), the environment the environment of the parent is copiedto produce the environment of the child. There is no inheritance-style association between those two environments thereafter, they are completely separate. So there is no "global" or "master" environment we could change, to achieve what you want.
当一个(“父”)进程启动另一个(“子”)进程(通过fork(2)
)时,父的环境被复制以产生子的环境。此后这两个环境之间没有继承式关联,它们是完全独立的。所以没有我们可以改变的“全局”或“主”环境来实现你想要的。
Why not simply change the per-process environment of all running processes? The memory area for the environment is in a well-defined location (basically right before the memory allocated for the stack), so you can't easily extend it, without corrupting other critical memory areas of the process.
为什么不简单地更改所有正在运行的进程的每个进程的环境?环境的内存区域位于一个明确定义的位置(基本上就在为堆栈分配的内存之前),因此您无法轻松扩展它,而不会破坏进程的其他关键内存区域。
Possible half-solutions for special cases
特殊情况下可能的半解决方案
That said, one can imagine several special cases where you could indeed achieve what you want.
也就是说,您可以想象几种特殊情况,您确实可以实现您想要的目标。
Most obviously, if you do "size-neutral" changes, you could conceivable patch up all environments of all processes. For example, replace every
USER=foo
environment variable (if present), withUSER=bar
. A rather special case, I fear.If you don't really need to change the environments of all processes, but only of a class of well-known ones, more creative approaches might be possible. Vorsprung's answeris an impressive demonstration of doing exactly this with only Bash processes.
最明显的是,如果您进行“大小中立”更改,则可以想象修补所有进程的所有环境。例如,将每个
USER=foo
环境变量(如果存在)替换为USER=bar
. 一个相当特殊的情况,我担心。如果你真的不需要改变所有进程的环境,而只需要改变一类众所周知的进程,那么更有创意的方法可能是可能的。Vorsprung 的回答令人印象深刻,它仅使用 Bash 进程就可以做到这一点。
There are probably many other special cases, where there is a possible solution. But as explained above: no solution for the general case.
可能还有许多其他特殊情况,其中有可能的解决方案。但如上所述:一般情况没有解决方案。
回答by mlissner
I fear the solution here is a frustrating one: Don't use environment variables. Instead use a file.
我担心这里的解决方案令人沮丧:不要使用环境变量。而是使用文件。
So, instead of setting up /etc/environment with:
因此,不要使用以下命令设置 /etc/environment:
SPECIAL_VAR='some/path/I/want/later/'
And calling it with:
并调用它:
$SPECIAL_VAR
Instead, create a file at ~/.yourvars with the content:
相反,在 ~/.yourvars 中创建一个包含以下内容的文件:
SPECIAL_VAR='some/path/I/want/later/'
And source the thing every time you need the variable:
每次需要变量时都获取源:
cd `source ~/.yourvars; echo $SPECIAL_VAR`
A hack? Perhaps. But it works.
黑客?也许。但它有效。