-
Book Overview & Buying
-
Table Of Contents
-
Feedback & Rating
Python Network Programming Techniques
By :
In the previous recipes, we have always only dealt with a single command that we wanted to execute. Maybe you have tried adding another call to the exec_command() function to the client already and have run into an error telling you that the session is closed. It is indeed correct that, once your command is done executing, the connection will close.
But quite often we don't want to execute only one but a sequence of commands one after another. We could reconnect for each of the commands, but this is a workaround that would create a lot of unneeded disconnecting and reconnecting. What we can do instead is, if the target device's configuration allows it, open up a shell session. This shell session is a single command, and we can then use stdin, stderr, and stdout to send multiple commands in the same session.
In this recipe, you will see how to programmatically open an SSH connection to a device, open a shell, and then send a list of commands to the device before closing the connection.
Open your code editor and start by creating a file called exec_multiple_commands.py. Next, navigate your terminal to the same directory that you just created the exec_multiple_commands.py file in.
Let's start by creating our credentials file. We will then read that file from our Python script, create clients for each of these devices, and finally execute a command while also saving the output back to our file:
time library:from paramiko.client import SSHClient import time
SSH_USER = "<Insert your ssh user here>" SSH_PASSWORD = "<Insert your ssh password here>" SSH_HOST = "<Insert the IP/host of your device/server here>" SSH_PORT = 22 # Change this if your SSH port is different
SSHClient object, which we just imported from Paramiko: client = SSHClient()
connect method of the client object to do so. Before actually connecting, we will need to make sure that our client knows the host keys: client.load_system_host_keys() client.connect(SSH_HOST, port=SSH_PORT, username=SSH_USER, password=SSH_PASSWORD)
channel = client.get_transport().open_session() shell = channel.invoke_shell()
commands = [ "configure terminal", "hostname test" ]
for cmd in commands: shell.send(cmd + "\n") out = shell.recv(1024) print(out) time.sleep(1)
client.close()
python3 exec_multiple_commands.py
In this example, we use Paramiko's concept of an interactive shell to send multiple commands to the remote device one after another.
When invoking a shell with Paramiko, we will retrieve a channel. This channel was used by Paramiko in the background all along to execute our commands but has been hidden from us so far. The channel takes care of low-level aspects such as sending and receiving the data to and from the raw network connection to our device. The channel function we use in this example is the send() function, which sends a string to the remote device. Mind the carriage return we added to the command. The same way you, when connecting to a device via SSH, have to execute a command by typing enter, the interactive session has to indicate that via a linebreak, which is the same symbol sent by your interactive session when hitting the Enter key.
We are using the sleep function here to wait for the commands you have passed to have finished executing. For short-running commands, you can get away with not using this sleep function.