LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1323|回复: 7

再问修改环境变量的问题

[复制链接]
发表于 2004-5-15 06:38:51 | 显示全部楼层 |阅读模式
上次我发贴问过一次有关修改环境变量的问题,虽然答案并不满意,不过因为并没有遇到什么实际问题,所以也没太在意。这此发贴问的是同一个问题,不知道到底有没有什么可以解决的法子。

例如一个用户创建了一个环境变量:
export TERMCMD=xterm
然后该用户startx进入x,我的问题是有没有办法在不退出x的前提下修改该环境变量,并使该变量立刻生效?

javalee在我上张贴子里回复说在/etc/profile中写变量

“修改配置文件后直接执行
. /etc/profile
那么这是的全局环境变量立即生效,而不用从新启动/注消重启”

原始贴子见:
http://www.linuxsir.cn/forum.php ... 7%BE%B3%B1%E4%C1%BF

我并没有去尝试是否有效,因为这样的办法即使有效,也解决不了什么问题。环境变量可以写在/etc下的某个文件里,也可能是用户配置文件如~/.bashrc里,又或者是直接在命令行下创建和修改的。我想这个问题可能会牵涉到进程通信或消息广播之类的概念,哪位大虾可以支个招呢?
发表于 2004-5-15 09:07:48 | 显示全部楼层
其实javalee兄说得对啊,为什么兄弟你觉得没有用呢?更何况你没有去尝试过。
在解释前先声明一点,我们这个版区,顾名思义,讨论的大前提是shell,而不是程序设计。

通常情况下,在标准文件描述器中与进程相关的终端就是该进程及其会话的控制终端。众所周知,每个终端上运行一个shell,控制终端也不例外(比如说,你在xterm里运行一个命令,shell产生一个进程来执行该命令,对该进程而言,这个shell就是它的控制终端)。控制终端的shell不但控制着其管辖进程的文件描述符,而且也是信号收集器,更是环境配置者,当然就包括环境变量的设置了。
环境变量只能由父进程继承给子进程。这是值得注意的,我们经常会犯这样的错误,比如,在shell里运行export命令声明一个环境变量,这对于其管辖进程是有效的,但对于另一个shell组长而言则不可见(打开一个xterm创建一个新组长);又比如说,在一个子进程如脚本里export一个环境变量,但对于组长乃至其他管辖进程又不可见。这就是兄弟的设置环境变量的错误根源。

至于bash的配置文件究竟是如何工作的。我在此再说一遍。
1. /etc/profile是交互式登录shell的全局配置文件,~/.bash_profile是相应的个人配置文件,后者的运行优先级高于前者
2. /etc/bashrc是交互式非登录shell的全局配置文件,~/.bashrc是相应的个人配置文件,后者的优先级别高于前者

系统启动后,打开一个tty,在其上产生一个登录进程login,用户登录后就会为其运行一个shell,这时候先执行/etc/profile,然后执行~/.bash_profile;在其后,用户自行创建一个交互式shell,注意,和profile不同,如果存在~/.bashrc,则执行它而不执行/etc/bashrc。
另外,有一点例外,如果使用kdm等x显示管理器来进行登录,则可能不会执行/etc/profile,比如debian,这时候要自己在相应的x配置文件里调用/etc/profile。


好了,回到你的问题上。
1.环境变量的设置与进程通信以及信息传递无关,无论设置的方式如何多样,都是由shell即控制终端所管理
2.要在x下设置环境变量,如果是debian,则在/etc/environment文件进行设置,如果是其它发行版本,如redhat,则在/etc/profile以及~/.bashrc里加入即可
3.正因为环境变量是上传下的,所以只要我们在/etc/profile等配置文件里设置好了,也就是说,在最老的控制终端上设置好了,那么以后它产生的进程乃至控制终端都可以继承环境变量了。注意,不可能改变父进程的环境变量,只能在某子进程里屏蔽而已。当然,x另当别论,请看上面的论述。

ps:
1.既然我们玩linux,就应该遵守linux的游戏规则
2.在unix的c语言里,用标准库函数char *getenv(const char *name)来获取环境变量;
当附加环境变量运行一个程序时,即ENVNAME=VALUE command的形式。
实际的程序中一般用exec家族函数来执行命令,如execve("./myscript",argv,envp)
 楼主| 发表于 2004-5-16 23:08:39 | 显示全部楼层
呵呵,说我不守规矩。。。。。
其实不守规矩有时候也并不是太坏的事情吧;p

我说javalee的法子对我的问题没啥意义,贴子里已经说明了啊。环境变量有可能在任何一个配置文件里设置,而且还有可能写在if或case块里面,甚至有可能是配置脚本中执行source命令建立的,所以几乎没可能写一个脚本去检查甚至修改某个环境吧?
其实我的问题就是“子进程”有没有可能修改“父进程”的环境变量,或者是X中能不能修改环境变量并立刻生效,跟环境变量应该设在什么地方一点关系都没。
兄台说“不可能改变父进程的环境变量,只能在某子进程里屏蔽而已。当然,x另当别论”,但我没太明白,不知道能不能具体说说?
这样干说好像很难沟通,我再举个实际的例子。比如X的输入法需要设置一个环境变量XIM,并且需要执行输入法的可执行文件。有没有什么法子可以在不退出X的前提下换另外一种输入法呢?

至于说shell或程序设计,其实我分不太清说。[也是个可执行文件,而且shell的语法其实不也很“程序设计”么。有什么应用现存命令和shell无法很好完成,写 个简单的程序也没什么吧。
发表于 2004-5-16 23:32:48 | 显示全部楼层
呵呵,说我不守规矩。。。。。
其实不守规矩有时候也并不是太坏的事情吧;p

嗯,不守规矩有时可能也是一个机遇未定

我说javalee的法子对我的问题没啥意义,贴子里已经说明了啊。环境变量有可能在任何一个配置文件里设置,而且还有可能写在if或case块里面,甚至有可能是配置脚本中执行source命令建立的,所以几乎没可能写一个脚本去检查甚至修改某个环境吧?

每个命令在执行自身时,都会检查自己需要的环境变量的值,正如exec函数所示。

其实我的问题就是“子进程”有没有可能修改“父进程”的环境变量,或者是X中能不能修改环境变量并立刻生效,跟环境变量应该设在什么地方一点关系都没。

建议兄弟参阅一下Debian系统的/etc/environment。这个文件修改后立即生效,作用域是整个系统,比如说可以在修改/etc/environment里的XIM值后无须重启X即可切换另一种输入法。
我先买个关子,兄弟自己去查阅一下关于/etc/environment的资料,它的原理就是兄弟所要的答案。
 楼主| 发表于 2004-5-16 23:34:12 | 显示全部楼层
老大啊,你不可能让我为了查这个东西去装个debian吧
发表于 2004-5-16 23:38:37 | 显示全部楼层
最初由 800 发表
老大啊,你不可能让我为了查这个东西去装个debian吧

呵呵,我说的是理解它的原理,查阅资料而非装Debian系统。
其实严格来说也不必重启X啊,注销即可。
 楼主| 发表于 2004-5-17 00:02:43 | 显示全部楼层
论坛的搜索狂菜,google我又不知道该搜虾米。刚这会找到的也就这个,没提啥啊:

http://www.unet.univie.ac.at/aix/files/aixfiles/environment.htm

也就这么一句“Any processes that were started prior to the change to the /etc/environment file must be restarted if the change is to take effect for those processes.”
发表于 2004-5-17 00:07:20 | 显示全部楼层
没错啊。这篇文章提及了两点。
1./etc/environment是系统级环境配置文件
2.重新运行一个进程后,它就会更新自身那些/etc/environment包含的环境变量定义

ps: Debian玩家有福气,呵呵。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表