Shell script: ssh to remote machine, then exit: 'exit' does not work
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.
Marius Hofert
Updated on September 18, 2022Comments
-
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
anddate: Undefined variable.
-
Marius Hofert almost 10 yearsHi 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 almost 10 yearsHi, thanks for helping, I checked the script and I had two newlines there, so that wasn't the issue.
-
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 almost 10 yearsIn 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 almost 10 yearsThe 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 almost 10 yearsThe
...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 theUnmatched '.
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 almost 10 yearsIs 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 almost 10 yearsHi,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 actualrsync
command is a bit more tricky, but that shouldn't play a role. -
Ctark almost 10 yearsTake 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 almost 10 yearsIf I do that (and have the linebreaks accordingly; see the update above), I get
bash: -c: option requires an argument
anddate: Undefined variable.
. -
Ctark almost 10 yearsAssuming 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 almost 10 yearsWhen I move
date
"inside", I obtaineddate: Undefined variable
. As this was a shell issue, I included the statementbash
right before thedate
variable (in order to change to a bash so that thedate
is defined), but then I obtainedbash: -c: option requires an argument
. -
R J almost 10 yearsHi 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 almost 10 yearsEven 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 about 7 yearsThanks! 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 about 7 yearsI have a question regarding this: unix.stackexchange.com/questions/362203/…. Will be beautiful if you could explain this there.
-
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.