如何通过多个 SSH 在远程计算机上运行参数中带有空格的本地脚本?

如何通过多个 SSH 在远程计算机上运行参数中带有空格的本地脚本?

和我的问题类似这里,除了多个 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

相关内容