循环遍历POSIX sh

时间:2017-01-27 16:23:18

标签: unix environment-variables sh

我需要遍历环境变量并在POSIX中获取它们的名称和值(不是bash)。这是我到目前为止所做的。

#!/usr/bin/env sh

# Loop over each line from the env command
while read -r line; do
  # Get the string before = (the var name)
  name="${line%=*}"
  eval value="\$$name"

  echo "name: ${name}, value: ${value}"
done <<EOF
$(env)
EOF

除非环境变量包含换行符,否则它大部分时间都有效。在这种情况下我需要它。

我知道-0的{​​{1}}标志用nul而不是换行符分隔变量,但是如果我使用那个标志,我该如何遍历每个变量? 编辑:@chepner指出POSIX env不支持env,所以就这样了。

任何使用便携式Linux实用程序的解决方案都是好的,只要它适用于POSIX sh。

2 个答案:

答案 0 :(得分:4)

无法完全自信地解析env的输出;考虑这个输出:

bar=3
baz=9

我可以用两种不同的环境来制作它:

$ env -i "bar=3" "baz=9"
bar=3
baz=9
$ env -i "bar=3
> baz=9"
bar=3
baz=9

这两个环境变量barbaz是简单的数值,还是一个变量bar,其值为$'3\nbaz=9'(使用{{1} ANSI引用风格)?

但是,您可以使用bash数组安全地使用POSIX awk访问环境。例如:

ENVIRON

使用此命令,您可以区分上述两种环境。

awk 'END { for (name in ENVIRON) {
            print "Name is "name;
            print "Value is "ENVIRON[name];
           }
         }' < /dev/null

答案 1 :(得分:2)

也许这会起作用?

ax.scatter

它不是防弹的,好像带换行符的变量的值恰好有一个看起来像赋值的行开头,可能会有些混淆。

扩展程序使用#!/usr/bin/env sh env | while IFS= read -r line do name="${line%%=*}" indirect_presence="$(eval echo "\${$name+x}")" [ -z "$name" ] || [ -z "$indirect_presence" ] || echo "name:$name, value:$(eval echo "\$$name")" done 删除最长匹配项,因此如果一行包含多个%%符号,则应删除它们以仅从行的开头留下变量名称。