1

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.

1 Answer 1

5

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

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot, that works fine. I thought I tried a new list already, but apparently not correctly. Much appreciated!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.