导出一个env变量以在所有子shell上可用,并且可以对其进行修改吗?


22

假设我有

export MY_VAR=0

~/.bashrc

我有一个打开的gnome终端,在这个终端中,我将$MY_VARvalue 更改为200。所以,如果我愿意

echo $MY_VAR

显示在此终端200中。

现在,我在gnome终端中打开了另一个标签,然后执行

echo $MY_VAR

...而不是200,我有0

当终端修改环境变量,并使此修改(设置为200)可用于所有后续子shell等时,我该怎么做才能保持200的值?这可能吗?

Answers:


23

环境的副本传播到子外壳,因此可以正常工作:

$ export MY_VAR=200
$ bash
$ echo $MY_VAR
200

但是由于它是一个副本,因此您无法通过父外壳获得该值-至少不通过更改环境即可。

听起来您实际上想更进一步,那就是使行为类似于全局变量,由独立于父级启动的“同级” shell共享,例如Gnome Terminal中的新选项卡。

通常,答案是“您不能,因为环境变量不能那样工作”。但是,还有另一个答案,那就是,您总是可以破解一些东西。一种方法是将变量的值写入文件,例如~/.myvar,然后将其包含在中~/.bashrc。然后,每个新的Shell将从从该文件读取的值开始

您可以更进一步-将~/.myvarMYVAR=200设置为format ,然后设置PROMPT_COMMAND=source ~/.myvar,这将导致每当您收到新提示时都重新读取该值。它仍然不是相当一个共享的全局变量,但它开始像它。但是,直到提示再次出现时,它才会激活,这取决于您要尝试执行的操作,可能是一个严重的限制。

然后,当然,下一步是更改自动写入~/.myvar。事情变得有些复杂,我将在此处停止,因为实际上,环境变量并不是要作为外壳间的通信机制,最好是找到另一种方式来做到这一点。


10
我可以听到在酷刑下外壳

是的,对不起。所以我停了下来 :)
mattdm 2011年

“这将使它像全局变量一样起作用”-的确,这就是我要完成的事情。〜/ .myvar并不漂亮,但是可以。您还有其他建议吗?
有人仍在使用您MS-DOS

2
好吧,让我们退后一步。为什么要一个全局变量?
mattdm

1
@mattdm:我有一些必须遵守的“官僚主义”。其中之一是我需要提交的一堆代码以及注释。现在,这些代码位于文件夹层次结构中(home / user / projects / projectcode / code1 / code2)。我制作了一个将code1和code2提取到env vars的函数(因此,当我需要执行一项活动时,我只是在dir中使用代码调用该函数),而在提交时,我使用vim,并且有一些函数阅读这些变量并自动添加注释。我认为为此使用文件可以解决。
有人仍在使用您MS-DOS

13

假设我export MY_VAR=0进去了~/.bashrc

那是你的错误。您应该在中定义环境变量~/.profile,该变量在登录时~/.bashrc读取。每次启动Shell时读取;启动内壳时,它会覆盖MY_VAR。如果没有这样做,您的环境变量将向下传播。

有关更多信息,~/.bashrcVS ~/.profile,看我以前 的帖子 这个 话题

请注意,向上传播(句点是不可能的)(从子shell中自动反映在父shell中的修改值)。



3

根本不要使用环境变量。使用文件。

为防止进程在更新/读取文件时互相踩踏,请使用lockfiles和小型前端更新程序脚本,其目的只是在未锁定的情况下使用$ 1更新文件。锁定文件的实现基本上是通过检查特定文件是否存在(/var/run/yourscript.lck),如果存在,则等待该文件消失一段时间,如果不存在则失败。此外,完成更新文件后,您必须删除锁定文件。

准备处理由于文件繁忙而导致脚本无法更新文件的情况。


8
技巧:使用目录而不是文件进行锁定,因为它mkdir可以作为原子的测试和创建。
mattdm

1
如果你们想谈谈锁定,那么您不妨使用flock(2)
Ehtesh Choudhury

@mattdm我发现符号链接ln -s dummy lockfile(即使损坏)也可能起作用,因为如果符号链接已经存在,它将失败。我想知道一种测试这种方法是否真正100%安全的方法。
Aquarius Power

1

当我刚刚用谷歌搜索这个问题时,我正试图解决从子外壳中更新状态(即外壳变量)的问题。这样就可以在管道内部分配变量,并且该分配对父对象是透明可见的。

当然,这不可能以简单的方式实现,因为流水线的各个部分是在子fork外壳中执行的,这些子外壳是从父外壳中编辑的,因此具有在父内存上写时复制视图的内存。但是,我认为基于“ 共享内存 ”类型的IPC可以实现苗条和透明的解决方案。

而且我什至找到了一个完全实现此设计的实现 ...但是它在Perl中。

无论如何添加此答案作为可能的解决方案。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.