通过SSH传递脚本参数时如何避免字符串错误拆分?
正确通过SSH传递参数避免错误拆分的方法
在通过SSH执行远程脚本task.sh时,需要将本地脚本run.sh接收的参数正确传递到远程,避免包含空格的参数被拆分或所有参数被合并。
task.sh内容:
i=0 for p in "$@"; do echo "#${i}: ${p}" i=$((i+1)) done
本地执行bash task.sh hello world 'in one line'可得到正确输出,但直接用ssh user@remote.example.com "bash -s $@" < task.sh会导致参数拆分错误,用单引号包裹$@则会合并所有参数。
正确实现方式
利用printf %q对每个参数进行转义,确保远程shell解析时能正确识别每个参数的边界。修改run.sh为:
ssh user@remote.example.com "bash -s $(printf '%q ' "$@")" < task.sh
原理说明
printf '%q' "$arg"会将参数转换为适合shell解析的安全格式:包含空格、特殊字符的参数会被自动添加引号或转义,确保远程shell不会错误拆分。- 本地shell先展开
$@并转义每个参数,再将完整的命令字符串传递给SSH,远程执行时bash -s会正确接收所有参数。
验证效果
执行bash run.sh hello world 'in one line',远程输出与本地一致:
#0: hello #1: world #2: in one line
为什么其他方法失败
- 直接使用
"bash -s $@":本地shell展开$@后,包含空格的参数会被远程shell再次拆分,导致多参数错误。 - 使用
'$@':本地shell不会展开$@,远程shell接收的是完整字符串,所有参数被合并为一个。 - 数组方式:
"${ARGS[@]}"展开后仍会被远程shell重新解析,空格拆分问题依旧;加单引号则整个数组被当作单个命令,触发找不到命令的错误。
内容的提问来源于stack exchange,提问作者Green 绿色
相关产品推荐
相关产品推荐

