Paramiko kullanarak SSH dönüş kodunu nasıl elde edebilirsiniz?


97
client = paramiko.SSHClient()
stdin, stdout, stderr = client.exec_command(command)

Komut dönüş kodunu almanın bir yolu var mı?

Tüm stdout / stderr'i ayrıştırmak ve komutun başarıyla bitip bitmediğini bilmek zordur.

Yanıtlar:


51

SSHClient, Paramiko'daki daha düşük seviyeli işlevselliği çevreleyen basit bir sarmalayıcı sınıfıdır. API belgeleri bir listeler recv_exit_status()üzerinde yöntemini Channelsınıfına.

Çok basit bir tanıtım betiği:

import paramiko
import getpass

pw = getpass.getpass()

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.WarningPolicy())
client.connect('127.0.0.1', password=pw)

while True:
    cmd = raw_input("Command to run: ")
    if cmd == "":
        break
    chan = client.get_transport().open_session()
    print "running '%s'" % cmd
    chan.exec_command(cmd)
    print "exit status: %s" % chan.recv_exit_status()

client.close()

Uygulama örneği:

$ python sshtest.py
Password: 
Command to run: true
running 'true'
exit status: 0
Command to run: false
running 'false'
exit status: 1
Command to run: 
$

9
Bu kötü bir çözüm. Aşağıdaki @ apdastous'un cevabına bakın, çok daha iyi.
Patrick

Bu konuda recv_exit_statushaklıyken, kod kilitlenebileceği için bu şekilde kullanamazsınız. Komutun bitmesini beklerken komut çıktısını tüketmelisiniz. Büyük çıktı ile Paramiko ssh kalıp / askıya bakın .
Martin Prikryl

287

Doğrudan "alt düzey" kanal sınıfını çağırma içermeyen bir daha kolay bir örnek (yani - DEĞİL kullanarak client.get_transport().open_session()komutu):

import paramiko

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('blahblah.com')

stdin, stdout, stderr = client.exec_command("uptime")
print stdout.channel.recv_exit_status()    # status is 0

stdin, stdout, stderr = client.exec_command("oauwhduawhd")
print stdout.channel.recv_exit_status()    # status is 127

5
Ne var güzel (soru sorar gibi) sadece EXIT yakalayan Bu örnekte hakkında, ama yine de STDOUT ve STDERR alabilirsiniz göstererek. Yıllar önce Paramiko'nun anemik örnek kod tabanı tarafından yanıltıldım (saygısızlık yok) ve EXIT'i almak için düşük seviyeli taşıma () çağrılarına başvurdum. transport () sizi "birini seçmeye" zorluyor gibi görünüyordu (bu doğru olmayabilir, ancak örneklerin ve öğretici belgelerin olmaması buna inanmamı sağladı) ...
Scott Prive

Bu konuda recv_exit_statushaklıyken, kod kilitlenebileceği için bu şekilde kullanamazsınız. Komutun bitmesini beklerken komut çıktısını tüketmelisiniz. Büyük çıktı ile Paramiko ssh kalıp / askıya bakın .
Martin Prikryl

5

JanC için teşekkürler, örnek için bazı değişiklikler ekledim ve Python3'te test ettim, bu benim için gerçekten yararlı.

import paramiko
import getpass

pw = getpass.getpass()

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.WarningPolicy())
#client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

def start():
    try :
        client.connect('127.0.0.1', port=22, username='ubuntu', password=pw)
        return True
    except Exception as e:
        #client.close()
        print(e)
        return False

while start():
    key = True
    cmd = input("Command to run: ")
    if cmd == "":
        break
    chan = client.get_transport().open_session()
    print("running '%s'" % cmd)
    chan.exec_command(cmd)
    while key:
        if chan.recv_ready():
            print("recv:\n%s" % chan.recv(4096).decode('ascii'))
        if chan.recv_stderr_ready():
            print("error:\n%s" % chan.recv_stderr(4096).decode('ascii'))
        if chan.exit_status_ready():
            print("exit status: %s" % chan.recv_exit_status())
            key = False
            client.close()
client.close()

chan.recv_stderr_ready () içinde -varsa - herhangi bir hata mesajı alıyor muyuz ?. Chan.recv_stderr (4096) .decode ('ascii') bir mesaj metni döndürür mü?
kten

0

Benim durumumda, problem çıktı tamponlamasıydı. Arabelleğe alma nedeniyle, uygulamadan gelen çıktılar engellemesiz bir şekilde çıkmaz. Çıktının arabelleğe alınmadan nasıl yazdırılacağıyla ilgili cevabı burada bulabilirsiniz: Çıktı arabelleğini devre dışı bırakın . Kısaca, python'u -u seçeneğiyle şu şekilde çalıştırın:

> python -u script.py

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.