Similar a mi preguntaaquí, excepto con múltiples ssh, y similar aesta preguntapero con espacios en blanco en los argumentos...
Me gustaría ejecutar un script local test.sh
en un servidor remoto a través de múltiples ssh. test.sh
toma un argumento que a menudo tiene varias palabras.
prueba.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}"
y ejecutar ./call_test.sh
, esto genera correctamente
multi word arg
Pero cuando cambio la última línea de call_test.sh
a la siguiente:
ssh -A user@host1 ssh -A user@host2 "bash -s" -- < ./test.sh -b "${PHRASE@Q}"
y ejecutar ./call_test.sh
, genera:
multi
Básicamente, cambiar de SSH único a SSH múltiple rompe mi argumento de varias palabras.
Creo que los múltiples comandos ssh desenvuelven las comillas del argumento de varias palabras en cada paso, pero no estoy seguro de cómo evitarlo. ¿Alguna idea de cómo pasar con éxito el argumento de varias palabras al script que se ejecuta en varios ssh?
Editar:
Yo creoesta respuestaaborda el problema con el que me estoy encontrando.
Respuesta1
Si lo pasa a través de 2 comandos ssh, debe escribir la cadena entre comillas DOS VECES. Hazlo con una PHRASE=${PHRASE@Q}
tarea adicional.
Sin embargo, tenga en cuenta que tanto ${var@Q}
y printf %q
(descrito a continuación) utilizarán el $'...'
formato de escape de comillas, que puede no ser compatible con el shell remoto..
Después de arreglar la última línea de su test.sh
script en echo "$bval"
lugar 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
En lugar del ${var@P}
formulario de expansión que no es compatible con versiones anteriores de bash, puede 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"
Además, en lugar de proporcionar su secuencia de comandos a través de la entrada estándar, lo cual es ineficiente (bash realizará una llamada al sistema de lectura para cada byte cuando lea la secuencia de comandos desde la entrada estándar), puede simplemente colocar la secuencia de comandos completa y sus argumentos en una variable:
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