मेरे पास मेरी स्थानीय मशीन पर एक पाठ फ़ाइल है जो क्रोन में चलने वाले दैनिक पायथन स्क्रिप्ट द्वारा उत्पन्न होती है।
मैं उस कोड को थोड़ा सा जोड़ना चाहूंगा कि फ़ाइल SSH के ऊपर मेरे सर्वर पर सुरक्षित रूप से भेजी जाए।
मेरे पास मेरी स्थानीय मशीन पर एक पाठ फ़ाइल है जो क्रोन में चलने वाले दैनिक पायथन स्क्रिप्ट द्वारा उत्पन्न होती है।
मैं उस कोड को थोड़ा सा जोड़ना चाहूंगा कि फ़ाइल SSH के ऊपर मेरे सर्वर पर सुरक्षित रूप से भेजी जाए।
जवाबों:
आप scp
बैश कमांड को कॉल कर सकते हैं (यह SSH पर फ़ाइलों की प्रतिलिपि बनाता है ) 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"])
यदि आप उसी पायथन प्रोग्राम में फ़ाइल भेजना चाहते हैं, जिसे आप फ़ाइल खोलने के लिए उपयोग कर रहे ब्लॉक के subprocess.run
बाहर कमांड को कॉल करना चाहते with
हैं (या .close()
फ़ाइल पर कॉल करें यदि आप उपयोग नहीं कर रहे हैं तो with
ब्लॉक), तो आप जानते हैं कि यह पायथन से डिस्क में प्रवाहित है।
आपको (स्रोत मशीन पर) जेनरेट करना होगा और (गंतव्य मशीन पर) ssh कुंजी को पहले से इंस्टॉल करना होगा, ताकि आपके सार्वजनिक ssh कुंजी (दूसरे शब्दों में, इसलिए आपकी स्क्रिप्ट पासवर्ड नहीं मांगे) ।
subprocess.check_call(['scp', srcfile, dest])
Python 2.5 के बजाय इस्तेमाल किया जा सकता हैrc = Popen(..).wait(); if rc != 0: raise ..
पैरामिको लाइब्रेरी के साथ पायथन में ऐसा करने के लिए (यानी सबप्रोसेस के माध्यम से एसपीपी लपेटना नहीं) या ऐसा करना, आप कुछ इस तरह करेंगे:
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()
(आप शायद अज्ञात मेजबानों, त्रुटियों, किसी भी निर्देशिका को आवश्यक बनाने के साथ सौदा करना चाहते हैं, और इसी तरह)।
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
को तुरंत करने के बाद बॉक्स से बाहर कर दें ssh
।
आप शायद उपप्रोसेस मॉड्यूल का उपयोग करेंगे । कुछ इस तरह:
import subprocess
p = subprocess.Popen(["scp", myfile, destination])
sts = os.waitpid(p.pid, 0)
जहां destination
शायद रूप का है user@remotehost:remotepath
। मेरे मूल उत्तर में कमजोरी की ओर इशारा करने के लिए @Charles Duffy का धन्यवाद, जिसने scp ऑपरेशन को निर्दिष्ट करने के लिए एक एकल स्ट्रिंग तर्क का उपयोग किया shell=True
- जो रास्तों में व्हाट्सएप को संभाल नहीं पाएगा।
मॉड्यूल प्रलेखन में त्रुटि की जाँच के उदाहरण हैं जो आप इस ऑपरेशन के साथ संयोजन के रूप में करना चाहते हैं।
सुनिश्चित करें कि आपने उचित क्रेडेंशियल्स सेट किए हैं ताकि आप मशीनों के बीच एक अनअटेंडेड, पासवर्ड रहित scp कर सकें । इसके लिए पहले से ही एक स्टैकओवरफ्लो प्रश्न है ।
subprocess.check_call(['scp', myfile, destination])
पाइथन 2.5 (2006) के बाद से इस्तेमाल किया जा सकता है
समस्या से निपटने के लिए अलग-अलग तरीके हैं:
प्रत्येक दृष्टिकोण के अपने स्वयं के प्रश्न हैं। यदि आप "ssh", "scp" या "rsync" जैसे सिस्टम कमांड्स को लपेट रहे हैं, तो आपको पासवर्ड-कम लॉगिन सक्षम करने के लिए SSH कुंजियों को सेटअप करने की आवश्यकता होगी। आप Paramiko या किसी अन्य लाइब्रेरी का उपयोग करके किसी स्क्रिप्ट में पासवर्ड एम्बेड कर सकते हैं, लेकिन आपको प्रलेखन निराशा की कमी मिल सकती है, खासकर यदि आप SSH कनेक्शन की मूल बातें (जैसे - प्रमुख एक्सचेंज, एजेंट, आदि) से परिचित नहीं हैं। यह शायद यह कहे बिना जाता है कि एसएसएच कीज इस तरह के सामान के लिए पासवर्ड से लगभग बेहतर विचार हैं।
नोट: यदि आप SSH के माध्यम से फ़ाइलों को स्थानांतरित करने की योजना बनाते हैं, तो rsync को हराना मुश्किल है, खासकर अगर विकल्प सादा पुराना scp है।
मैंने Paramiko का उपयोग सिस्टम कॉल को बदलने के लिए एक आंख के साथ किया है, लेकिन अपने उपयोग में आसानी और तत्काल परिचितता के कारण खुद को लिपटे हुए कमांडों में वापस पाया। आप अलग हो सकते हैं। मैंने कुछ समय पहले एक बार शंख दिया था, लेकिन इसने मुझे अपील नहीं की।
यदि सिस्टम-कॉल पथ के लिए चयन किया जाता है, तो पायथन ऑस.सिस्टम या कमांड / सबप्रोसेस मॉड्यूल जैसे विकल्पों की एक सरणी प्रदान करता है। यदि संस्करण 2.4+ का उपयोग कर रहा हूं तो मैं सबप्रोसेस मॉड्यूल के साथ जाऊंगा।
उसी समस्या तक पहुँच गए, लेकिन "हैकिंग" या कमांड लाइन का अनुकरण करने के बजाय:
इसका जवाब यहां मिला ।
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')
आप इस तरह से कुछ भी कर सकते हैं, साथ ही होस्ट की की चेकिंग को भी संभाल सकते हैं
import os
os.system("sshpass -p password scp -o StrictHostKeyChecking=no local_file_path username@hostname:remote_path")
fabric
विज़ एसश फाइल अपलोड करने के लिए इस्तेमाल किया जा सकता है:
#!/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()
आप वासल पैकेज का उपयोग कर सकते हैं, जो बिल्कुल इसके लिए डिज़ाइन किया गया है।
आपको केवल वासल स्थापित करना और करना है
from vassal.terminal import Terminal
shell = Terminal(["scp username@host:/home/foo.txt foo_local.txt"])
shell.run()
इसके अलावा, यह आपको क्रेडेंशियल प्रमाणित करने से बचाएगा और उन्हें बार-बार टाइप करने की आवश्यकता नहीं है।
मैंने sshfs का उपयोग ssh के माध्यम से दूरस्थ निर्देशिका को माउंट करने के लिए किया है, और फाइलों को कॉपी करने के लिए शिल्ट किया है:
$ mkdir ~/sshmount
$ sshfs user@remotehost:/path/to/remote/dst ~/sshmount
फिर अजगर में:
import shutil
shutil.copy('a.txt', '~/sshmount')
इस पद्धति का लाभ यह है कि आप डेटा को स्ट्रीम कर सकते हैं यदि आप स्थानीय रूप से कैशिंग करने के बजाय डेटा उत्पन्न कर रहे हैं और एक बड़ी फाइल भेज रहे हैं।
यदि आप 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!')
बाहरी संसाधन 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')
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})
एक बहुत ही सरल तरीका निम्नलिखित है:
import os
os.system('sshpass -p "password" scp user@host:/path/to/file ./')
कोई अजगर पुस्तकालय (केवल ओएस) की आवश्यकता नहीं है, और यह काम करता है, हालांकि इस विधि का उपयोग करने के लिए एक और ssh क्लाइंट पर निर्भर करता है। यदि किसी अन्य सिस्टम पर चलाया जाता है तो यह अवांछित व्यवहार हो सकता है।
हैकी की तरह, लेकिन निम्नलिखित काम करना चाहिए :)
import os
filePath = "/foo/bar/baz.py"
serverPath = "/blah/boo/boom.py"
os.system("scp "+filePath+" user@myserver.com:"+serverPath)