什么';s相当于bash';sh中的s${!ENV}?

什么';s相当于bash';sh中的s${!ENV}?,bash,sh,gitlab-ci,Bash,Sh,Gitlab Ci,bash中的命令${!ENV}将获取环境变量ENV的值,然后将该值解释为另一个环境变量的名称,然后它将立即返回后面的值 ENV=PATH echo ${!ENV} 输出: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 为了使现有的Gitlab管道更加简洁,我发现了这种行为的用途。但是,我们的Gitlab运行程序使用sh运行,而不是bash sh中bash的${!ENV}的等价物是什么?否。POSIX不要求在shell

bash中的命令
${!ENV}
将获取环境变量
ENV
的值,然后将该值解释为另一个环境变量的名称,然后它将立即返回后面的值

ENV=PATH
echo ${!ENV}
输出:

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
为了使现有的Gitlab管道更加简洁,我发现了这种行为的用途。但是,我们的Gitlab运行程序使用sh运行,而不是bash


sh中bash的
${!ENV}
的等价物是什么?

否。POSIX不要求在shell中进行这种“间接扩展”。如果您想严格遵守POSIX,最好的办法是
eval

ENV=PATH
eval echo "\"$ENV is \$$ENV\""
输出(示例):

在我的经验中,使用BASH几乎没有任何困难,所以你也应该考虑坚持BASH,除非你是迂腐POSIX。< /P> 请注意,
eval
是一件危险的事情。建议您在实际评估字符串之前,验证该字符串是否可以安全地进行
eval
,除非该字符串是由您(您的脚本)创建的,而不是由用户输入的。像这样简单的方法会奏效:

echo "$ENV" | grep -qi '^[A-Z_][A-Z0-9_]*$'

检查退出值
$?
。如果为零,则可以安全地计算
$ENV
。如果是1,那么最好更彻底地检查字符串。

看看间接寻址,解决方案是使用
eval“echo\$${ENV}”
这不是等价的;这就是为什么shell添加了自己的间接扩展作为POSIX标准的扩展;它的行为是
${!ENV}
行为的一个大型(危险)超集;除了间接参数扩展之外,您的用例可能还有另一个兼容POSIX的解决方案。如果只使用Linux“Bash”是可以的,但请记住,默认情况下,其他操作系统(*BSD)中甚至没有安装该解决方案,那么通过使用“sh”,您可以确保更高的可移植性。我不了解您,但这个解决方案看起来比我在过去20分钟里提出的要好得多:
echo$(env|grep^$(env|grep^ env=| cut-f2-d“=”);cut-f2-d“=”
。值得注意的是:这仅在导出两个变量时有效。至少检查
ENV
的值是否确实是有效的标识符名称,以避免注入攻击。我开始看到问题所在。我冗长的解决方案更安全吗?更安全,但太重了。除了用于命令替换的fork之外,您还生成了6个外部进程。
echo "$ENV" | grep -qi '^[A-Z_][A-Z0-9_]*$'