这样做的明显方法有很多问题:
# 这会因某些输入而失败。HTML肯定会出问题
# 因为 '<' 和 '>' 字符将被解释为文件重定向
$ 同时读取 r; 做评估回声$ r; 完成<输入
下面的 perl 应该可以很好地处理简单输入的问题。
$ perl -pwe 'while(($k,$v) = each %ENV) { s/\${?$k}?/$v/ }' 输入
但它对 ${FOO-bar} 之类的结构没有任何作用。如果您需要处理此类构造,则转义所有 shell 元字符并执行 while/read 循环可能就足够了:
$ sed -e 's/\([<>&|();]\)/\\\1/g' 输入 | 同时读取-rl;执行 eval echo "$l"; 完毕
请注意,这既不可靠也不安全。考虑一下输入会发生什么,例如:
\; rm -rf /
我说“考虑”。不要测试那个。sed 会在分号前插入一个反斜杠,然后 eval 会得到字符串 "\\;" 这将被解释为单个反斜杠,后跟一个分号,终止回显,并且 rm -rf 将被执行。鉴于评估未知输入的不安全性,坚持使用 perl 之类的东西并明确替换所需的 sh 构造可能会更安全。就像是:
$ perl -pwe 'while(($k,$v) = each %ENV) { s/\${?$k}?/$v/ };
s/\${[^-]*-([^}]*)}/$1/g' 输入
这个输入有问题,如 ${FOO=some-text}。为了可靠地获取所有 sh 构造(${word:rhs},其中 ':' 可以是 '-'、'?'、'='、'+'、'%'、'#' 或任何带有冒号的相同(或许多其他符号,如果您允许非posix sh 语法!))您将不得不构建一组相当精细的比较。