আমার আমার স্থানীয় মেশিনে একটি পাঠ্য ফাইল রয়েছে যা ক্রোন চালিত দৈনিক পাইথন স্ক্রিপ্ট দ্বারা উত্পন্ন হয়।
এই ফাইলটি আমার সার্ভারে এসএসএইচে নিরাপদে প্রেরণ করতে আমি কিছুটা কোড যুক্ত করতে চাই।
আমার আমার স্থানীয় মেশিনে একটি পাঠ্য ফাইল রয়েছে যা ক্রোন চালিত দৈনিক পাইথন স্ক্রিপ্ট দ্বারা উত্পন্ন হয়।
এই ফাইলটি আমার সার্ভারে এসএসএইচে নিরাপদে প্রেরণ করতে আমি কিছুটা কোড যুক্ত করতে চাই।
উত্তর:
আপনি কল করতে পারেন 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
অবরুদ্ধ করুন), সুতরাং আপনি জানেন যে এটি পাইথন থেকে ডিস্কে ফ্লাশ হয়েছে।
আপনাকে পূর্বেই (উত্স মেশিনে) তৈরি এবং (গন্তব্য মেশিনে) একটি এসএস কী ইনস্টল করতে হবে যাতে স্ক্রিপটি আপনার পাবলিক এসএস কী দিয়ে স্বয়ংক্রিয়ভাবে প্রমাণিত হয় (অন্য কথায়, যাতে আপনার স্ক্রিপ্টটি পাসওয়ার্ড জিজ্ঞাসা করে না) ।
subprocess.check_call(['scp', srcfile, dest])
পাইথন 2.5 পরিবর্তে যেহেতু ব্যবহার করা যেতে পারেrc = Popen(..).wait(); if rc != 0: raise ..
পাইথনে এটি করার জন্য (যেমন সাবপ্রসেসের মাধ্যমে 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()
(আপনি সম্ভবত অজানা হোস্ট, ত্রুটিগুলি, যে কোনও ডিরেক্টরি তৈরি করতে প্রয়োজনীয় প্রয়োজনীয়তাগুলি সমাধান করতে চান))
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
। আমার প্রকৃত উত্তরের দুর্বলতাটি চিহ্নিত করার জন্য @ চারেলস ডাফিকে ধন্যবাদ জানাই, যেটি স্কিপ ক্রিয়াকলাপ নির্দিষ্ট করার জন্য একক স্ট্রিং যুক্তি ব্যবহার করেছিল shell=True
- যে পথগুলিতে হোয়াইটস্পেস পরিচালনা করবে না।
মডিউল ডকুমেন্টেশনের ত্রুটি যাচাইয়ের উদাহরণ রয়েছে যা আপনি এই ক্রিয়াকলাপের সাথে মিলিয়ে সম্পাদন করতে চাইতে পারেন।
নিশ্চিত হয়ে নিন যে আপনি যথাযথ শংসাপত্রগুলি সেট আপ করেছেন যাতে আপনি মেশিনগুলির মধ্যে একটি অবরুদ্ধ, পাসওয়ার্ডহীন স্ক্র্যাপ সম্পাদন করতে পারেন । ইতিমধ্যে এটির জন্য একটি স্ট্যাকওভারফ্লো প্রশ্ন রয়েছে ।
subprocess.check_call(['scp', myfile, destination])
এর পরিবর্তে পাইথন 2.5 (2006) ব্যবহার করা যেতে পারে
সমস্যাটি দেখার জন্য কয়েকটি উপায় রয়েছে:
প্রতিটি পদ্ধতির নিজস্ব কীর্তি রয়েছে। আপনি "ssh", "scp" বা "rsync" এর মতো সিস্টেম কমান্ড মোড়ানো থাকলে পাসওয়ার্ড-কম লগইন সক্ষম করতে আপনাকে এসএসএইচ কীগুলি সেটআপ করতে হবে। আপনি প্যারামিকো বা অন্য কোনও লাইব্রেরি ব্যবহার করে কোনও স্ক্রিপ্টে একটি পাসওয়ার্ড এম্বেড করতে পারেন তবে ডকুমেন্টেশনের অভাব হতাশ হতে পারে, বিশেষত আপনি যদি এসএসএইচ সংযোগের বেসিকগুলির সাথে পরিচিত না হন (যেমন - কী এক্সচেঞ্জ, এজেন্টস ইত্যাদি)। এটি সম্ভবত বলা ছাড়াই যায় যে এসএসএইচ কীগুলি প্রায়শই এই ধরণের স্টাফের পাসওয়ার্ডের চেয়ে ভাল ধারণা।
দ্রষ্টব্য: আপনি যদি এসএসএইচের মাধ্যমে ফাইল স্থানান্তর করার পরিকল্পনা করেন তবে বিশেষত বিকল্পটি যদি পুরানো স্ক্রিপ হয় তবে আরএসসিএনকে পরাস্ত করা শক্ত।
আমি সিস্টেম কলগুলি প্রতিস্থাপনের দিকে নজর দিয়ে প্যারামিকো ব্যবহার করেছি তবে ব্যবহারের সহজলভ্যতা এবং তাত্ক্ষণিক পরিচয়ের কারণে আমি নিজেকে মোড়ানো কমান্ডগুলিতে ফিরে পেয়েছি। আপনি অন্য হতে পারে। আমি কিছুক্ষণ আগে শঙ্খকে একবারে ওভার দিয়েছিলাম তবে এটি আমার কাছে আবেদন করে না।
যদি সিস্টেম-কলের পথটি বেছে নেওয়া হয়, পাইথন ওএস.সিস্টেম বা কমান্ড / সাবপ্রসেস মডিউলগুলির মতো বিকল্পগুলির একটি অ্যারে সরবরাহ করে। সংস্করণ ২.৪+ ব্যবহার করে আমি সাবপ্রসেস মডিউলটি নিয়ে যাব।
একই সমস্যা পৌঁছেছে, তবে "হ্যাকিং" বা কমান্ড লাইন অনুকরণের পরিবর্তে:
এই উত্তরটি এখানে পেয়েছি ।
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
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()
আপনি ভ্যাসাল প্যাকেজটি ব্যবহার করতে পারেন, এটি ঠিক এটির জন্য ডিজাইন করা হয়েছে।
আপনার যা দরকার তা হ'ল ভ্যাসাল ইনস্টল করা এবং করা
from vassal.terminal import Terminal
shell = Terminal(["scp username@host:/home/foo.txt foo_local.txt"])
shell.run()
এছাড়াও, এটি আপনাকে প্রমাণীকরণের শংসাপত্রগুলি সংরক্ষণ করবে এবং এগুলি বারবার টাইপ করার দরকার নেই।
আমি ssh এর মাধ্যমে রিমোট ডিরেক্টরিটি মাউন্ট করতে sshfs ব্যবহার করেছি , এবং ফাইলগুলি অনুলিপি করতে shutil :
$ mkdir ~/sshmount
$ sshfs user@remotehost:/path/to/remote/dst ~/sshmount
তারপরে অজগরে:
import shutil
shutil.copy('a.txt', '~/sshmount')
এই পদ্ধতিটির সুবিধা রয়েছে যে আপনি যদি স্থানীয়ভাবে ক্যাশে এবং একক বড় ফাইল প্রেরণ না করে ডেটা তৈরি করে থাকেন তবে আপনি ডেটা স্ট্রিম করতে পারবেন।
আপনি যদি এসএসএল শংসাপত্র ব্যবহার করতে না চান তবে এটি ব্যবহার করুন:
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!')
বাহ্যিক সংস্থান প্যারামিকো ব্যবহার করে;
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)