如何在使用bash -c调用时将完整参数集从一个bash脚本传递到另一个?
如何在Bash脚本中正确转发完整参数集?
现有脚本
Caller.sh
#!/bin/bash echo "Caller received args $@" bash -c "./Callee.sh $@" bash -c './Callee.sh "$@"' "$@"
Callee.sh
#!/bin/bash echo "Callee received args $@"
当前执行结果
执行脚本后出现参数传递不完整的问题:
./Caller.sh Foo Caller received args Foo Callee received args Foo Callee received args ~/Code/Play master ./Caller.sh Foo Bar Caller received args Foo Bar Callee received args Foo Callee received args Bar
问题分析
- 第一种写法
bash -c "./Callee.sh $@":直接展开$@会导致参数被拆分,多个参数会被解析为bash -c命令的多个参数,而非完整传递给Callee.sh,多参数场景下只有第一个参数能被正确接收。 - 第二种写法
bash -c './Callee.sh "$@"' "$@":bash -c执行的命令字符串中,$@对应的是该命令的位置参数,但外层传递的"$@"会覆盖$0(脚本名位置),导致内部$@无法获取到实际参数。
正确解决方案
方案1:通过bash -c正确传递参数
需要给bash -c的执行环境指定$0占位符,再传递实际参数,确保内部$@能正确引用所有参数:
bash -c './Callee.sh "$@"' 'Caller' "$@"
这里'Caller'作为$0的占位值(可替换为任意字符串),后续的"$@"会被解析为命令环境中的$1、$2...,内部的"./Callee.sh "$@""就能完整接收所有参数。
方案2:直接调用脚本(更简洁)
如果不需要通过bash -c间接执行,直接调用脚本并传递"$@"是最可靠的方式:
./Callee.sh "$@"
这种方式能完整保留每个参数的原始内容(包括含空格、特殊字符的参数),避免bash -c带来的位置参数混淆。
验证结果
修改后执行./Caller.sh Foo Bar,正确输出应为:
Caller received args Foo Bar # 原错误行输出(若保留) Callee received args Foo # 正确行输出 Callee received args Foo Bar
内容的提问来源于stack exchange,提问作者merlin2011
相关产品推荐
相关产品推荐

