Ä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.sh
auf einem Remote-Server über mehrere SSHs ausführen. test.sh
Nimmt 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.sh
wie 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.sh
Skripts 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