it-swarm-ko.tech

SCP 또는 SSH를 사용하여 Python)의 원격 서버로 파일을 복사하는 방법은 무엇입니까?

Cron에서 매일 Python 스크립트 실행)에 의해 생성되는 텍스트 파일이 로컬 컴퓨터에 있습니다.

SSH를 통해 해당 파일을 서버에 안전하게 전송하기 위해 약간의 코드를 추가하고 싶습니다.

92
Alok

간단한 접근 방식을 원한다면 이것이 효과가 있습니다.

먼저 파일을 ".close ()"하여 파이썬에서 디스크로 플러시되도록해야합니다.

import os
os.system("scp FILE [email protected]:PATH")
#e.g. os.system("scp foo.bar [email protected]:/path/to/foo.bar")

Scp가 공개 ssh 키를 사용하여 자동으로 인증되도록 (즉, 스크립트가 비밀번호를 요구하지 않도록) ssh 키를 미리 생성 (소스 시스템에서)하고 대상 시스템에서 설치해야합니다. .

ssh-keygen 예

46
pdq

Paramiko 라이브러리를 사용하여 Python (즉, subprocess.Popen 또는 비슷한 것을 통해 scp를 래핑하지 않음)) 에서이 작업을 수행하려면 다음과 같이하십시오.

import os
import paramiko

ssh = paramiko.SSHClient() 
ssh.load_Host_keys(os.path.expanduser(os.path.join("~", ".ssh", "known_hosts")))
ssh.connect(server, username=username, password=password)
sftp = ssh.open_sftp()
sftp.put(localpath, remotepath)
sftp.close()
ssh.close()

(아마도 알 수없는 호스트, 오류, 필요한 디렉토리 작성 등을 처리하고 싶을 것입니다).

136
Tony Meyer

아마도 subprocess 모듈 을 사용했을 것입니다. 이 같은:

import subprocess
p = subprocess.Popen(["scp", myfile, destination])
sts = os.waitpid(p.pid, 0)

여기서 destination는 아마도 [email protected]:remotepath 형식 일 것입니다. @Charles Duffy 덕분에 원본 답변의 약점을 지적 해 주셔서 단일 문자열 인수를 사용하여 scp 작업 Shell=True을 지정했습니다. 경로에서 공백을 처리하지 않습니다.

모듈 문서에는 이 작업과 관련하여 수행 할 수있는 오류 검사의 예가 있습니다

시스템간에 무인 암호없는 scp를 수행 할 수 있도록 적절한 자격 증명을 설정했는지 확인하십시오 . stackoverflow 질문이 이미 있습니다 .

30
Blair Conrad

이 문제에 접근하는 방법에는 두 가지가 있습니다.

  1. 명령 행 프로그램 랩
  2. sSH 기능을 제공하는 Python 라이브러리를 사용하십시오 (예 :- Paramiko 또는 Twisted Conch )

각 접근 방식에는 고유 한 단점이 있습니다. "ssh", "scp"또는 "rsync"와 같은 시스템 명령을 래핑하는 경우 비밀번호가없는 로그인을 활성화하려면 SSH 키를 설정해야합니다. Paramiko 또는 다른 라이브러리를 사용하여 스크립트에 비밀번호를 포함시킬 수 있지만 SSH 연결의 기본 사항 (예 : 키 교환, 에이전트 등)에 익숙하지 않은 경우 문서화가 부족할 수 있습니다. SSH 키가 이런 종류의 암호보다 거의 항상 더 좋은 아이디어라는 것은 말할 것도 없습니다.

참고 : SSH를 통해 파일을 전송하려는 경우 특히 대체가 일반 오래된 scp 인 경우 rsync를 이길 수 없습니다.

나는 Paramiko를 시스템 호출을 대체하는 데 주목했지만 사용의 용이성과 즉각적인 친숙성으로 인해 래핑 된 명령으로 되돌아 갔다. 다를 수 있습니다. 나는 얼마 전에 Conch에게 옛날을 주었지만 그것은 나에게 호소하지 않았다.

시스템 호출 경로를 선택하면 Python은 os.system 또는 명령/하위 프로세스 모듈과 같은 옵션 배열을 제공합니다. 버전 2.4 이상을 사용하는 경우 하위 프로세스 모듈을 사용합니다.

11
Michael

같은 문제에 도달했지만 "해킹"또는 에뮬레이션 명령 줄 대신 :

이 답변을 찾았습니다 here .

from paramiko import SSHClient
from scp import SCPClient

ssh = SSHClient()
ssh.load_system_Host_keys()
ssh.connect('example.com')

with SCPClient(ssh.get_transport()) as scp:
    scp.put('test.txt', 'test2.txt')
    scp.get('test2.txt')
6
Maviles

호스트 키 검사를 처리하기 위해 이와 같은 작업을 수행 할 수 있습니다

import os
os.system("sshpass -p password scp -o StrictHostKeyChecking=no local_file_path [email protected]:remote_path")
4
Pradeep Pathak

fabric ssh를 통해 파일을 업로드하는 데 사용될 수 있습니다 :

#!/usr/bin/env python
from fabric.api import execute, put
from fabric.network import disconnect_all

if __name__=="__main__":
    import sys
    # specify hostname to connect to and the remote/local paths
    srcdir, remote_dirname, hostname = sys.argv[1:]
    try:
        s = execute(put, srcdir, remote_dirname, Host=hostname)
        print(repr(s))
    finally:
        disconnect_all()
3
jfs

이를 위해 설계된 vassal 패키지를 사용할 수 있습니다.

당신이 필요로하는 것은 vassal을 설치하고하는 것입니다

from vassal.terminal import Terminal
Shell = Terminal(["scp [email protected]:/home/foo.txt foo_local.txt"])
Shell.run()

또한 인증 정보를 저장하므로 다시 입력 할 필요가 없습니다.

1
Shawn

외부 자원 paramiko 사용;

    from paramiko import SSHClient
    from scp import SCPClient
    import os

    ssh = SSHClient() 
    ssh.load_Host_keys(os.path.expanduser(os.path.join("~", ".ssh", "known_hosts")))
    ssh.connect(server, username='username', password='password')
    with SCPClient(ssh.get_transport()) as scp:
            scp.put('test.txt', 'test2.txt')
0
michael

매우 간단한 접근 방식은 다음과 같습니다.

import os
os.system('sshpass -p "password" scp [email protected]:/path/to/file ./')

아니오 python 라이브러리가 필요하며 (os에만 해당) 작동합니다

0

SSL 인증서를 사용하지 않으려면 다음을 시도하십시오.

import subprocess

try:
    # Set scp and ssh data.
    connUser = 'john'
    connHost = 'my.Host.com'
    connPath = '/home/john/'
    connPrivateKey = '/home/user/myKey.pem'

    # Use scp to send file from local to Host.
    scp = subprocess.Popen(['scp', '-i', connPrivateKey, 'myFile.txt', '{}@{}:{}'.format(connUser, connHost, connPath)])

except CalledProcessError:
    print('ERROR: Connection to Host failed!')
0
JavDomGom

sshfs 를 사용하여 ssh를 통해 원격 디렉토리를 마운트하고 shutil 을 사용하여 파일을 복사했습니다.

$ mkdir ~/sshmount
$ sshfs [email protected]:/path/to/remote/dst ~/sshmount

그런 다음 파이썬에서 :

import shutil
shutil.copy('a.txt', '~/sshmount')

이 방법은 로컬로 캐싱하고 하나의 큰 파일을 보내지 않고 데이터를 생성하는 경우 데이터를 스트리밍 할 수 있다는 이점이 있습니다.

0
Jonno_FTW

하위 프로세스를 통해 scp 명령을 호출하면 스크립트 내에서 진행률 보고서를받을 수 없습니다. pexpect를 사용하여 해당 정보를 추출 할 수 있습니다.

import pipes
import re
import pexpect # $ pip install pexpect

def progress(locals):
    # extract percents
    print(int(re.search(br'(\d+)%$', locals['child'].after).group(1)))

command = "scp %s %s" % Tuple(map(pipes.quote, [srcfile, destination]))
pexpect.run(command, events={r'\d+%': progress})

로컬 네트워크의 파이썬 복사 파일 (linux-> linux) 참조

0
jfs