读取ruby中的所有shell变量
问题:
我在ruby脚本中运行shell脚本作为子进程,运行脚本后我希望有一个选项来检查shell的所有环境变量,包括数组变量。
到目前为止,我想出了:
set | awk -F= 'BEGIN {v=0;} /^[a-zA-Z_][a-zA-Z0-9_]*=/ {v=1;} v==1 && $2~/^['\''\$]/ {v=2;} v==1 && $2~/^\(/ {v=3;} v==2 && /'\''$/ && !/'\'\''$/ {v=1;} v==3 && /\)$/ {v=1;} v {print;} v==1 {v=0;} '
哪个非常好只显示变量,包括数组,多行字符串和过滤函数。
但是这并不是一直使用相同的格式,尤其是数组变量在BASH和ZSH中的表示方式不同。
这是我目前的实现: https : //github.com/mpapis/tf/blob/master/lib/tf/environment.rb
题:
有一种简单的方法可以显示在BASH和ZSH /可能的其他shell中持久工作的所有变量。
很高兴再次见到你mpapis 😉
不幸的是,POSIX.1-2008并未涵盖数组和关联数组 ,正如您所发现的那样, bash
和zsh
之间存在一些令人讨厌的细微差别。 因此,没有一种方法可以在所有POSIX shell中执行此操作,我们需要检查$BASH_VERSION
等,如您所述。
我决定最好避免编写Ruby来解析set
或其他shell
内置函数的输出。 输出不方便解析,无论如何shell都知道自己的数据,所以我认为将大部分智能放在shell代码中是有意义的。 所以我提出了一个解决方案 ,它使用shell代码将数据结构输出为YAML ,然后将YAML直接加载到Ruby中。
首先,我将您的参考实现和测试导入到独立存储库的master
分支中 。 然后我加强了测试套件并进行了一些调整。 这表明多线处理仍然存在问题。
然后我创建了一个新的yaml
分支并开发了我自己的实现。 我再次扩展了测试。 他们都通过;-)请注意,我使用一些不同的技巧在zsh
和bash
进行内省:
-
zsh
有一个zsh/parameter
模块,它提供了包含其所有参数的名称和类型的关联数组。 -
bash
declare -p
,它是一种易于解析的forms。 它还有compgen -A variable
,但最后我没有使用它。
我认为添加ksh
支持也很容易。
set
返回所有shell变量,而不是环境变量。 要获取环境变量,请使用env
命令。 请注意,bash不会将数组导出到环境中。