Bash – How to Execute Local Script on Remote Machine with Arguments

bashoptionsscriptingshellshell-script

I have written a script that runs fine when executed locally:

./sysMole -time Aug 18 18

The arguments "-time", "Aug", "18", and "18" are successfully passed on to the script.

Now, this script is designed to be executed on a remote machine but, from a local directory on the local machine. Example:

ssh root@remoteServer "bash -s" < /var/www/html/ops1/sysMole

That also works fine. But the problem arises when I try to include those aforementioned arguments (-time Aug 18 18), for example:

ssh root@remoteServer "bash -s" < /var/www/html/ops1/sysMole -time Aug 18 18

After running that script I get the following error:

bash: cannot set terminal process group (-1): Invalid argument
bash: no job control in this shell

Please tell me what I'm doing wrong, this greatly frustrating.

Best Answer

You were pretty close with your example. It works just fine when you use it with arguments such as these.

Sample script:

$ more ex.bash 
#!/bin/bash

echo $1 $2

Example that works:

$ ssh serverA "bash -s" < ./ex.bash "hi" "bye"
hi bye

But it fails for these types of arguments:

$ ssh serverA "bash -s" < ./ex.bash "--time" "bye"
bash: --: invalid option
...

What's going on?

The problem you're encountering is that the argument, -time, or --time in my example, is being interpreted as a switch to bash -s. You can pacify bash by terminating it from taking any of the remaining command line arguments for itself using the -- argument.

Like this:

$ ssh root@remoteServer "bash -s" -- < /var/www/html/ops1/sysMole -time Aug 18 18

Examples

#1:

$ ssh serverA "bash -s" -- < ./ex.bash "-time" "bye"
-time bye

#2:

$ ssh serverA "bash -s" -- < ./ex.bash "--time" "bye"
--time bye

#3:

$ ssh serverA "bash -s" -- < ./ex.bash --time "bye"
--time bye

#4:

$ ssh  < ./ex.bash serverA "bash -s -- --time bye"
--time bye

NOTE: Just to make it clear that wherever the redirection appears on the command line makes no difference, because ssh calls a remote shell with the concatenation of its arguments anyway, quoting doesn't make much difference, except when you need quoting on the remote shell like in example #4:

$ ssh  < ./ex.bash serverA "bash -s -- '<--time bye>' '<end>'"
<--time bye> <end>
Related Question