2010-08-25 26 views

Trả lời

42

SSHClient là lớp trình bao bọc đơn giản xung quanh chức năng cấp thấp hơn trong Paramiko. API documentation liệt kê một phương pháp recv_exit_status() trên lớp Kênh.

Một cuộc biểu tình rất đơn giản kịch bản:

$ cat sshtest.py 
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: 
$ 
+0

Thực sự đánh giá cao câu trả lời của bạn !! Tôi đã sử dụng nó trong dự án của tôi. Cảm ơn bạn rất nhiều. Cho đến nay tôi có thể sử dụng paramiko thay vì gói ssh lệnh hệ thống trong lập trình với python. – Beyonder

+0

Nó chỉ là một cái gì đó tôi đặt lại với nhau bằng cách nhìn vào nguồn của SSHClient, vì vậy nó có thể không được * tối ưu *. BTW: nếu điều này làm những gì bạn muốn, bạn có thể muốn "chấp nhận" câu trả lời của tôi. – JanC

+0

Liên kết chết Vui lòng cập nhật –

195

Dễ dàng hơn nhiều ví dụ mà không liên quan đến cách gọi lớp kênh trực tiếp:

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 
+29

Đây là giải pháp đúng cho câu hỏi. – gphilip

+1

Những gì * đẹp * về ví dụ này là chụp không chỉ EXIT (như câu hỏi yêu cầu), nhưng chứng tỏ bạn vẫn có thể nhận được STDOUT và STDERR. Nhiều năm trước, tôi đã bị nhầm lẫn bởi codebase ví dụ điển hình của Paramiko (không thiếu tôn trọng), và để có được EXIT tôi đã sử dụng các cuộc gọi vận chuyển cấp thấp(). transport() dường như buộc bạn phải "chọn một" (điều này có thể không đúng, nhưng thiếu các ví dụ và tài liệu hướng dẫn đã dẫn tôi tin rằng) ... –

5

Cám ơn JanC, tôi đã thêm một số thay đổi ví dụ và thử nghiệm trong Python3, nó thực sự hữu ích cho tôi.

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

chúng tôi có nhận được bất kỳ thông báo lỗi nào - nếu có - trong chan.recv_stderr_ready() ?. Liệu chan.recv_stderr (4096) .decode ('ascii') có trả về văn bản tin nhắn không? – kten

Các vấn đề liên quan