Завершить удаленный сеанс через определенное время, если на удаленном сервере с использованием Paramiko не было получено ответа от команды - PullRequest
1 голос
/ 21 ноября 2019

У меня возникли некоторые проблемы с модулем Paramiko при выполнении команды на удаленном сервере.

def check_linux(cmd, client_ip, client_name):
    port = 22
    username = 'xxxxxxx'
    password = 'xxxxxxxx'
    try:
        sse = paramiko.SSHClient()
        sse.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        sse.connect(client_ip, port, username, password, timeout=5)
        (stdin, stdout, stderr) = sse.exec_command("my cmd")
        del stdin
        status = stdout.read()
        status = status.decode('ascii')
        return status
    except (paramiko.SSHException, socket.error, socket.timeout, Exception) as error:
        print "Unable to Authenticate/logon:" ,client_name,client_ip,
        sys.exit()
[root@xxxxxxx star_script]# python
Python 2.7.5 (default, Oct 11 2015, 17:47:16)
[GCC 4.8.3 20140911 (Red Hat 4.8.3-9)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import paramiko
>>> port = 22
>>> username = 'xxxxxxxx'
>>> password = 'xxxxxxxxxx'
>>> client_ip = 'xxxxxxx'
>>> cmd = 'openssl s_client -connect xxxxxxx:xxxxx'
>>> sse = paramiko.SSHClient()
>>> sse.set_missing_host_key_policy(paramiko.AutoAddPolicy())
>>> sse.connect(client_ip, port, username, password, timeout=5)
>>> (stdin, stdout, stderr) = sse.exec_command(cmd)
>>> status = stderr.read()

Для некоторых серверов выполнение команд не происходит, и программа не выполняется в дальнейшем. Я пробовал readlines() и stdout.channel.eof_received, но оба, кажется, не работают.

1 Ответ

1 голос
/ 22 ноября 2019

.read будет ожидать завершения команды, чего она никогда не делает.

Вместо этого дождитесь завершения команды в первую очередь. Если это занимает слишком много времени, убейте команду (используя stdout.channel.close()).

Вы можете использовать код из Python Paramiko exec_command timeout не работает? :

timeout = 30
import time
endtime = time.time() + timeout
while not stdout.channel.eof_received:
    time.sleep(1)
    if time.time() > endtime:
        stdout.channel.close()
        break
status = stdout.read()
...