4

I've read several posts on here about this topic but every solution I find seems to be a one liner where you run one command.

I'm creating a script where I ssh to several different hosts one after a time. The goal is to ssh to a machine, do some local commands, execute a a script, wait for it to finish and then exit the ssh session and move on to the next.

However, when I use the "exit" command it does not work and just exits the script altogether.

Joshua
  • 179
  • 1
  • 3
  • 12
  • 6
    **Show us your script.** The `exit` command will exit an ssh session, if you are within an ssh connection. Most likely you have your exit in the wrong place or something. – Zoredache Jan 19 '17 at 18:33
  • 2
    It sounds like you're executing the `exit` command on the local machine, not sending it to the remote machine. I'm not sure why you need it at all. `ssh hostname "command1; command2; command3"` should execute the sequence of command and then close the connection. – Barmar Jan 19 '17 at 20:10

7 Answers7

3

I guess that your script is not exiting the shell session because you are calling it directly with ./exit.sh. You should source it instead.

An exit statement in your script will then close the shell session.

$ source exit.sh
# or
$ . exit.sh

The source builtin executes your script in the current shell context, while ./exit.sh launches a new shell to run it.

Lensys
  • 41
  • 3
2

Have you tried to put the commands in a file and use cat with it or EOF

ssh -t me@server1.com << EOF
 command1
 command2
 exit
EOF
Talal Al-Khalifa
  • 668
  • 5
  • 12
1

I'd recommend looking at pssh for what you are trying to accomplish - it allows you to easily handle the nuances of opening/closing connections across machines, and can even run in parallel to reduce execution time.

It still uses ssh as the transport protocol, so it's obviously just as secure as a looped ssh connection.

https://linux.die.net/man/1/pssh

Brennen Smith
  • 1,742
  • 8
  • 11
0

I will normally do this for my nodes.

Assuming your node list is in a file /tmp/serverlist:

server001
server002
server003
server004
server005
server006

Assuming I want to run through the servers from 001-006:

#!/bin/bash

LINUX_COMMAND='uptime'

for i in `cat /tmp/serverlist`
do
    ssh ${i} ${LINUX_COMMAND}
done
0

You can usually do a for loop with ssh without problems.

$ for srv in 192.168.88.138; do echo $srv:; ssh $srv uptime; done
192.168.88.138:
 13:27:25 up 30 days,  8:42,  1 user,  load average: 4.15, 4.06, 4.06

So in this case I ran uptime on the other side. You can replace uptime with what you want to run. Whatever you put there is where the exit needs to be. uptime exits once it prints its output, but if you are writing the script you may need to make sure it eventually exits so the for loop can continue.

If you're doing anything complicated I'd recommend creating the script in a separate file and then scping it to the server you want to run it on then ssh in to run it. Trying to get something complicated into ssh via quoting and escapes is more challenging than it is worth usually.

I've done this hundreds of times and it works fine when you want things to run on one server at a time. If you want things to run in parallel there are other options, but I'd look at first.

chicks
  • 3,793
  • 10
  • 27
  • 36
0

So this works, after trying out about a dozen things online. I came up with the idea to find my ssh session, within my ssh session, and kill it

Within my script:

ssh ${blah} "/usr/bin/run_some_command ; ps -fu myUsername | grep -i MySSHconnection | grep -v grep | awk '{print \$2}'| xargs -i kill -9 {} "
Cory Knutson
  • 1,876
  • 13
  • 20
-1

Are you trying to do the same thing to many hosts in parallel, or are you using results of commands run on one host to decide what to do in the next host?

If you are trying to run commands on multiple hosts in parallel, that is what rsh was created for. These days, rsh is considered to be very low security, so the more current and correct option for this would be pdsh. You would rewrite your shell script to be what the run would be on a single host, then use pdsh to execute that script on many hosts.