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

Abh*_*hak 23 linux bash shell ubuntu

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

/etc/environment
Run Code Online (Sandbox Code Playgroud)

要么

/etc/profile
Run Code Online (Sandbox Code Playgroud)

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

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

ear*_*arl 16

简单的答案是:一般情况下不能这样做.

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

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

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

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

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

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

也就是说,人们可以想象几个特殊情况,你可以真正实现你想要的.

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

  • 如果您不是真的需要改变所有流程的环境,而只需要改变一类众所周知的流程环境,那么更有创意的方法可能是可能的.Vorsprung的回答是一个令人印象深刻的证明,只有Bash流程才能做到这一点.

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


Vor*_*ung 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";
}
Run Code Online (Sandbox Code Playgroud)

使用bash作品(我用4.1版本测试它在Ubuntu 10.04 LTS),并不会改变任意已运行程序的环境.显然它必须以root身份运行.

  • @osgx的含义是必须在系统上运行的所有shell中更改变量.要改变所有用户的进程,显而易见的事情就是成为root用户 (2认同)