Câu hỏi Cách đơn giản nhất để SSH sử dụng Python là gì?


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 địa phương (3.0), 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 giao diện điều khiển Python?

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


76
2017-08-05 14:34


gốc




Các câu trả lời:


Tôi đã không thử nó, nhưng điều này pysftp mô-đun có thể giúp, mà lần lượ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ó lẽ 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() và .put các phương thức ám chỉ 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 khi 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ạ.


38
2017-08-05 14:49



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
Các mô-đun ssh đã làm các trick. Đơn giản và hoạt động tốt. Không tìm kiếm thông qua API Paramiko. - Christopher Tokar
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
Yup, chúng ta có thể có một liên kết mới xin vui lòng. Tôi tìm thấy ssh.py trên github, nhưng nó không giống nhau (và không tốt) - jdborg
Gói pysftp chỉ cung cấp SFTP. Cách xa máy khách SSH. - bortzmeyer


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

Fabric là một thư viện Python và   công cụ dòng lệnh được thiết kế để   hợp lý hóa việc triển khai ứng dụng hoặc   thực hiện các nhiệm vụ quản trị hệ thống   thông qua giao thức SSH. Nó cung cấp   công cụ để chạy vỏ tùy tiện   lệnh (hoặc là đăng nhập bình thường   người dùng hoặc thông qua sudo), tải lên và   tải xuống tệp và 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à đây. Nó bây giờ có thể được tìm thấy đây.

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

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

Triển khai Django bằng Vải

Các công cụ của Hacker Python hiện đại: Virtualenv, Fabric và Pip

Triển khai đơn giản và dễ dàng với Fabric và Virtualenv


Sau đó: Vải không còn yêu cầu 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...

Điều này chủ yếu là mỹ phẩm, tuy nhiên: ssh là một nhánh của paramiko, người duy trì cho cả hai thư viện là như nhau (Jeff Forcier, cũng là tác giả của Fabric), và người bảo trì có kế hoạch tái hợp paramiko và ssh dưới tên paramiko. (Điều chỉnh này qua pbanka.)


60
2017-08-05 15:00



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: clemesha.org/blog/… - dlewin
Cảm ơn. Sửa lỗi liên kết 404. - hughdbrown
Người hỏi không chỉ định rằng anh ta 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. - Zoran Pavlovic
@Zoran Pavlovic: tất cả các câu trả lời hoặc là để cài đặt một gói địa phương (paramiko, fabric, ssh, libssh2) hoặc sử dụng subprocess để chạy ssh. Sau này là một giải pháp không cài đặt, nhưng tôi không nghĩ rằng sinh sản ssh là một ý tưởng tuyệt vời, và cũng không phải OP kể từ khi ông chọn câu trả lời để cài đặt mô-đun ssh. Những tài liệu này nói: "ssh.py cung cấp ba hoạt động SSH phổ biến, nhận, đặt và thực thi. Đây là một sự trừu tượng ở cấp độ cao trên Paramiko." Vì vậy, trừ khi bạn ủng hộ libssh2, đó là nặng về mã hóa, không có khuyến nghị phù hợp. Tôi ưu tiên đưa ra một giải pháp tốt khi các điều kiện của OP không thể được đáp ứng hợp lý. - hughdbrown


Nếu bạn muốn tránh bất kỳ mô-đun bổ sung nào, bạn có thể sử dụng mô-đun tiến trình con để chạy

ssh [host] [command]

và nắm bắt đầ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 tiến trình con để tương tác với quy trình ssh hoặc bạn có thể cài đặt khóa công khai trên máy chủ để tránh lời nhắc mật khẩu.


22
2017-08-05 15:05



Nhưng nếu khách hàng sử dụng Windows thì sao? - Nathan
Rất khó để cung cấp mật khẩu cho ssh subprocess thông qua một đường ống. Xem Tại sao không chỉ sử dụng một đường ống (popen ())?. Bạn có thể cần pty, pexpect để giải quyết vấn đề. - jfs
doesnt dường như làm việc cho chuỗi 'ssh somecomputer; python -c "import numpy; in numpy .__ version__" 'nó nói nó không biết lệnh "import" - usethedeathstar
@usethedeathstar: bọc toàn bộ lệnh từ xa trong dấu ngoặc kép: ssh somecomputer 'python -c "import this; print this"' - Neil


Tôi đã viết Ràng buộc Python cho 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)

16
2018-02-28 12:51



Nó có vẻ 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
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


Đị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 (tích cực phát triển) 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 đối với sự đơn giản, lưu ý rằng 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 sẽ có thể sử dụng lại rất nhiều mã từ các kịch bản mẫu rồi quên nó đi.


8
2017-08-05 14:44





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ó một người bảo trì mới và đang trong quá trình được viết 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.

Để có tài liệu cập nhật, bạn có thể kiểm tra: http://docs.fabfile.org


6
2017-08-06 10:08



Vải dùng một cái nĩa của paramiko pypi.python.org/pypi/ssh cho mọi thứ ssh. - Damien


Tôi thấy paramiko là một chút quá thấp, và Fabric không đặc biệt thích hợp khi được sử dụng như một thư viện, vì vậy tôi đặt cùng một thư viện của riêng tôi gọi là thúc đẩy sử dụng paramiko để triển khai giao diện đẹp hơn một chút:

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 đầu ra của chương trình khi chương trình đang chạy, điều này rất hữu ích nếu bạn muốn xem đầu ra của các lệnh chạy dài trước khi nó thoát:

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

6
2018-01-10 21:47



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. - Babken Vardanyan
Khi tôi vượt qua một địa chỉ IP để tên máy, nó ném một lỗi nói rằng IP không được tìm thấy trong known_hosts ... - rexbelia
@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. - Michael Williamson


Điều 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

1
2017-12-22 08:51





Vì lợi ích của những người đạt đến đây googling cho mẫu python ssh. Câu hỏi và câu trả lời ban đầu gần như là một giải mã cũ. Có vẻ như các paramiko đã đạt được một chút chức năng (Ok. Tôi sẽ thừa nhận - tinh khiết đoán ở đây - Tôi mới đến Python) và bạn có thể tạo khách hàng ssh trực tiếp với paramiko.

import base64
import paramiko

client = paramiko.SSHClient()

client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('192.168.1.1', username='user', password='password')
stdin, stdout, stderr = client.exec_command('cat /proc/meminfo')
for line in stdout:
    print('... ' + line.strip('\n'))
client.close()

Mã này đã được điều chỉnh từ bản demo https://github.com/paramiko/paramiko Nó làm việc cho tôi.


1
2018-06-21 11:09



Cảm ơn, làm việc như một say mê! - Valmond