Shell script: ssh to remote machine, then exit: 'exit' does not work

66,136

Solution 1

This should solve your problem.

ssh [email protected] << 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 [email protected] '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

Solution 2

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.

Solution 3

You can do

$ssh user@comp echo abc<ENTER>

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

Solution 4

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 [email protected] "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 [email protected]:/u3/mylogin/backup/$date\_backup
ssh [email protected] '
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.

Share:
66,136
Marius Hofert
Author by

Marius Hofert

Updated on September 18, 2022

Comments

  • Marius Hofert
    Marius Hofert almost 2 years

    I have a shell script of the following type:

    #!/bin/bash
    
    ssh [email protected]
    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 [email protected]:/u3/mylogin/backup/$date\_backup
    ssh [email protected] 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.

  • Marius Hofert
    Marius Hofert almost 10 years
    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
    Marius Hofert almost 10 years
    Hi, thanks for helping, I checked the script and I had two newlines there, so that wasn't the issue.
  • Marius Hofert
    Marius Hofert almost 10 years
    ... but indeed you are right. If I put everything in one line, the 'exit' works. Hmmm... but the script is then not readable anymore :-( can one use curly braces or some kind of grouping?
  • Ctark
    Ctark almost 10 years
    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
    Ctark almost 10 years
    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.
  • Marius Hofert
    Marius Hofert almost 10 years
    The ...batch -c approach is best (as it also solves another minor issue I had with the script). However, the observation remains: If I write the statements on different lines, I get the Unmatched '. errors/warnings. Only if I write them on the same line (;-separated), then it fully works. Strange (?) as it seemed to work on the website you point to.
  • Ctark
    Ctark almost 10 years
    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.
  • Marius Hofert
    Marius Hofert almost 10 years
    Hi,I updated the original post with a not-so-minimal version. As you can see, it's essentially a script for doing a backup to a remote machine via rsync. The actual rsync command is a bit more tricky, but that shouldn't play a role.
  • Ctark
    Ctark almost 10 years
    Take out the double quotes from the start and end, making it: ssh [email protected] bash -c ' rm -f /u3/mylogin/backup/old_backup ln -s $date\_backup /u3/mylogin/backup/old_backup exit ' Test with just something simple like that, if it starts working, then add things until it breaks, and go from there.
  • Marius Hofert
    Marius Hofert almost 10 years
    If I do that (and have the linebreaks accordingly; see the update above), I get bash: -c: option requires an argument and date: Undefined variable..
  • Ctark
    Ctark almost 10 years
    Assuming your updated script is all you are doing, can you move the date variable into the ssh, and remove the bash -c? See my updated answer for what I mean.
  • Marius Hofert
    Marius Hofert almost 10 years
    When I move date "inside", I obtained date: Undefined variable. As this was a shell issue, I included the statement bash right before the date variable (in order to change to a bash so that the date is defined), but then I obtained bash: -c: option requires an argument.
  • R J
    R J almost 10 years
    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.
  • Ctark
    Ctark almost 10 years
    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.
  • Sibbs Gambling
    Sibbs Gambling about 7 years
    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
    Sibbs Gambling about 7 years
    I have a question regarding this: unix.stackexchange.com/questions/362203/…. Will be beautiful if you could explain this there.
  • barlop
    barlop about 7 years
    @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.