如何向无控制权的Bash脚本传递带复合逻辑的CMD变量?
如何将嵌套命令作为变量传入不可修改的Bash脚本?
有一个无法修改的Bash脚本magic.sh,内容如下:
set -x echo "$CMD" if ${CMD}; then echo "Success" fi
需要将命令bash -c "echo first && true"作为CMD环境变量传入该脚本执行,但直接尝试的方式出现参数拆分错误:
❯ env CMD='bash -c "echo first && true"' bash magic.sh + echo 'bash -c "echo first && true"' bash -c "echo first && true" + bash -c '"echo' first '&&' 'true"' first: -c: line 1: unexpected EOF while looking for matching `"'
错误原因
当脚本中执行${CMD}时,Bash会先完成变量替换,再对结果进行分词处理——此时变量内的双引号已经失去了语法上的引号作用,仅作为普通字符存在。这就导致原命令被拆分为bash、-c、"echo、first、&&、true"这几个参数,bash -c实际收到的脚本内容是"echo,自然出现语法错误。
解决方法
需要将嵌套命令中的特殊字符和引号正确转义,确保变量替换后能被Bash正确解析为完整的参数列表。以下两种方法都可行:
方法1:转义单引号包裹内部命令
通过单引号嵌套转义,让内部命令被正确识别为bash -c的单个参数:
env CMD='bash -c '\''echo first && true'\'' bash magic.sh
方法2:用printf %q自动转义
利用printf %q将每个命令参数转换为适合Shell重新解析的转义字符串,避免手动处理转义:
env CMD="$(printf '%q ' bash -c 'echo first && true')" bash magic.sh
执行上述任意一种命令后,脚本都会正确输出:
+ echo 'bash -c '\''echo first && true'\'' bash -c 'echo first && true' + bash -c 'echo first && true' first + echo Success Success
内容的提问来源于stack exchange,提问作者Yeti
相关产品推荐
相关产品推荐

