Reputation: 13
I'm working my way through Python and I'm getting my way through the basics. Now, the main goal of the code is to automate tasks using SSH (in this case for example using Paramiko), do some unrelated actions after that, and then do tasks on the same devices again, but without setting up a new session. The Paramiko part works, the code works fine for a single device but now I am stuck. Lets say I have the following:
for host in hosts:
sshclient = paramiko.SSHClient()
sshclient.connect(host, port=22, username=user, password=password)
cmd = sshclient.invoke_shell()
So this will loop through the hosts list and connect to the devices. But now, later on in the code, outside of this for loop, I need another loop that will send commands on all devices like:
for some in data:
cmd.send("some command")
But when I do that, it only uses the last host it connected to as the cmd variable is declared and remembered in the first for loop. I can fix that by setting up a new "connect" in the latter for loop, but Paramiko builds a session and with too many iterations in the list the number of sessions become too large. So I want to reuse the cmd variable and create new variables in the first for loop for each session(?), or am I thinking completely wrong?
Can anyone help me how to solve this?
Thanks a lot.
Upvotes: 1
Views: 326
Reputation: 13106
You could aggregate all of your cmd
vars into a list
to be looped over later:
cmds = []
for host in hosts:
sshclient = paramiko.SSHClient()
sshclient.connect(host, port=22, username=user, password=password)
cmds.append(sshclient.invoke_shell())
# Now you can iterate over them
for cmd in cmds:
cmd.send("some command")
If you're worried about the number of simultaneously open connections, you could generate them as needed:
def create_cmds(hosts):
for host in hosts:
sshclient = paramiko.SSHClient()
sshclient.connect(host, port=22, username=user, password=password)
yield sshclient
sshclient.close() # close invoked here automatically on call to next() with for loop
for client in create_cmds(hosts):
cmd = client.invoke_shell() # an open method was called here
cmd.send('some command')
As noted here you will want to invoke client.close
in order to prevent weird shutdown errors
Upvotes: 5