读取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并未涵盖数组和关联数组 ,正如您所发现的那样, bashzsh之间存在一些令人讨厌的细微差别。 因此,没有一种方法可以在所有POSIX shell中执行此操作,我们需要检查$BASH_VERSION等,如您所述。

我决定最好避免编写Ruby来解析set或其他shell内置函数的输出。 输出不方便解析,无论如何shell都知道自己的数据,所以我认为将大部分智能放在shell代码中是有意义的。 所以我提出了一个解决方案 ,它使用shell代码将数据结构输出为YAML ,然后将YAML直接加载到Ruby中。

首先,我将您的参考实现和测试导入到独立存储库的master分支中 。 然后我加强了测试套件并进行了一些调整。 这表明多线处理仍然存在问题。

然后我创建了一个新的yaml分支并开发了我自己的实现。 我再次扩展了测试。 他们都通过;-)请注意,我使用一些不同的技巧在zshbash进行内省:

  • zsh有一个zsh/parameter模块,它提供了包含其所有参数的名称和类型的关联数组。
  • bash declare -p ,它是一种易于解析的forms。 它还有compgen -A variable ,但最后我没有使用它。

我认为添加ksh支持也很容易。

set返回所有shell变量,而不是环境变量。 要获取环境变量,请使用env命令。 请注意,bash不会将数组导出到环境中。