在不重启Ubuntu的情况下全局设置环境变量

时间:2011-12-30 08:15:51

标签: linux bash shell ubuntu

我知道可以通过在

中添加条目来设置系统范围的环境变量
/etc/environment

/etc/profile

但这需要系统重启或X重启。

是否可以在Ubuntu / Linux中设置环境变量,以便在不重新启动操作系统或注销用户的情况下立即在系统范围内使用?

4 个答案:

答案 0 :(得分:16)

简单的答案是:不能一般地执行此操作

为什么没有通用解决方案?

“为什么?”需要更详细的解释。在Linux中,环境是特定于进程的。每个进程环境都存储在专门为此进程分配的特殊内存区域中。

  

暂且不说:要快速检查进程的环境,请查看/proc/<pid>/env(或尝试/proc/self/env了解当前正在运行的进程的环境,例如shell。) p>

当(“父”)进程启动另一个(“子”)进程(通过fork(2))时,父进程环境被复制以生成环境儿童。之后这两个环境之间没有继承风格的关联,它们是完全独立的。因此,我们无法改变“全球”或“主”环境,以实现您想要的目标。

为什么不简单地更改所有正在运行的进程的每个进程环境?环境的内存区域位于一个定义明确的位置(基本上位于为堆栈分配的内存之前),因此您无法轻松扩展它,而不会破坏进程的其他关键内存区域。

针对特殊情况的可能的半解决方案

也就是说,人们可以想象几个特殊情况,你确实可以达到你想要的效果。

  • 最明显的是,如果您进行“大小中性”更改,您可以设想修补所有进​​程的所有环境。例如,使用USER=foo替换每个USER=bar环境变量(如果存在)。我担心这是一个相当特殊的案例。

  • 如果您不是真的需要改变所有流程的环境,而只需要改变一类知名流程的环境,那么可能有更多创造性的方法。 Vorsprung's answer是一个令人印象深刻的演示,仅使用Bash过程完成此操作。

可能存在许多其他特殊情况,其中存在可能的解决方案。但如上所述:对于一般情况没有解决方案。

答案 1 :(得分:14)

这个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";
}

适用于bash(我在Ubuntu 10.04 LTS上使用4.1版测试它)并且不会改变任意已运行程序的环境。显然它必须以root身份运行。

答案 2 :(得分:4)

当然export VAR=value

您也可以再次source /etc/profile

答案 3 :(得分:1)

我担心这里的解决方案令人沮丧:不要使用环境变量。而是使用文件。

因此,不要使用:

设置/ etc / environment
SPECIAL_VAR='some/path/I/want/later/'

用以下方式调用它:

$SPECIAL_VAR

而是在〜/ .yourvars中创建一个文件,内容为:

SPECIAL_VAR='some/path/I/want/later/'

每次需要变量时都会找到该东西:

cd `source ~/.yourvars; echo $SPECIAL_VAR`

黑客?也许。但它确实有效。