Similar to my question here, except with multiple ssh, and similar to this question but with white space in the arguments...
I would like to run a local script, test.sh
, on a remote server via multiple ssh. test.sh
takes an argument that often has multiple words.
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}"
and run ./call_test.sh
, this correctly outputs
multi word arg
But when I change the last line of call_test.sh
to the following:
ssh -A user@host1 ssh -A user@host2 "bash -s" -- < ./test.sh -b "${PHRASE@Q}"
and run ./call_test.sh
, it outputs:
multi
Basically, changing from single SSH to multiple SSH breaks my multi-word argument.
I think that the multiple ssh commands are unwrapping the quotes for the multi-word argument at each step, but I'm not sure how to prevent that. Any ideas how to successfully pass the multi-word argument to the script running across multiple ssh?
I believe this answer gets at the problem that I'm running into.
If you pass it through 2 ssh commands, you have to quote-escape the string TWICE. Do that with an extra PHRASE=${PHRASE@Q}
assignment.
Beware however that both ${var@Q}
and printf %q
(described below) will use the $'...'
quote-escape format, which may not be supported by the remote shell.
After fixing the last line of your test.sh
script to echo "$bval"
instead of 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
Instead of the ${var@P}
expansion form which is not supported in older versions of bash, you can use 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"
Also, instead of giving your script via stdin, which is inefficient (bash will do a read system call for each byte when reading the script from stdin), you can just put the whole script and its arguments in a 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
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments