2009-08-05 69 views
73

Làm thế nào tôi có thể chỉ đơn giản là SSH đến một máy chủ từ xa từ một kịch bản Python (3.0) cục bộ, cung cấp một đăng nhập/mật khẩu, thực hiện một lệnh và in đầu ra cho bảng điều khiển Python?Cách đơn giản nhất để SSH bằng Python là gì?

Tôi không muốn sử dụng bất kỳ thư viện bên ngoài lớn nào hoặc cài đặt bất kỳ thứ gì trên máy chủ từ xa.

Trả lời

38

Tôi chưa thử, nhưng mô-đun pysftp này có thể trợ giúp, từ đó sử dụng paramiko. Tôi tin rằng mọi thứ đều ở phía khách hàng.

Lệnh thú vị có thể là .execute() thực hiện lệnh tùy ý trên máy từ xa. (Mô-đun cũng có các tính năng .get().put các phương pháp gợi ý nhiều hơn đến ký tự FTP của nó).

CẬP NHẬT:

Tôi đã viết lại câu trả lời sau bài đăng trên blog mà tôi đã liên kết ban đầu không còn nữa. Một số nhận xét liên quan đến phiên bản cũ của câu trả lời này giờ đây sẽ trông kỳ lạ.

+0

Tốt tìm! Miễn là bạn không quan tâm đến việc tùy chỉnh phản hồi lỗi, trừu tượng bổ sung này sẽ rất hữu ích. – Cascabel

+0

Mô-đun ssh đã thực hiện thủ thuật. Đơn giản và hoạt động tốt. Không tìm kiếm thông qua API Paramiko. –

+2

Liên kết đến tệp ssh.py bên trong liên kết bạn cung cấp bị hỏng:/ – dgorissen

8

Định nghĩa của bạn "đơn giản nhất" là quan trọng ở đây - mã đơn giản có nghĩa là sử dụng một mô-đun (mặc dù "thư viện bên ngoài lớn" là một cường điệu).

Tôi tin rằng mô-đun cập nhật nhất (được phát triển tích cực) là paramiko. Nó đi kèm với các kịch bản demo trong quá trình tải xuống và có tài liệu API trực tuyến chi tiết. Bạn cũng có thể thử PxSSH, được chứa trong pexpect. Có một mẫu ngắn cùng với tài liệu ở liên kết đầu tiên.

Một lần nữa về tính đơn giản, lưu ý rằng việc phát hiện lỗi tốt luôn làm cho mã của bạn trông phức tạp hơn, nhưng bạn có thể sử dụng lại rất nhiều mã từ tập lệnh mẫu rồi quên nó đi.

59

Bạn có thể tự mã hóa bằng cách sử dụng Paramiko, như được đề xuất ở trên. Ngoài ra, bạn có thể nhìn vào vải, một ứng dụng python để làm tất cả những điều bạn hỏi về:

Vải là một thư viện Python và công cụ dòng lệnh được thiết kế để tinh giản các ứng dụng triển khai hoặc thực hiện nhiệm vụ quản trị hệ thống thông qua giao thức SSH. Nó cung cấp các công cụ để chạy các trình bao tùy ý (hoặc là thông tin đăng nhập bình thường người dùng hoặc qua sudo), tải lên và tải xuống tệp, v.v.

Tôi nghĩ điều này phù hợp với nhu cầu của bạn. Nó cũng không phải là một thư viện lớn và không yêu cầu cài đặt máy chủ, mặc dù nó có phụ thuộc vào paramiko và pycrypt yêu cầu cài đặt trên máy khách.

Ứng dụng đã từng là here. Nó bây giờ có thể được tìm thấy here.

* The official, canonical repository is git.fabfile.org 
* The official Github mirror is GitHub/bitprophet/fabric 

Có một vài điều tốt về nó, mặc dù bạn nên cẩn thận vì nó đã thay đổi trong sáu tháng qua:

Deploying Django with Fabric

Tools of the Modern Python Hacker: Virtualenv, Fabric and Pip

Simple & Easy Deployment with Fabric and Virtualenv


Sau: Vải không còn đòi hỏi paramiko cài đặt:

$ pip install fabric 
Downloading/unpacking fabric 
    Downloading Fabric-1.4.2.tar.gz (182Kb): 182Kb downloaded 
    Running setup.py egg_info for package fabric 
    warning: no previously-included files matching '*' found under directory 'docs/_build' 
    warning: no files found matching 'fabfile.py' 
Downloading/unpacking ssh>=1.7.14 (from fabric) 
    Downloading ssh-1.7.14.tar.gz (794Kb): 794Kb downloaded 
    Running setup.py egg_info for package ssh 
Downloading/unpacking pycrypto>=2.1,!=2.4 (from ssh>=1.7.14->fabric) 
    Downloading pycrypto-2.6.tar.gz (443Kb): 443Kb downloaded 
    Running setup.py egg_info for package pycrypto 
Installing collected packages: fabric, ssh, pycrypto 
    Running setup.py install for fabric 
    warning: no previously-included files matching '*' found under directory 'docs/_build' 
    warning: no files found matching 'fabfile.py' 
    Installing fab script to /home/hbrown/.virtualenvs/fabric-test/bin 
    Running setup.py install for ssh 
    Running setup.py install for pycrypto 
... 
Successfully installed fabric ssh pycrypto 
Cleaning up... 

này được chủ yếu là mỹ phẩm, tuy nhiên: ssh là một ngã ba của paramiko, nhà duy trì cho cả các thư viện là như nhau (Jeff Forcier, cũng là tác giả của vải), và the maintainer has plans to reunite paramiko and ssh under the name paramiko . (Đợt điều chỉnh này qua pbanka.)

+0

Vì đây có vẻ là một liên kết thú vị, tôi muốn cập nhật nó là của bạn bây giờ đã bị hỏng. vui lòng sử dụng: http://www.clemesha.org/blog/modern-python-hacker-tools-virtualenv-fabric-pip/ – dlewin

+0

Cảm ơn. Sửa lỗi liên kết 404. – hughdbrown

+0

Người yêu cầu không chỉ định rằng anh ấy không muốn sử dụng "thư viện bên ngoài lớn"? Paramiko và Fabric đều quá mức cần thiết khi tất cả tác giả thực sự yêu cầu là một công thức ssh một lần đơn giản. –

22

Nếu bạn muốn tránh bất kỳ module phụ, bạn có thể sử dụng các mô-đun subprocess để chạy

ssh [host] [command] 

và nắm bắt được đầu ra.

Hãy thử một cái gì đó như:

process = subprocess.Popen("ssh example.com ls", shell=True, 
    stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 
output,stderr = process.communicate() 
status = process.poll() 
print output 

Để đối phó với tên người dùng và mật khẩu, bạn có thể sử dụng trình con để tương tác với quá trình ssh, hoặc bạn có thể cài đặt một khóa công khai trên máy chủ để tránh nhắc mật khẩu.

+5

Nhưng nếu khách hàng sử dụng Windows thì sao? – Nathan

+0

Rất khó để cung cấp mật khẩu cho quy trình con 'ssh' thông qua một đường ống. Xem [Tại sao không chỉ sử dụng một đường ống (popen())?] (Http://pexpect.readthedocs.org/en/latest/FAQ.html#whynotpipe). Bạn có thể cần các mô đun 'pty',' pexpect' để giải quyết nó. – jfs

+0

doesnt dường như làm việc cho chuỗi 'ssh somecomputer; python -c "nhập khẩu numpy; in numpy .__ version__" 'nó nói nó không biết lệnh "nhập" – usethedeathstar

6

Giống như hughdbrown, tôi thích Fabric. Xin lưu ý rằng trong khi nó thực thi kịch bản lệnh khai báo của riêng nó (để thực hiện triển khai và như vậy) nó cũng có thể được nhập khẩu như một mô-đun Python và được sử dụng trên các chương trình của bạn mà không cần phải viết một kịch bản lệnh Vải.

Vải có trình bảo trì mới và đang trong quá trình ghi lại; điều đó có nghĩa là hầu hết các hướng dẫn bạn (hiện tại) tìm thấy trên web sẽ không hoạt động với phiên bản hiện tại. Ngoài ra, Google vẫn hiển thị trang Vải cũ là kết quả đầu tiên.

Đối với lên đến tài liệu ngày bạn có thể kiểm tra: http://docs.fabfile.org

+0

Fabric sử dụng một nhánh của paramiko http://pypi.python.org/pypi/ssh/ cho tất cả các công cụ ssh. – Damien

16

Tôi đã viết Python bindings for libssh2. Libssh2 là một thư viện phía máy khách thực hiện giao thức SSH2.

import socket 
import libssh2 

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
sock.connect(('exmaple.com', 22)) 

session = libssh2.Session() 
session.startup(sock) 
session.userauth_password('john', '******') 

channel = session.channel() 
channel.execute('ls -l') 

print channel.read(1024) 
+1

Có vẻ như rất thấp. Ví dụ (ví dụ của bạn), bạn phải nói rõ rằng bạn sử dụng IPv4 hoặc IPv6 (một cái gì đó bạn không phải làm với OpenSSH dòng lệnh client). Ngoài ra, tôi không tìm thấy cách làm cho nó hoạt động với ssh-agent. – bortzmeyer

+2

Những điều tốt về pylibssh2 là nó chuyển các tập tin WAY nhanh hơn so với bất kỳ thực hiện python bản địa của ssh như paramiko. – Damien

6

tôi thấy paramiko là một chút quá thấp cấp, và vải không đặc biệt rất phù hợp để được sử dụng như một thư viện, vì vậy tôi đặt cùng thư viện của riêng tôi gọi spur sử dụng paramiko để thực hiện một chút đẹp hơn giao diện:

import spur 

shell = spur.SshShell(hostname="localhost", username="bob", password="password1") 
result = shell.run(["echo", "-n", "hello"]) 
print result.output # prints hello 

bạn cũng có thể chọn để in kết quả của chương trình vì nó đang chạy, đó là hữu ích nếu bạn muốn nhìn thấy đầu ra của lệnh dài chạy trước khi nó thoát:

result = shell.run(["echo", "-n", "hello"], stdout=sys.stdout) 
+0

Không hỗ trợ chạy các lệnh không chuẩn, ví dụ trên một số lệnh (MikroTik) được đặt trước bằng '/', thư viện này sẽ phát ra lỗi. Đối với máy chủ Linux chuẩn, có vẻ như khá tốt tuy nhiên. –

+0

Khi tôi chuyển một địa chỉ IP tới tên máy chủ, nó sẽ phát ra lỗi nói rằng IP không được tìm thấy trong known_hosts ... – rexbelia

+0

@rexbelia Đây là hành vi bình thường của SSH: để đảm bảo rằng bạn đang nói chuyện với máy chủ chính xác, SSH sẽ chỉ chấp nhận khóa từ máy chủ nếu nó đã được biết. Giải pháp là thêm khóa có liên quan vào known_hosts hoặc để đặt đối số missing_host_key thành giá trị thích hợp, như được mô tả trong tài liệu. –

1

này làm việc cho tôi

import subprocess 
import sys 
HOST="IP" 
COMMAND="ifconfig" 

def passwordless_ssh(HOST): 
     ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND], 
         shell=False, 
         stdout=subprocess.PIPE, 
         stderr=subprocess.PIPE) 
     result = ssh.stdout.readlines() 
     if result == []: 
       error = ssh.stderr.readlines() 
       print >>sys.stderr, "ERROR: %s" % error 
       return "error" 
     else: 
       return result 
0

Chỉ cần sử dụng ssh_decorate

from ssh_decorate import ssh_connect 
ssh=ssh_connect('user','password','server') 

#Run a python function 
@ssh 
def python_pwd(): 
    import os 
    return os.getcwd() 

print (python_pwd()) 
Các vấn đề liên quan