在Ubuntu 14.04上以root身份安装Ruby Version Manager(RVM)之后。我遇到了一个奇怪的bash行为。我们来看看导出的环境变量。我以ubunutu用户身份登录并在我的bash中运行export
。以下是rvm的三个导出环境变量,其他可用:
declare -ax chpwd_functions='([0]="__rvm_cd_functions_set" [1]="__rvm_after_cd")'
declare -x rvm_version="1.25.28 (stable)"
declare -x rvm_ruby_mode
一切都很好,但是当我运行bash -c export
时,我们只得到:
declare -x rvm_version="1.25.28 (stable)"
有人可以解释为什么在子bash中删除所有空的环境变量和所有数组?我该怎么做才能确保父shell中的所有环境变量真的可以在子shell中使用?
这个问题对我来说真是一个阻碍者。我正在使用vagrant及其shell配置程序。在一个脚本中我设置了rvm,在第二个脚本中我必须配置一些gemsets。问题是在第二个脚本中rvm命令不运行。活动shell仅获取rvm的那些环境变量,它们是非数组且非空。手动采购rvm.sh
不是解决办法!
答案 0 :(得分:2)
这是因为man bash
的最后一行:
可能尚未导出数组变量。
我在某处读到BASH开发人员的一个注释,因为导出数组非常复杂且容易出错。
这一行:
declare -x rvm_ruby_mode
仅声明具有导出属性集(没有值)的变量的名称,如果为其分配值,则它将在子shell中可用。
<强> Here is post by BASH author on export of array in BASH. 强>
答案 1 :(得分:1)
使用=
运算符为名称指定值时会创建变量,例如
foo=bar
创建一个名为foo
的变量,其值为bar
。
declare
有两个原因:一,允许动态创建变量(这超出了本问题的范围),另外两个,设置名称的属性(不是必然变量)。命令
declare -x rvm_ruby_mode
只需设置名称 rvm_ruby_mode
的导出属性即可。要实际创建名称具有export属性集的变量,您需要使用=
运算符,就像没有declare
命令一样。
declare -x rvm_ruby_mode=
现在 rvm_ruby_mode
是一个空变量,其名称标记为导出。
我说&#34;标记为出口&#34;因为在创建子shell之前不会导出变量。在此之前,只有一个名称列表,如果名称在创建子shell /子进程时具有值,则会复制到新环境中。此列表与实际变量列表(也是具有关联值的名称)分开。
至于为什么无法导出数组?从技术上讲,环境不是一组变量,因为变量是shell构造,而环境是POSIX中所有进程使用的东西,无论是否由shell运行。环境只是<name>=<value>
形式的字符串列表。没有关于如何将数组元素打包成单个字符串的标准,任何进程都可以解析并重构为适当的数据结构。虽然bash
可能会导致异常,但如果新的子进程是另一个bash
shell并且想出一些在环境中嵌入数组的方法(就像它对函数一样)定义),显然这还没有完成。