Wie führe ich ein lokales Skript mit Leerzeichen in Argumenten auf einem Remotecomputer über mehrere SSH aus?

Wie führe ich ein lokales Skript mit Leerzeichen in Argumenten auf einem Remotecomputer über mehrere SSH aus?

Ähnlich wie meine FrageHier, außer mit mehreren SSH, und ähnlich wiediese Frageaber mit Leerzeichen in den Argumenten ...

Ich möchte ein lokales Skript test.shauf einem Remote-Server über mehrere SSHs ausführen. test.shNimmt ein Argument an, das oft aus mehreren Wörtern besteht.

test.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}"

und ausführen ./call_test.sh, dies gibt korrekt aus

multi word arg

Aber wenn ich die letzte Zeile call_test.shwie folgt ändere:

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

und ausführen ./call_test.sh, es gibt aus:

multi

Im Grunde macht die Änderung von einem SSH-Server zu mehreren SSH-Servern mein Argument mit mehreren Wörtern ungültig.

Ich denke, dass die mehreren SSH-Befehle bei jedem Schritt die Anführungszeichen für das aus mehreren Wörtern bestehende Argument aufheben, aber ich bin nicht sicher, wie ich das verhindern kann. Irgendwelche Ideen, wie man das aus mehreren Wörtern bestehende Argument erfolgreich an das Skript übergibt, das über mehrere SSHs ausgeführt wird?

Bearbeiten:

Ich glaubediese Antwortgeht auf das Problem ein, auf das ich stoße.

Antwort1

Wenn Sie es durch zwei SSH-Befehle übergeben, müssen Sie die Zeichenfolge ZWEIMAL mit Anführungszeichen maskieren. Tun Sie das mit einer zusätzlichen PHRASE=${PHRASE@Q}Zuweisung.

Beachten Sie jedoch, dass sowohl ${var@Q}als auch printf %q(unten beschrieben) das Anführungszeichen-Escape-Format verwenden $'...', das von der Remote-Shell möglicherweise nicht unterstützt wird..

Nachdem Sie die letzte Zeile Ihres test.shSkripts wie echo "$bval"folgt korrigiert haben 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

Anstelle der ${var@P}Erweiterungsform, die in älteren Versionen von Bash nicht unterstützt wird, können Sie verwendenprintf -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"

Anstatt Ihr Skript über stdin einzugeben, was ineffizient ist (bash führt beim Lesen des Skripts von stdin für jedes Byte einen Lesesystemaufruf aus), können Sie einfach das gesamte Skript und seine Argumente in eine Variable einfügen:

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

verwandte Informationen