解决Bash脚本中传入的命令参数提前执行的问题
解决Bash脚本中命令参数提前执行的问题
你的问题出在命令替换$(...)被外层shell提前解析了:调用install_package时,外层双引号里的$(curl ...)会被当前shell先执行,把curl返回的脚本内容替换进去,导致这条curl命令在函数执行前就跑了。以下是两种可靠的解决方式:
方式1:用单引号包裹命令参数,避免提前解析
把整个命令参数用单引号括起来,shell就不会解析里面的命令替换和特殊字符,原封不动传递给函数:
install_package () { $2 EXITCODE=$? if [ "$EXITCODE" -ne "0" ]; then exit $EXITCODE fi } # 用单引号包裹第二个参数 install_package "brew" '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"'
方式2:改用参数列表传递命令(更安全)
推荐这种写法,避免字符串解析的问题,直接把命令和它的参数作为函数的后续参数传递,函数里用"$@"执行:
install_package () { local pkg_name="$1" shift # 移除第一个参数(包名) "$@" # 执行后续所有参数组成的命令 local exitcode=$? if [ "$exitcode" -ne 0 ]; then exit "$exitcode" fi } # 直接传递命令的各个部分,不需要嵌套引号 install_package "brew" /bin/bash -c '$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)'
补充说明
- 方式2里,
"$@"会保留每个参数的原始格式,不会因为空格或特殊字符出现分词错误,比直接执行$2更安全。 - 用单引号包裹
bash -c后的内容时,curl命令会在子shell中被解析执行,不会提前触发。
内容的提问来源于stack exchange,提问作者Nipun Ravisara
相关产品推荐
相关产品推荐

