如何在SSH命令中传递包含空格参数的bash $@?
如何在SSH命令中传递包含空格参数的bash $@?
这个问题我之前也踩过坑!核心原因是SSH在传递命令时,会把本地的参数拼接成一个字符串,远程服务器的shell会重新解析这个字符串,导致原来带空格的参数被拆分成多个独立参数——就像你遇到的--since '2 days ago'被拆成了--since、2、days、ago,自然触发了journalctl的时间解析错误。
下面给你两种靠谱的解决方法:
方法一:用printf '%q'转义所有参数
通过printf的%q格式符,可以把每个参数转义成适合shell安全解析的形式(比如空格会被转义成\ ),这样远程shell就能正确还原参数列表。脚本写法如下:
#!/usr/bin/env bash ssh host "$(printf '%q ' journalctl "$@")"
当你执行bin/log --since '2 days ago'时,printf会把命令转义成journalctl\ --since\ '2\ days\ ago',远程shell接收到后能正确解析成完整的参数。
方法二:通过bash -c传递位置参数(更推荐)
这种方法让远程的bash直接接收位置参数,彻底避免字符串解析的坑。关键是要给远程的bash -c脚本传递$@,同时用_填充$0的位置(因为bash -c的第一个参数是脚本内容,第二个参数会作为$0,后续参数才是$1、$2等位置参数):
#!/usr/bin/env bash ssh host bash -c 'journalctl "$@"' _ "$@"
这个写法的逻辑是:远程执行bash -c 'journalctl "$@"',把_作为远程bash的$0,再把本地的$@作为远程脚本的位置参数。这样远程的"$@"就会完整展开你传递的带空格的参数,完全不会拆分。
亲测第二种方法更可靠,尤其是碰到特殊字符(比如引号、通配符)的时候,不会出现意外解析的问题。
备注:内容来源于stack exchange,提问作者jojman
相关产品推荐
相关产品推荐

