आप Paramiko का उपयोग करके SSH रिटर्न कोड कैसे प्राप्त कर सकते हैं?


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

क्या कमांड रिटर्न कोड प्राप्त करने का कोई तरीका है?

सभी stdout / stderr को पार्स करना और यह जानना मुश्किल है कि कमांड सफलतापूर्वक पूरा हुआ या नहीं।

जवाबों:


51

SSHClient पैरामिको में अधिक निचले स्तर की कार्यक्षमता के आसपास एक साधारण आवरण वर्ग है। API दस्तावेज़ एक सूचीबद्ध करता है recv_exit_status()पर विधि Channelवर्ग।

एक बहुत ही सरल प्रदर्शन स्क्रिप्ट:

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()

इसके निष्पादन का उदाहरण:

$ 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
यह एक बुरा उपाय है। नीचे देखें @apdastous ', यह बहुत बेहतर है।
पैट्रिक

जब आप सही होते हैं recv_exit_status, तो आप इसे इस तरह से उपयोग नहीं कर सकते, क्योंकि कोड गतिरोध हो सकता है। आपको कमांड आउटपुट का उपभोग करना होगा, जबकि कमांड खत्म होने का इंतजार करना होगा। Paramiko ssh मरना / बड़े आउटपुट के साथ लटका हुआ देखना ।
मार्टिन प्रीक्रिल

282

एक बहुत आसान उदाहरण जिसमें "निचले स्तर" चैनल वर्ग को सीधे शामिल करना शामिल नहीं है (अर्थात - कमांड का उपयोग नहीं करना client.get_transport().open_session()):

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
इस उदाहरण के बारे में क्या अच्छा है, न केवल EXIT (जैसे प्रश्न पूछता है) पर कब्जा कर रहा है, लेकिन आप अभी भी STDOUT और STDRR प्राप्त कर सकते हैं। वर्षों पहले मुझे पैरामिको के एनेमिक उदाहरण कोडबेस (कोई अनादर) से गुमराह नहीं किया गया था, और एक्ज़िट पाने के लिए मैंने निम्न-स्तरीय परिवहन () कॉल का सहारा लिया। परिवहन () आपको "एक लेने" के लिए मजबूर करने के लिए लग रहा था (जो सच नहीं हो सकता है, लेकिन उदाहरणों और ट्यूटोरियल डॉक्स की कमी ने मुझे यह विश्वास करने के लिए प्रेरित किया कि ...)
स्कॉट प्रिव

जब आप सही होते हैं recv_exit_status, तो आप इसे इस तरह से उपयोग नहीं कर सकते, क्योंकि कोड गतिरोध हो सकता है। आपको कमांड आउटपुट का उपभोग करना होगा, जबकि कमांड खत्म होने का इंतजार करना होगा। Paramiko ssh मरना / बड़े आउटपुट के साथ लटका हुआ देखना ।
मार्टिन प्रीक्रिल

5

JanC के लिए धन्यवाद, मैंने उदाहरण के लिए कुछ संशोधन जोड़े और पायथन 3 में परीक्षण किया, यह वास्तव में मेरे लिए उपयोगी है।

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 () में? क्या chan.recv_stderr (4096) .decode ('ascii') यह एक संदेश पाठ लौटाता है?
kten

0

मेरे मामले में, आउटपुट बफरिंग समस्या थी। बफरिंग के कारण, एप्लिकेशन से आउटपुट नॉन-ब्लॉकिंग तरीके से नहीं निकलता है। आप यहाँ बफ़रिंग के बिना आउटपुट प्रिंट करने के बारे में जवाब पा सकते हैं: आउटपुट बफ़रिंग अक्षम करें । संक्षेप में, बस इस तरह से -u विकल्प के साथ अजगर चलाएं:

> python -u script.py

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.