Como executar um script local com espaços em branco nos argumentos em uma máquina remota por meio de vários SSH?

Como executar um script local com espaços em branco nos argumentos em uma máquina remota por meio de vários SSH?

Semelhante à minha perguntaaqui, exceto com vários ssh, e semelhante aessa questãomas com espaço em branco nos argumentos...

Gostaria de executar um script local test.shem um servidor remoto por meio de vários ssh. test.shaceita um argumento que geralmente contém várias palavras.

teste.sh:

#!/bin/bash
while getopts b: opt;
do
  case $opt in
    b)
       bval="$OPTARG"
       ;;
  esac
done
echo $bval

call_test.sh

#!/bin/bash
# Do some stuff
PHRASE="multi word arg"
ssh -A user@host1 "bash -s" -- < ./test.sh -b "${PHRASE@Q}"

e run ./call_test.sh, isso gera corretamente

multi word arg

Mas quando eu mudo a última linha call_test.shpara o seguinte:

ssh -A user@host1 ssh -A user@host2 "bash -s" -- < ./test.sh -b "${PHRASE@Q}"

e run ./call_test.sh, ele gera:

multi

Basicamente, mudar de SSH único para SSH múltiplo quebra meu argumento de várias palavras.

Acho que os vários comandos ssh estão desembrulhando as aspas do argumento de várias palavras em cada etapa, mas não tenho certeza de como evitar isso. Alguma idéia de como passar com êxito o argumento de várias palavras para o script executado em vários ssh?

Editar:

Eu acreditoesta respostachega ao problema que estou enfrentando.

Responder1

Se você passar por 2 comandos ssh, será necessário escapar aspas da string DUAS VEZES. Faça isso com uma PHRASE=${PHRASE@Q}tarefa extra.

Tenha cuidado, no entanto, que ambos ${var@Q}e printf %q(descritos abaixo) usarão o $'...'formato quote-escape, que pode não ser suportado pelo shell remoto.

Depois de corrigir a última linha do seu test.shscript em echo "$bval"vez de 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

Em vez do ${var@P}formulário de expansão que não é compatível com versões mais antigas do bash, você pode usarprintf -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"

Além disso, em vez de fornecer seu script via stdin, o que é ineficiente (o bash fará uma chamada de sistema de leitura para cada byte ao ler o script do stdin), você pode simplesmente colocar o script inteiro e seus argumentos em uma variável:

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

informação relacionada