和我的问题类似这里,除了多个 ssh,并且类似于这个问题但参数中有空格......
我想test.sh
通过多个 ssh 在远程服务器上运行本地脚本。test.sh
接受一个经常有多个单词的论点。
测试.sh:
#!/bin/bash
while getopts b: opt;
do
case $opt in
b)
bval="$OPTARG"
;;
esac
done
echo $bval
呼叫测试.sh
#!/bin/bash
# Do some stuff
PHRASE="multi word arg"
ssh -A user@host1 "bash -s" -- < ./test.sh -b "${PHRASE@Q}"
并运行./call_test.sh
,这会正确输出
multi word arg
但是当我将最后一行更改call_test.sh
为以下内容时:
ssh -A user@host1 ssh -A user@host2 "bash -s" -- < ./test.sh -b "${PHRASE@Q}"
并运行./call_test.sh
,它输出:
multi
基本上,从单个 SSH 更改为多个 SSH 打破了我的多词争论。
我认为多个 ssh 命令在每一步都会解开多单词参数的引号,但我不确定如何防止这种情况。有什么想法如何成功地将多字参数传递给跨多个 ssh 运行的脚本吗?
编辑:
我相信这个答案解决我遇到的问题。
答案1
如果通过 2 个 ssh 命令传递它,则必须对字符串进行两次引号转义。通过额外的PHRASE=${PHRASE@Q}
作业来做到这一点。
但请注意,${var@Q}
and printf %q
(如下所述)都将使用$'...'
引号转义格式,远程 shell 可能不支持该格式。
test.sh
将脚本的最后一行修复echo "$bval"
为echo $bval
:
PHRASE="multi word arg"
PHRASE=${PHRASE@Q}
ssh -A user@host1 ssh -A user@host2 "bash -s" -- < ./test.sh -b "${PHRASE@Q}"
multi word arg
${var@P}
您可以使用旧版本的 bash 不支持的扩展形式,而不是使用printf -v var %q
:
PHRASE="multi word arg"
printf -v PHRASE %q "$PHRASE"
printf -v PHRASE %q "$PHRASE"
ssh -A user@host1 ssh -A user@host2 "bash -s" -- < ./test.sh -b "$PHRASE"
另外,您可以将整个脚本及其参数放在一个变量中,而不是通过标准输入提供脚本,这是低效的(当从标准输入读取脚本时,bash 将为每个字节执行读取系统调用):
printf -v cmd 'bash -c %q bash -b %q' "$(cat test.sh)" 'multi word wahterve'
printf -v cmd %q "$cmd"
ssh localhost ssh localhost "$cmd"
multi word wahterve