Python을 사용하여 SSH를 사용하는 가장 간단한 방법은 무엇입니까?


82

로컬 Python (3.0) 스크립트에서 원격 서버에 SSH하고 로그인 / 암호를 제공하고 명령을 실행하고 출력을 Python 콘솔에 인쇄하려면 어떻게해야합니까?

큰 외부 라이브러리를 사용하지 않거나 원격 서버에 아무것도 설치하지 않습니다.

답변:


42

나는 그것을 시도하지 않았지만이 pysftp 모듈이 도움 이 될 수 있으며 차례로 paramiko를 사용합니다. 나는 모든 것이 클라이언트 측이라고 믿습니다.

흥미로운 명령은 아마도 .execute()원격 시스템에서 임의의 명령을 실행하는 것 입니다. (이 모듈은 또한 FTP 문자에 대해 더 많은 것을 암시하는 기능 .get().put방법을 제공합니다).

최신 정보:

원래 링크 한 블로그 게시물을 더 이상 사용할 수 없게 된 후 답변을 다시 작성했습니다. 이 답변의 이전 버전을 참조하는 일부 댓글은 이제 이상하게 보입니다.


좋은 찾기! 오류 응답을 사용자 정의하는 데 신경 쓰지 않는 한이 추가 추상화는 매우 유용합니다.
Cascabel

ssh 모듈이 트릭을 수행했습니다. 간단하고 잘 작동합니다. Paramiko API를 통해 검색하지 않습니다.
Christopher Tokar

2
제공 한 링크 내의 ssh.py 파일에 대한 링크가 깨졌습니다. : /
dgorissen

네, 새 링크를주세요. 나는 GitHub의에 ssh.py을 발견하지만 동일하지 (그리고 좋지 않은 등)
joedborg

1
pysftp 패키지는 SFTP 만 제공합니다. SSH 클라이언트와는 거리가 멀다.
bortzmeyer

61

위에서 제안한대로 Paramiko를 사용하여 직접 코딩 할 수 있습니다. 또는 요청한 모든 작업을 수행하는 Python 애플리케이션 인 Fabric을 살펴볼 수 있습니다.

Fabric은 애플리케이션 배포를 간소화하거나 SSH 프로토콜을 통해 시스템 관리 작업을 수행하도록 설계된 Python 라이브러리 및 명령 줄 도구입니다. 임의의 셸 명령 (일반 로그인 사용자로 또는 sudo를 통해) 실행, 파일 업로드 및 다운로드 등을위한 도구를 제공합니다.

나는 이것이 당신의 필요에 맞다고 생각합니다. 또한 클라이언트에 설치해야하는 paramiko 및 pycrypt에 대한 종속성이 있지만 큰 라이브러리가 아니며 서버 설치가 필요하지 않습니다.

이 앱은 여기에 있었습니다. 이제 여기 에서 찾을 수 있습니다 .

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

몇 가지 좋은 기사가 있지만 지난 6 개월 동안 변경되었으므로주의해야합니다.

Fabric으로 Django 배포

최신 Python 해커의 도구 : Virtualenv, Fabric 및 Pip

Fabric 및 Virtualenv를 통한 간단하고 쉬운 배포


나중에 : Fabric을 설치하는 데 더 이상 paramiko가 필요하지 않습니다.

$ 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...

그러나 이것은 대부분 외형 적이지만 ssh는 paramiko의 포크이고 두 라이브러리의 관리자는 동일하며 (Fabric의 저자 인 Jeff Forcier) 관리자는 paramiko라는 이름으로 paramiko와 ssh를 재결합 할 계획을 가지고 있습니다. (이 수정은 pbanka 를 통해 이루어집니다 .)


흥미로운 링크 인 것 같으므로 이제 귀하의 링크가 끊어 졌으므로 업데이트하고 싶습니다. 사용하십시오 : clemesha.org/blog/…
dlewin

질문자가 "대형 외부 라이브러리"를 사용하고 싶지 않다고 지정하지 않았습니까? 저자가 실제로 요청한 모든 것이 간단한 일회용 ssh 레시피 일 때 Paramiko와 Fabric은 모두 과잉입니다.
Zoran Pavlovic

1
@Zoran Pavlovic : 모든 대답은 로컬 패키지 (paramiko, fabric, ssh, libssh2)를 설치하거나 하위 프로세스를 사용하여 ssh를 실행하는 것이 었습니다. 후자는 설치되지 않은 솔루션이지만 ssh를 생성하는 것은 좋은 생각이 아니며 ssh 모듈을 설치하기 위해 답변을 선택했기 때문에 OP도 마찬가지라고 생각합니다. 이 문서는 "ssh.py는 세 가지 일반적인 SSH 작업 인 get, put 및 execute를 제공합니다. 이는 Paramiko에 대한 높은 수준의 추상화입니다."라고 말합니다. 따라서 코딩이 많은 libssh2를 선호하지 않는 한 준수 권장 사항이 없습니다. 나는 OP의 조건이 합리적으로 충족 될 수 없을 때 좋은 해결책을 제공하는 것을 선호합니다.
hughdbrown

24

추가 모듈을 피하려면 하위 프로세스 모듈을 사용하여 실행할 수 있습니다.

ssh [host] [command]

출력을 캡처합니다.

다음과 같이 시도하십시오.

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

사용자 이름과 암호를 처리하기 위해 하위 프로세스를 사용하여 ssh 프로세스와 상호 작용하거나 서버에 공개 키를 설치하여 암호 프롬프트를 피할 수 있습니다.


7
그러나 클라이언트가 Windows에 있다면 어떻게 될까요?
Nathan

ssh파이프를 통해 하위 프로세스에 암호를 제공하는 것은 어려울 수 있습니다 . 파이프 (popen ())를 사용하지 않는 이유를 참조하십시오 . . 이를 해결 하려면 pty, pexpect모듈 이 필요할 수 있습니다 .
jfs 2014

문자열 'ssh somecomputer'에서 작동하지 않는 것 같습니다. 파이썬 -c "수입 NumPy와, 인쇄 NumPy와 .__ version__"그것은 명령 "수입"알고 나던 말한다 '
usethedeathstar

1
@usethedeathstar : 전체 원격 명령을 따옴표로 묶습니다. ssh somecomputer 'python -c "import this; print this"'
Neil

17

libssh2에 대한 Python 바인딩을 작성했습니다 . Libssh2는 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)

2
매우 낮은 수준 인 것 같습니다. 예를 들어 (자신의 예) IPv4 또는 IPv6 (OpenSSH 명령 줄 클라이언트와 관련이없는 작업)을 사용한다고 명시 적으로 말해야합니다. 또한 ssh-agent와 함께 작동하도록 만드는 방법을 찾지 못했습니다.
bortzmeyer

2
pylibssh2의 좋은 점은 paramiko와 같은 ssh의 네이티브 파이썬 구현보다 파일을 훨씬 빠르게 전송한다는 것입니다.
Damien 2012

8

여기서 "가장 단순한"정의가 중요합니다. 간단한 코드는 모듈을 사용하는 것을 의미합니다 ( "대형 외부 라이브러리"는 과장된 것임).

나는 가장 최신 (능동적으로 개발 된) 모듈이 paramiko 라고 믿는다 . 다운로드시 데모 스크립트와 함께 제공되며 자세한 온라인 API 문서가 있습니다. pexpect 에 포함 된 PxSSH 를 사용해 볼 수도 있습니다 . 첫 번째 링크에는 설명서와 함께 짧은 샘플이 있습니다.

다시 한 번 단순함과 관련하여 좋은 오류 감지는 항상 코드를 더 복잡하게 보이게 만들지 만 샘플 스크립트에서 많은 코드를 재사용 한 다음 잊어 버릴 수 있어야합니다.


6

휴드 브라운처럼 저는 패브릭을 좋아합니다. 자체 선언적 스크립팅을 구현하는 동안 (배포 등을위한) Python 모듈로 가져 와서 Fabric 스크립트를 작성하지 않고도 프로그램에서 사용할 수 있습니다.

Fabric은 새로운 메인테이너를 가지고 있으며 재 작성 중입니다. 즉, (현재) 웹에서 찾을 수있는 대부분의 자습서는 현재 버전에서 작동하지 않습니다. 또한 Google은 여전히 ​​첫 번째 결과로 이전 Fabric 페이지를 표시합니다.

최신 문서는 http://docs.fabfile.org에서 확인할 수 있습니다.


Fabric은 모든 ssh 항목 에 paramiko pypi.python.org/pypi/ssh 포크를 사용합니다 .
Damien 2012

6

나는 paramiko가 너무 낮은 수준이고 Fabric은 라이브러리로 사용하기에 특히 적합하지 않다는 것을 알았으므로 약간 더 좋은 인터페이스를 구현하기 위해 paramiko를 사용하는 spur 라는 자체 라이브러리 를 구성했습니다.

import spur

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

실행중인 프로그램의 출력을 인쇄하도록 선택할 수도 있습니다. 이는 종료하기 전에 장기 실행 명령의 출력을 확인하려는 경우 유용합니다.

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

비표준 명령 실행을 지원하지 않습니다. 예를 들어 일부 라우터 (MikroTik) 명령에 '/'접두사가 붙은 경우이 라이브러리에서 오류가 발생합니다. 그러나 표준 리눅스 호스트의 경우 꽤 괜찮아 보입니다.
Babken Vardanyan 2014

나는에서 known_hosts에서 찾을 수 없습니다 IP를 말하는 오류가 발생합니다 호스트 이름에 IP 주소 ... 전달하는 경우
rexbelia

@rexbelia 이것은 SSH의 정상적인 동작입니다. 올바른 서버와 통신하고 있는지 확인하기 위해 SSH는 이미 알려진 경우에만 호스트의 키를 수락합니다. 해결책은 known_hosts에 관련 키를 추가하거나 문서에 설명 된대로 missing_host_key 인수를 적절한 값으로 설정하는 것입니다.
Michael Williamson

4

여기에 도달하는 사람들을 위해 python ssh 샘플을 검색하십시오. 원래의 질문과 대답은 이제 거의 해독이 아닙니다. paramiko에 약간의 기능이있는 것 같습니다 (좋아요. 여기에서 순수 추측-Python을 처음 사용했습니다). paramiko로 직접 ssh 클라이언트를 만들 수 있습니다.

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

이 코드는 https://github.com/paramiko/paramiko 데모에서 수정되었습니다 .


1

이것은 나를 위해 일했습니다.

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

please refer to paramiko.org, its very useful while doing ssh using python.

import paramiko

import time

ssh = paramiko.SSHClient() #SSHClient() is the paramiko object</n>

#Below lines adds the server key automatically to know_hosts file.use anyone one of the below

ssh.load_system_host_keys() 

ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

try:

#Here we are actually connecting to the server.

ssh.connect('10.106.104.24', port=22, username='admin', password='')

time.sleep(5)

#I have mentioned time because some servers or endpoint prints there own information after 
#loggin in e.g. the version, model and uptime information, so its better to give some time 
#before executing the command.

#Here we execute the command, stdin for input, stdout for output, stderr for error

stdin, stdout, stderr = ssh.exec_command('xstatus Time')

#Here we are reading the lines from output.

output = stdout.readlines() 

print(output)


#Below all are the Exception handled by paramiko while ssh. Refer to paramiko.org for more information about exception.


except (BadHostKeyException, AuthenticationException,  
    SSHException, socket.error) as e:           

print(e)

0

원격 시스템을 관리하고 파일 작업을 수행하기 위해 개발 한 spurparamiko 를 둘러싼 래퍼 인 spurplus를 살펴보십시오 .

Spurplus는 즉시 사용할 수있는 check_output()기능을 제공합니다 .

import spurplus
with spurplus.connect_with_retries(
        hostname='some-machine.example.com', username='devop') as shell:
     out = shell.check_output(['/path/to/the/command', '--some_argument']) 
     print(out)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.