2

I have a shell script of the following type:

#!/bin/bash

ssh mylogin@myremotemachine.com
echo "Hi"
exit

I run it locally to do something on a remote server (represented by 'echo "Hi"'). However, when I run it, I see the prompt on the remote server -- so the 'exit' command is not executed. When I then manually type 'exit' on the remote prompt, I then see "Connection to myremotemachine.com" closed and then "Hi". How can I set up the shell script such that it exits correctly and shows me the (local) prompt from which I executed it?

https://unix.stackexchange.com/questions/89747/ssh-exits-after-quit-case-in-bash-script and ssh and shell through ssh : how to exit? seem somewhat related, but I couldn't adapt the ideas presented there./

UPDATE

The following, not so minimal version leads to Unmatched '..

#!/bin/bash

date=`date "+%Y-%m-%d"`
rsync -acxzP --delete --link-dest=/u3/mylogin/backup/old_backup /home/mylogin mylogin@myremotemachine.com:/u3/mylogin/backup/$date\_backup
ssh mylogin@myremotemachine.com bash -c "'
rm -f /u3/mylogin/backup/old_backup
ln -s $date\_backup /u3/mylogin/backup/old_backup
exit
'"

If I remove the double quotes in this snippet, I get: bash: -c: option requires an argument and date: Undefined variable.

7

This should solve your problem.

ssh mylogin@myremotemachine.com << HERE
rm -f /u3/mylogin/backup/old_backup
ln -s $date\_backup /u3/mylogin/backup/old_backup
HERE

Or you can do the following. Put all the commands you want to run on the remote host in a separate script. Give it a name like remote.sh

Now run the following

ssh mylogin@myremotemachine.com 'bash -s' < /path/to/remote.sh

Where remote.sh contains.

rm -f /u3/mylogin/backup/old_backup
ln -s $date\_backup /u3/mylogin/backup/old_backup
| improve this answer | |
  • 1
    Hi R J, thanks for helping. I prefer the first solution (I was aware of the second). However, I get Pseudo-terminal will not be allocated because stdin is not a terminal. Warning: no access to tty (Bad file descriptor). Thus no job control in this shell. But the commands are executed as expected. – Marius Hofert Sep 9 '14 at 1:52
  • 1
    Hi Marius. That is a friendly reminder from ssh that what is being executed is a script under a job that has no access to TTY, instead of the usual expected binary. Therefore you cannot interrupt it using Ctrl + c or suspend it using Ctrl + z or other interactive commands. It is harmless and can safely be ignored. – R J Sep 9 '14 at 7:43
1

You can do

$ssh user@comp echo abc<ENTER>

then it will run that command (outputting abc), and exit

| improve this answer | |
  • Thanks! Is this equivalent to adding a newline character at the end of a script to simulate the carriage enter? Sometimes everything works even without this. When is this a must? I have a question regarding this: unix.stackexchange.com/questions/362203/…. Will be beautiful if you could explain this there. – Sibbs Gambling Apr 30 '17 at 2:44
  • @SibbsGambling i'm not sure if you misunderstood.. <ENTER> means push the enter key.. Re new lines at the end of a script, i'm not sure, I don't use *nix that much. – barlop Apr 30 '17 at 10:51
1

Maybe you have no newline at the end of script?

If there is no empty line (exactly LF - line feed character) after exit - your script will not "press enter" programatically.

| improve this answer | |
1

Although barlops answer is correct, I think we can expand on it, to make it more clear. Since you seem to be using a script, I would suggest something like this:

#!/bin/bash

ssh mylogin@myremotemachine.com "echo Hi\!"

Extra reading: I also suggest you also look into special characters and when you need to escape them, as bash will automatically parse exclamation marks, when in double quotes. You can solve this by either using single quotes, or the backslash character to 'escape' it.

Edit:

#!/bin/bash
date=`date "+%Y-%m-%d"`
rsync -acxzP --delete --link-dest=/u3/mylogin/backup/old_backup /home/mylogin mylogin@myremotemachine.com:/u3/mylogin/backup/$date\_backup
ssh mylogin@myremotemachine.com '
date=`date "+%Y-%m-%d"`
rm -f /u3/mylogin/backup/old_backup
ln -s $date\_backup /u3/mylogin/backup/old_backup
'

When I tried a simplified version, the date variable works without issue, maybe this will correct the bash -c issue you were having. Also the exit is unneeded at the end, when the last command is executed the ssh session is automatically closed.

| improve this answer | |
  • Hi Ctark, thanks for helping. There are no special characters involved Obviously, the 'echo' here is just a minimal example; there are various lines of code to be executed remotely. I'm thus not sure how much this "writing everything in one line" should help... there are indeed several lines of code – Marius Hofert Sep 7 '14 at 1:20
  • 1
    In that case I would suggest this link: unixmantra.com/2014/03/… It seems to have basically what you are asking. (I could copy paste, but there is a lot of info, and it walks you through WHY it works, so you learn too!) – Ctark Sep 7 '14 at 1:30
  • 1
    The easiest way would be to just use the ssh with single quotes, BUT if you have any other single quotes in the rest of the script you want to use, then it will mess up. If you can change all single quotes in the script you want to run to double quotes, then just a simple: ssh $host 'line 1 line2 line3 "some params" ' At the end of that article the author talks about trying to use single quotes, but it doesn't seem to like that very much, and he doesn't talk about a resolution. Basically unless you need variables or single quotes, you can just use the first example. – Ctark Sep 7 '14 at 2:03
  • 1
    Is it possible for you to post the different lines, it sounds like some of them use single quotes in them. If they do, that is where you are getting your unmatched ' errors. If you use semicolons, then you don't have the open/close single quote. I can't do anymore until I see the code you are using. – Ctark Sep 7 '14 at 3:10
  • 1
    Even though you found a different way, updated answer for anyone else that stumbles across this. the reason you were getting undefined variable is due to the rsync command using date, so you need it both inside and outside the ssh script (unless you use bash -c, and if you do you get other issues). Glad you finally found a solution that worked, sorry my solution kept having bugs. – Ctark Sep 9 '14 at 20:09

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.