【问题标题】:Setting environment variable globally without restarting Ubuntu在不重新启动 Ubuntu 的情况下全局设置环境变量
【发布时间】:2012-01-30 10:34:38
【问题描述】:

我知道可以通过添加条目来设置系统范围的环境变量

/etc/environment

/etc/profile

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

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

【问题讨论】:

  • X重启就够了,为什么还要重启系统?
  • 好吧,我不想重新启动系统。这就是重点。
  • 这意味着你不能按照你的要求去做,那么:你将至少必须重新启动 X。你不能改变已经运行的进程的环境。
  • @fge 实际上,您可以,但它需要您使用gdb 附加到进程。它有效,但它非常hackish

标签: linux bash shell ubuntu


【解决方案1】:

简单的答案是:一般不能这样做

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

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

顺便说一句:要快速检查进程的环境,请查看/proc/<pid>/env(或尝试/proc/self/env 查看当前正在运行的进程的环境,例如您的shell)。

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

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

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

也就是说,可以想象几种特殊情况,你确实可以实现你想要的。

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

  • 如果您真的不需要更改所有进程的环境,而只需要更改一类知名进程的环境,则可能会采用更具创造性的方法。 Vorsprung's answer 是一个令人印象深刻的演示,它仅使用 Bash 进程就可以做到这一点。

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 为什么需要root?
    • @osgx 这意味着必须在系统上运行的所有 shell 中更改变量。要更改所有用户的进程,显而易见的做法是成为 root
    • 绝对+1!它可以简化一点。 ps -C bash -o pid= 可用于消除 PID 标题行。然后可以使用@pid 代替@pids[ 1 .. $#pids ]
    • @TrueY 或者我可以shift(@pids) tmtowtdi :)
    • 当然!但不写头文件更有效。而且只需要一个额外的=
    【解决方案3】:

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

    所以,而不是设置 /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`
    

    黑客?可能。但它有效。

    【讨论】:

      猜你喜欢
      • 2016-04-16
      • 2015-10-04
      • 1970-01-01
      • 1970-01-01
      • 2017-12-31
      • 1970-01-01
      • 2019-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多