Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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.

share|improve this question
    
"Bash -s" is one of the ways you can execute an script from standard input (ie. a file). – AllenD Aug 20 '13 at 1:54
up vote 65 down vote accepted

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>
share|improve this answer
    
you are an Genius! What do I have to do to get to your level? I have alot of work cut out. Thanks so much. – AllenD Aug 20 '13 at 2:21
4  
@AllenD - just keep asking questions, and try and participate on the site as much as you can. I always try and learn something new each day. Before your question I didn't know how to do this either. 8-). Thanks for your question! – slm Aug 20 '13 at 2:25
3  
note that the redirection can appear at any point in the command: for example bash -s -- --time bye < ./ex.bash or even < ./ex.bash bash -s -- --time bye. this is because the shell first takes out the redirection instruction (regardless of where it is in the command), then sets up the redirection, then executes the rest of the command line with the redirection in place. – lesmana Aug 20 '13 at 9:30
    
@sim I'm trying to do this exact same thing, but from within a script, not from the command line. Any idea of how to do this? For some reason, enclosing your exact answer in backticks does not work at all. It instead runs the script specified locally, and the output is sent as a command to the bash over ssh – krb686 Mar 3 '15 at 21:42
    
@krb686 - I'd ask it as a new Q. – slm Mar 4 '15 at 1:33

say a.a is a local file that contains ls

$ssh servername "cat | bash" < a.a

change 127.0.0.1 to whatever your remote ip is

these two give a message about pseudo tty allocation but they work.

$ cat a.a | ssh 127.0.0.1

$ ssh 127.0.0.1 <a.a

Or

$ cat a.a | ssh 127.0.0.1 bash or

$ ssh 127.0.0.1 bash < a.a

share|improve this answer
1  
I'm struggling to see in how far this answers the question. – ChrisWue Sep 8 at 1:39
    
The quality and formatting is doubtful. I don't see any new useful information that's not present in the accepted answer either. – Julie Pelletier Sep 8 at 4:07
    
@JuliePelletier I gave some 'cat' examples not in the accepted answer. It's good to know alternative ways of doing things. – barlop Sep 8 at 5:18
    
That's not a good thing; your cats are useless. – Scott Sep 8 at 5:20
    
@Scott To say they're useless is ambiguous.. They work in passing the script a.a to the remote machine. It may be that it's probably unnecessary..and I see a big flaw with my answer, in that I didn't look into/cover passing arguments, and the question requests that.. I found my first example interesting.. the shell passes a.a to ssh which then sees cat awaiting stdin and it passes it to that, at least seems that way to me anyway! – barlop Sep 8 at 5:36

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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