2

I'm trying to run the script test.sh (which is on my local machine) on a remote server. 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

It works fine on my local machine:

./test.sh -b "multi word arg"

Output:

multi word arg

But when I run it on a remote server, like so:

ssh -A user@remotehost "bash -s" -- < ./test.sh -b "multi word arg"

I get only:

multi

Any ideas on how I could pass the full, multi-word argument to the script?

2

1 Answer 1

1

You need another level of quotes: '"multi word arg"'

The first level of quotes is removed by your local shell, and ssh gets multi word arg. Then ssh, on the remote system, runs something like $SHELL -c "bash -s -- -b multi word arg" (where $SHELL is your login shell, most probably bash, again).The login shell then does quote removal (none to be removed) and word splitting, which is why you get one word.

To illustrate:

% ssh 192.168.0.2 'printf :%s:\\n' '"foo bar baz"'
:foo bar baz:
% ssh 192.168.0.2 'printf :%s:\\n' 'foo bar baz'
:foo:
:bar:
:baz:
6
  • This looks promising, but I'm hoping to run a full script that is stored locally on a remote server, which (AFAIK) requires the "bash -s" -- < ./test.sh -b "multi word arg" syntax. Using that syntax, when I wrapped "multi word arg" in an extra set of quotes, like so: '"multi word arg"', the output was an empty string - the -b flag didn't even get triggered. Is there an alternative to my syntax that would allow me to use the extra quote wrapping? Mar 12, 2020 at 14:31
  • @JacobStern I get multi word arg as the output. Something else might messing with your command there. O.o Maybe try bash -xs to get debug output and update your question with that.
    – muru
    Mar 16, 2020 at 5:36
  • You're right, this totally works! I realized I dropped the '--' when I ran the command, which was what caused it to fail. Your answer works perfectly. Mar 16, 2020 at 15:47
  • One follow-up question - is there any way to do this if "multi word arg" is stored in a variable, like PHRASE="multi word arg"? (My full use case is to run this command within a shell script). When I try wrapping a variable in single quotes, ('$PHRASE' it treats the variable as a string literal rather than as a variable, and when I wrap the variable in double quotes ("$PHRASE"), it ignores the quotes and I get "multi" as output. Is this worth a new question? Mar 16, 2020 at 16:02
  • @JacobStern you can swap the quotes around, perhaps: "'$PHRASE'", or use parameter expansion with quoting: "${PHRASE@Q}"
    – muru
    Mar 17, 2020 at 2:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.