Background (nohup * &) SSH command block possible?

Hello,
I am trying to find a way to send several sequential commands via SSH to a remote box in a single command.
Thoughts so far:

1) Can I put them into a function and call the function within the ssh command?

e.g.

ssh <targetserver> $(functionx)

No - then it calls the function in the shell on the target and does not recognised it.

2) Can I use a command block?

e.g.

ssh <targetserver> << EOF
echo 1
echo 2
date
EOF

Hmmm - maybe, but I get these messages:

"Pseudo-terminal will not be allocated because stdin is not a terminal"
(and on target)
"Warning: no access to tty (Bad file descriptor).
Thus no job control in this shell."

Actually then is does run the commands BUT I'm not sure it's solid.
my final target is that I want to run this whole command in the background --- when I try and do this with nohup I still see these errors
E.g.

nohup ssh <targetserver> << EOF > <log> &
echo 1
echo 2
date
EOF
"Pseudo-terminal will not be allocated because stdin is not a terminal"
(and on target)
"Warning: no access to tty (Bad file descriptor).
Thus no job control in this shell."

3) Create a shell script on the target and call that...
this option does work but I really want to find a way to centralise this script so that I don't have to stick the second script on every server I want to connect to.

I think it's quite an interesting one - can anyone advise on the best possible method for generating a set of commands to execute on a remote box via ssh; but with one SSH command?

NB It cannot be several SSH commands as I need this to both be run in the background and also for the commands to be sequential.

Thanks in advance!
Jamie Neilan

To keep the forums high quality for all users, please take the time to format your posts correctly.

First of all, use Code Tags when you post any code or data samples so others can easily read your code. You can easily do this by highlighting your code and then clicking on the # in the editing menu. (You can also type code tags

```text
 and 
```

by hand.)

Second, avoid adding color or different fonts and font size to your posts. Selective use of color to highlight a single word or phrase can be useful at times, but using color, in general, makes the forums harder to read, especially bright colors like red.

Third, be careful when you cut-and-paste, edit any odd characters and make sure all links are working property.

Thank You.

The UNIX and Linux Forums

That would call the function locally, and feed its output into ssh.

Still, you cannot, since functions aren't exported across ssh calls. It's like running a fresh script. It knows nothing about your functions or environment...

Yes. You won't be able to use standard input for anything else, though.

It means what it says. stdin is not a terminal, it's a here-document, so it doesn't allocate a pseudo-tty.

Other than that, there's nothing wrong with it.

Nothing's actually going wrong. The shell's just complaining since its input isn't an interactive terminal.

They're not errors, they're warnings.

I think you can avoid the warnings by running the shell in a manner so it doesn't expect stdin to be a terminal.

ssh username@host /bin/sh -s <<EOF
...
EOF

If you want the deluxe version, the one I tend to use:

ssh username@host exec /usr/bin/env sh -s "arg1" "arg2" "arg3" <<"EOF"
echo "First argument is $1"
echo "Second argument is $2"
echo "Third argument is $3"
EOF

Running sh in this way should be quite safe, and using <<"EOF" makes sure nothing gets substituted into the here document, no substitution at all. The only way you can transfer in variables is with the "arg1" "arg2" "arg3" there, which become $1 $2 $3 ...

1 Like

A quick, and wonderful response - thank you - one more thing though. How would you run your final version there in the background (so if it's in a script that script can continue on while that code runs?)

Perhaps like this?

nohup ssh username@host exec /usr/bin/env sh -s "arg1" "arg2" "arg3" <<"EOF" > logfile.log &
echo "First argument is $1"
echo "Second argument is $2"
echo "Third argument is $3"
EOF

Not sure if I really need the nohup and the ampersand ...... have tried the ssh -f option to fork to background but doesn't seem to like that..

---------- Post updated at 21:54 ---------- Previous update was at 21:45 ----------

In Fact I think I have it! Returning to my post syntax updating with your input I have running - awesome!

nohup ssh -q <targetserver> exec /usr/bin/ksh -s << EOF > <log> &
echo 1
echo 2
date
EOF

Works a treat! No output to my STOUD/screen (thanks to -q option on ssh) and the log is generated locally from commands passed to the remote box using an code block - absolute genuis - many thanks Corona688. I am indebted to you.

---------- Post updated 27-04-12 at 10:19 ---------- Previous update was 26-04-12 at 21:54 ----------

*UPDATE*

I have found now that while this works for simple commands I include a FOR loop within the EOF code-block and it errors as follows (below) - any ideas??

nohup ssh -q <targetserver> exec /usr/bin/ksh -s << EOF > <log> &
echo 1
echo 2
date
testvar="a b c"
for i in ${testvar}
do
 echo $i
done
EOF

Error is :

/usr/bin/ksh: syntax error at line X : `newline or ;' unexpected

---------- Post updated at 10:32 ---------- Previous update was at 10:19 ----------

Ah-ha! You can use $() to execute code in a here document. OK so here is ht working fix to that:

nohup ssh -q <targetserver> exec /usr/bin/ksh -s << EOF > <log> &
echo 1
echo 2
date
$(
testvar="a b c"
for i in ${testvar}
do
 echo $i
done
)
EOF
1 Like

Instead of nohup consider at which does all of the exec, etc., for you:

ssh <remotenode> ' at -k now <<!
echo 1
echo 2
! '

This runs the list of commands using ksh.