Yanıtlar:
scp
Bash komutunu (dosyaları SSH üzerinden kopyalar ) şu şekilde çağırabilirsiniz subprocess.run
:
import subprocess
subprocess.run(["scp", FILE, "USER@SERVER:PATH"])
#e.g. subprocess.run(["scp", "foo.bar", "joe@srvr.net:/path/to/foo.bar"])
Eğer aynı Python programında göndermek istediğiniz dosyayı oluşturuyorsanız, aramak isteyeceksiniz subprocess.run
dışında komutu with
dosyayı açmak için kullandığınız bloğun (veya aramayı .close()
sen a kullanmıyorsanız ilk dosyada with
bloğu), böylece Python'dan diske temizlendiğini bilirsiniz.
Önceden bir ssh anahtarı oluşturmanız (kaynak makinede) ve yüklemeniz (hedef makinede) gerekir, böylece scp otomatik olarak genel ssh anahtarınızla doğrulanır (başka bir deyişle, betiğiniz bir parola istemez) .
subprocess.check_call(['scp', srcfile, dest])
yerine Python 2.5'ten beri kullanılabilirrc = Popen(..).wait(); if rc != 0: raise ..
Bunu Python'da yapmak için (yani scp'yi alt süreçler , Açık veya benzeri ile kaydırmamak) Paramiko kitaplığı ile yapmak için, şöyle bir şey yaparsınız:
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()
(Muhtemelen bilinmeyen ana bilgisayarlar, hatalar, gerekli dizinleri oluşturma vb. İle uğraşmak istersiniz).
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
örneklemeden sonra ekleyin ssh
.
Muhtemelen alt işlem modülünü kullanırsınız . Bunun gibi bir şey:
import subprocess
p = subprocess.Popen(["scp", myfile, destination])
sts = os.waitpid(p.pid, 0)
destination
Muhtemelen formun nerede user@remotehost:remotepath
. Scp operasyonu belirtmek için tek bir dize argümanı kullanılan orijinal cevap, güçsüzlük işaret için @Charles Duffy sayesinde shell=True
yollarında boşluk işlemek olmaz -.
Modül belgelerinde, bu işlemle bağlantılı olarak gerçekleştirmek isteyebileceğiniz hata denetimi örnekleri vardır .
Makineler arasında gözetimsiz, şifresiz bir scp gerçekleştirebilmek için doğru kimlik bilgilerini ayarladığınızdan emin olun . Bunun için zaten bir yığın aşımı sorusu var .
subprocess.check_call(['scp', myfile, destination])
yerine kullanılabilir Python 2.5 (2006)
Soruna yaklaşmanın birkaç farklı yolu vardır:
Her yaklaşımın kendine özgü tuhaflıkları vardır. "Ssh", "scp" veya "rsync" gibi sistem komutlarını sarmalıyorsanız, şifresiz oturumları etkinleştirmek için SSH anahtarlarını ayarlamanız gerekecektir. Paramiko veya başka bir kitaplığı kullanarak bir şifreyi bir komut dosyasına gömebilirsiniz, ancak özellikle SSH bağlantısının temellerine aşina değilseniz (örn. Anahtar değişimleri, aracılar, vb.), Belge eksikliğini sinir bozucu bulabilirsiniz. Muhtemelen bu tür şeyler için SSH anahtarlarının neredeyse her zaman parolalardan daha iyi bir fikir olduğunu söylemeye gerek yok.
NOT: SSH yoluyla dosya aktarmayı planlıyorsanız, özellikle alternatif düz eski scp ise, rsync'i yenmek zordur.
Paramiko'yu sistem çağrılarını değiştirmeye yönelik bir gözle kullandım, ancak kullanım kolaylığı ve anında aşinalıklarından dolayı sarılmış komutlara geri çekildim. Farklı olabilirsin. Bir süre önce Conch'a bir kereliğine vermiştim ama bana çekici gelmedi.
Sistem çağrısı yolunu seçiyorsanız, Python, os.system veya komutlar / alt işlem modülleri gibi bir dizi seçenek sunar. 2.4+ sürümünü kullanıyorsanız alt işlem modülünü tercih ederim.
Aynı soruna ulaştım, ancak "hacklemek" veya komut satırına öykünmek yerine:
Bu cevabı burada buldum .
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')
Ana bilgisayar anahtarı kontrolünü de işlemek için buna benzer bir şey yapabilirsiniz.
import os
os.system("sshpass -p password scp -o StrictHostKeyChecking=no local_file_path username@hostname:remote_path")
fabric
ssh ile dosya yüklemek için kullanılabilir:
#!/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()
Tam olarak bunun için tasarlanmış vasal paketini kullanabilirsiniz.
Tek ihtiyacınız olan vassal yüklemek ve yapmak
from vassal.terminal import Terminal
shell = Terminal(["scp username@host:/home/foo.txt foo_local.txt"])
shell.run()
Ayrıca, kimlik bilgilerinizi de kaydedecek ve tekrar tekrar yazmanıza gerek kalmayacaktır.
Uzak dizini ssh yoluyla bağlamak için sshfs kullandım ve dosyaları kopyalamak için shutil kullandım:
$ mkdir ~/sshmount
$ sshfs user@remotehost:/path/to/remote/dst ~/sshmount
Sonra python'da:
import shutil
shutil.copy('a.txt', '~/sshmount')
Bu yöntem, verileri yerel olarak önbelleğe almak ve tek bir büyük dosya göndermek yerine veri akışı gerçekleştirme avantajına sahiptir.
SSL sertifikalarını kullanmak istemiyorsanız bunu deneyin:
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!')
Harici kaynak paramiko'nun kullanılması;
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')
scp
Alt işlem aracılığıyla komut çağırmak , komut dosyası içindeki ilerleme raporunun alınmasına izin vermez. pexpect
bu bilgiyi çıkarmak için kullanılabilir:
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})
Çok basit bir yaklaşım şudur:
import os
os.system('sshpass -p "password" scp user@host:/path/to/file ./')
Python kitaplığı gerekmez (yalnızca os) ve çalışır, ancak bu yöntemi kullanmak başka bir ssh istemcisinin kurulmasına bağlıdır. Bu, başka bir sistemde çalıştırılırsa istenmeyen davranışlara neden olabilir.
Biraz kırılgan, ancak aşağıdakiler işe yaramalı :)
import os
filePath = "/foo/bar/baz.py"
serverPath = "/blah/boo/boom.py"
os.system("scp "+filePath+" user@myserver.com:"+serverPath)