简体   繁体   中英

Create and maintain several ssh sessions in Python

Once my program has been launched, it opens any number of ssh sessions (user defined) and runs specific commands on the servers indefinitely (while true loop) or until the user quits. For efficiency reasons I want to create each session only once, then be able to run the commands until the user quits.

How can I do this in python? I ran across a cool method in another post which used subprocess to run a command and capture its STDOUT. How can I first initiate the session, then run looped commands?

Any links to process-like stuff in Python would also be appreciated. This is my first python application.

Ignoring Python for the moment, you can multiplex ssh sessions by adding this

ControlMaster auto
ControlPath /tmp/ssh_mux_%h_%p_%r
ControlPersist 1h

to your ~/.ssh/config file. After connecting to a machine once, the ssh session to this machine will stay open, and subsequent commands will execute on this machine near-instantaneously thereafter. You could then use Python subprocess to call ssh and execute commands on that machine as-needed, and the session will be reused without having to do anything special.

You could also call ssh with the -F flag pointing to an alternate config file, if you'd rather not make the session multiplexing the default behavior (or you're deploying for other users who might not have it as their default).

OPTION 1: You can re-use a ssh process by redirecting input using a PIPE.

Here is a basic example:

[(Z) </tmp> ]% touch input_file
[(Z) </tmp> ]% tailf input_file | ssh <remote_host>

Now try writing something into the file

[(Z) </tmp> ]% echo "date" >> /tmp/input_file

Here is a way to make use of this in Python using subprocess module.

import subprocess
SSH_CMD = "cat -| /usr/bin/ssh -o PasswordAuthentication=no -T -x %s "
HOSTNAME = "127.0.0.1"
s = subprocess.Popen(SSH_CMD%HOSTNAME , shell=True, close_fds=True, 
stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE)

This starts a subprocess which can be re-used. Please note that close_fds=True is required because of a known bug ( http://bugs.python.org/issue2320 ).

>>> REMOTE_CMD = "date"
>>> s.stdin.write( REMOTE_CMD +
... "\necho 'remote command completed with exit code = '$?\n")
>>> s.stdout.readline()
'Thu Feb 16 20:01:36 PST 2012\n'
>>> s.stdout.readline()
'remote command completed with exit code = 0\n'

echo 'remote command completed with exit code = '$?\\n line is used to know that the remote command finished and it is done writing to s.stdout. This is also useful to know the exit code of the remote command.

To use the same subprocess for executing another remote command:

>>> REMOTE_CMD = "uptime"
>>> s.stdin.write( REMOTE_CMD +
... "\necho 'remote command completed with exit code = '$?\n")
>>> s.stdout.readline()
' 20:02:17 up 28 days,  9:15, 48 users,  load average: 0.01, 0.02, 0.05\n'
>>> s.stdout.readline()
'remote command completed with exit code = 0\n'

Coming back to your question, once you create a ssh subprocess, you can keep sending the remote commands. Once the user is quits, you can kill the subprocess.

>>> s.kill()

OPTION 2: I have never used this, but ssh has a ControlMaster option for re-using ssh. Check man page for ssh_config(5)

Try using pexpect module. It allows opening and maintaining ssh sessions, which you can reuse to send in multiple commands. You can send in any commands and expect particular outputs based on which you can perform other logical operations.

尝试将它与多线程混合起来?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM