পাইথনে বাশ কমান্ড চলমান


299

আমার লোকাল মেশিনে, আমি একটি অজগর স্ক্রিপ্ট চালাচ্ছি যা এই লাইনটি অন্তর্ভুক্ত করে

bashCommand = "cwm --rdf test.rdf --ntriples > test.nt"
os.system(bashCommand)

এটি কাজ করে।

তারপরে আমি একই কোডটি একটি সার্ভারে চালিত করি এবং আমি নিম্নলিখিত ত্রুটি বার্তাটি পাই

'import site' failed; use -v for traceback
Traceback (most recent call last):
File "/usr/bin/cwm", line 48, in <module>
from swap import  diag
ImportError: No module named swap

সুতরাং আমি তখন যা করেছি তা isোকানো হচ্ছে print bashCommandযা টার্মিনালে এটি চালানোর আগে কমান্ডের চেয়ে আমাকে মুদ্রণ করে os.system()

অবশ্যই, আমি আবার ত্রুটি পেয়েছি (এর ফলে os.system(bashCommand)) তবে ত্রুটির আগে এটি টার্মিনালে কমান্ডটি মুদ্রণ করে। তারপরে আমি কেবলমাত্র সেই আউটপুটটি অনুলিপি করেছি এবং টার্মিনালে একটি অনুলিপি পেস্ট করেছি এবং এন্টার টিপুন এবং এটি কাজ করে ...

কারও কি কি একটা ক্লু আছে যা চলছে?


2
আপনি কীভাবে চালাবেন তার উপর নির্ভর করে পরিবেশের মধ্যে একটি পার্থক্য রয়েছে বলে মনে হচ্ছে cwm। আপনার নিজের মধ্যে এমন কিছু কনফিগারেশন রয়েছে .bashrcযা ইন্টারেক্টিভ বাশ ব্যবহারের জন্য পরিবেশ নির্ধারণ করে?
সোভেন মারনাচ

সার্ভারে লগ ইন করার পরে আপনি কি কমান্ড লাইন থেকে কমান্ডটি চালানোর চেষ্টা করেছিলেন? আপনার পোস্টটি কেবলমাত্র বলেছে যে আপনি "এটিকে টার্মিনালে আটকালেন"।
সোভেন মারনাচ

@ সোভেন: হ্যাঁ আমার অর্থ হ'ল আমি সার্ভারের টার্মিনালে সরাসরি কমান্ডটি
চালিয়েছি

কীভাবে আপনি চালাচ্ছেন তার উপর নির্ভর করে পাইথনপথে পার্থক্য রয়েছে বলে মনে হচ্ছে cwm। অথবা হতে পারে PATH এর মধ্যে পার্থক্য রয়েছে এবং এর বিভিন্ন সংস্করণ cwmবলা হয়। বা পাইথনের বিভিন্ন সংস্করণ। মেশিনে অ্যাক্সেস ছাড়াই এটি নির্ধারণ করা সত্যিই কঠিন ...
সোভেন মার্নাচ

উত্তর:


314

ব্যবহার করবেন না os.system। এটি সাব - প্রসেসের পক্ষে অবচয় করা হয়েছে । থেকে ডক্স : "এই মডিউল বিভিন্ন পুরোনো মডিউল এবং ফাংশন প্রতিস্থাপন করতে ইচ্ছুক: os.system, os.spawn"।

আপনার ক্ষেত্রে মত:

bashCommand = "cwm --rdf test.rdf --ntriples > test.nt"
import subprocess
process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE)
output, error = process.communicate()

8
এটি আমি যা চাইছিলাম তা করতে পারেনি যখন আমাকে cd 'path\to\somewhere'অন্য ব্যাশ কমান্ড অনুসরণ করার দরকার ছিল যা কোথাও চালানো দরকার। @ ব্যবহারকারী225312
এরাটাইটিভ

36
@ অরাইটাইভ আপনার যদি একটি নির্দিষ্ট ওয়ার্কিং ডিরেক্টরিতে চালানোর জন্য আপনার সাবপ্রসেসের প্রয়োজন হয় তবে আপনি পপেন-এর পক্ষে cwdযুক্তিটি ব্যবহার করতে পারেন :subprocess.Popen(..., cwd='path\to\somewhere')
জলরোধী

7
আমার কমান্ডের জন্য আমার শেল প্রয়োজন = ঠিক এখানে; stackoverflow.com/questions/18962785/...
user984003

4
এক্ষেত্রে স্ট্রিং.স্প্লিট () এর পরিবর্তে shlex.split () এর চেয়ে ভাল ব্যবহার করুন
আলেক্সি

4
... ( stdout=fileএই ক্ষেত্রে কোনও ফাইলে আউটপুট পুনঃনির্দেশ করে It এটি প্রয়োগ করে > file)। ..., '>', 'file']পুনর্নির্দেশের প্রত্যাশা করে শেষ কমান্ডটি পাস করা ভুল হবে (এটি শেল ছাড়া কাজ করবে না এবং আপনি যদি শেল ব্যবহার করেন তবে কমান্ডটি স্ট্রিং হিসাবে পাস করা উচিত)
jfs

186

এখানে পূর্ববর্তী উত্তরগুলিকে কিছুটা প্রসারিত করতে, বেশ কয়েকটি বিবরণ রয়েছে যা সাধারণত উপেক্ষা করা হয়।

  • পছন্দ subprocess.run()উপর subprocess.check_call()এবং বন্ধুদের উপর subprocess.call()উপর subprocess.Popen()উপর os.system()উপরos.popen()
  • বুঝতে এবং সম্ভবত ব্যবহার করুন text=True, ওরফে universal_newlines=True
  • মানে বুঝতে shell=Trueবা shell=Falseএবং কীভাবে উদ্ধৃত পরিবর্তন এবং শেল সুবিধা প্রাপ্যতা।
  • shবাশের মধ্যে পার্থক্য বুঝুন
  • কীভাবে সাব-প্রসেসটি তার পিতামাতার থেকে পৃথক এবং সাধারণভাবে পিতামাতাকে পরিবর্তন করতে পারে তা বুঝতে।
  • পাইথনের উপ-প্রসেস হিসাবে পাইথন ইন্টারপ্রেটার চালানো এড়িয়ে চলুন।

এই বিষয়গুলি নীচে আরও কিছু বিবরণে আচ্ছাদিত করা হয়েছে।

পছন্দ subprocess.run()বাsubprocess.check_call()

subprocess.Popen()ফাংশন একটি নিম্ন স্তরের workhorse কিন্তু এটি সঠিকভাবে ব্যবহার করতে চতুর এবং আপনি কপি শেষ / কোডের একাধিক লাইনের ... যা সুবিধামত ইতিমধ্যে বিভিন্ন উদ্দেশ্যে ফাংশন মোড়কের উচ্চ স্তরের একটি সেট হিসাবে মান গ্রন্থাগার মধ্যে উপস্থিত পেস্ট, যা নীচে আরও বিস্তারিতভাবে উপস্থাপন করা হয়েছে।

ডকুমেন্টেশন থেকে এখানে একটি অনুচ্ছেদ দেওয়া হয়েছে :

উপ-প্রক্রিয়াগুলি চালিত হওয়ার জন্য প্রস্তাবিত পদ্ধতির হ'ল এটি হ্যান্ডল করতে পারে এমন run()সমস্ত ব্যবহারের ক্ষেত্রে ফাংশনটি ব্যবহার করা। আরও উন্নত ব্যবহারের ক্ষেত্রে, অন্তর্নিহিত Popenইন্টারফেসটি সরাসরি ব্যবহার করা যেতে পারে।

দুর্ভাগ্যক্রমে, এই মোড়ক ফাংশনগুলির প্রাপ্যতা পাইথন সংস্করণগুলির মধ্যে পৃথক।

  • subprocess.run()পাইথন 3.5 তে আনুষ্ঠানিকভাবে চালু হয়েছিল। এটি নিম্নলিখিত সমস্ত প্রতিস্থাপন বোঝানো হয়।
  • subprocess.check_output()পাইথন 2.7 / 3.1 এ চালু হয়েছিল। এটি মূলত সমানsubprocess.run(..., check=True, stdout=subprocess.PIPE).stdout
  • subprocess.check_call()পাইথন 2.5 তে চালু হয়েছিল। এটি মূলত সমানsubprocess.run(..., check=True)
  • subprocess.call()মূল subprocessমডিউলে পাইথন ২.৪-এ প্রবর্তিত হয়েছিল ( পিইপি -324 )। এটি মূলত সমানsubprocess.run(...).returncode

উচ্চ-স্তরের API বনাম subprocess.Popen()

রিফ্যাক্টরড এবং প্রসারিত subprocess.run()পুরানো উত্তরাধিকারের ফাংশনগুলির পরিবর্তে এটি আরও যুক্তিযুক্ত এবং আরও বহুমুখী। এটি এমন একটি CompletedProcessবস্তু প্রদান করে যার বিভিন্ন পদ্ধতি রয়েছে যা আপনাকে প্রস্থান পরিস্থিতি, স্ট্যান্ডার্ড আউটপুট এবং সমাপ্ত সাবপ্রসেস থেকে কিছু অন্যান্য ফলাফল এবং স্থিতি সূচকগুলি পুনরুদ্ধার করতে দেয়।

subprocess.run()পাইথনে নিয়ন্ত্রণ চালাতে এবং চালানোর জন্য যদি আপনার কোনও প্রোগ্রামের প্রয়োজন হয় তবে যাবার উপায়। আরও জড়িত পরিস্থিতিতে (ব্যাকগ্রাউন্ড প্রক্রিয়াগুলি, সম্ভবত পাইথন প্যারেন্ট প্রোগ্রামের সাথে ইন্টারেক্টিভ I / O সহ) আপনাকে এখনও subprocess.Popen()সমস্ত নদীর গভীরতানির্ণয় নিজেকে ব্যবহার এবং যত্ন নিতে হবে। এর জন্য সমস্ত চলমান অংশগুলির সম্পর্কে মোটামুটি জটিলতা দরকার এবং এটি হালকাভাবে নেওয়া উচিত নয়। সরল Popenঅবজেক্টটি (সম্ভবত এখনও চলমান) প্রক্রিয়াটি উপস্থাপন করে যা সাব-প্রসেসের আজীবন বাকী থাকার জন্য আপনার কোড থেকে পরিচালনা করা দরকার needs

এটি সম্ভবত জোর দেওয়া উচিত যে কেবল subprocess.Popen()নিছক একটি প্রক্রিয়া তৈরি করে। যদি আপনি এটি এটি ছেড়ে দেন তবে পাইথনের পাশাপাশি আপনার একটি উপপদ্ধতি চলছে, সুতরাং একটি "পটভূমি" প্রক্রিয়া process যদি ইনপুট বা আউটপুট করার প্রয়োজন না হয় বা অন্যথায় আপনার সাথে সমন্বয় সাধনের প্রয়োজন না হয় তবে এটি আপনার পাইথন প্রোগ্রামের সাথে সমান্তরালে কার্যকর কাজ করতে পারে।

এড়ানো os.system()এবংos.popen()

অনাদি কাল থেকে (ভাল, পাইথন 2.5 এর পরে) osমডিউল ডকুমেন্টেশনে এর subprocessচেয়ে বেশি পছন্দ করার সুপারিশ রয়েছে os.system():

subprocessমডিউল নতুন প্রসেস ডিম ছাড়ার এবং তাদের ফলাফল পুনরুদ্ধারের জন্য আরো শক্তিশালী সুবিধা প্রদান করে; এই ফাংশনটি ব্যবহার করার জন্য সেই মডিউলটি ব্যবহার করা ভাল।

সমস্যাগুলি system()হ'ল এটি স্পষ্টতই সিস্টেম-নির্ভর এবং সাব-প্রসেসের সাথে ইন্টারঅ্যাক্ট করার উপায় সরবরাহ করে না। পাইথনের নাগালের বাইরে স্ট্যান্ডার্ড আউটপুট এবং স্ট্যান্ডার্ড ত্রুটি সহ এটি কেবল চলে। পাইথন ফিরে পাওয়া একমাত্র তথ্য হ'ল কমান্ডের প্রস্থান স্থিতি (শূন্য মানে সাফল্য, যদিও শূন্য-অমূল্যের অর্থ কিছুটা সিস্টেম-নির্ভর)।

পিইপি -324 (যা ইতিমধ্যে উপরে উল্লিখিত ছিল) কেন os.systemসমস্যাযুক্ত এবং কীভাবে subprocessএই সমস্যাগুলি সমাধান করার চেষ্টা করছে তার আরও বিশদ যুক্তি রয়েছে contains

os.popen()আরও দৃ strongly়ভাবে নিরুৎসাহিত হতে ব্যবহৃত :

সংস্করণ ২.6 থেকে হ্রাস করা: এই ফাংশনটি অচল। subprocessমডিউলটি ব্যবহার করুন ।

তবে পাইথন 3-এর কিছু সময় থেকে এটি কেবল ব্যবহারের জন্য পুনরায় প্রতিস্থাপন করা হয়েছে subprocessএবং subprocess.Popen()বিশদগুলির জন্য ডকুমেন্টেশনে পুনঃনির্দেশিত হয়েছে ।

বুঝতে এবং সাধারণত ব্যবহার check=True

আপনি দেখতে পাবেন যে subprocess.call()একই সীমাবদ্ধতা অনেক আছে os.system()। নিয়মিত ব্যবহারে, আপনার সাধারণত প্রক্রিয়াটি সফলভাবে শেষ হয়েছে কিনা তা যাচাই করা উচিত, কোনটি subprocess.check_call()এবং subprocess.check_output()কী (যেখানে পরবর্তীকালে সমাপ্ত সাবপ্রসেসের স্ট্যান্ডার্ড আউটপুটও ফিরে আসে)। একইভাবে, আপনি সাধারণত ব্যবহার করা উচিত check=Trueসঙ্গে subprocess.run()যদি না আপনি বিশেষভাবে একটি ত্রুটি অবস্থা ফিরে আসার subprocess অনুমতি প্রয়োজন।

অনুশীলনে, এর সাথে check=Trueবা subprocess.check_*পাইথন একটি CalledProcessErrorব্যতিক্রম ছুঁড়ে ফেলবে যদি সাবপ্রসেসটি ননজারো প্রস্থান স্থিতি ফিরে আসে।

সহ একটি সাধারণ ত্রুটি subprocess.run()হ'ল check=Trueসাব-প্রসেস ব্যর্থ হলে ডাউনস্ট্রিম কোড ব্যর্থ হয়ে গেলে বাদ দেওয়া এবং অবাক হওয়া।

অন্যদিকে, সঙ্গে একটি সাধারণ সমস্যা check_call()এবং check_output()যে যখন ব্যতিক্রম যেমন উত্থাপিত হয়েছিল যখন ব্যবহারকারী যারা অন্ধভাবে এই ফাংশন ব্যবহার বিস্মিত হয় ছিল grepএকটি ম্যাচ খুঁজে পাইনি। (আপনার সম্ভবত grepনীচের বর্ণনায় যেমন পাইথন কোডটি প্রতিস্থাপন করা উচিত ))

সমস্ত জিনিস গণনা করা হয়েছে, আপনাকে বুঝতে হবে শেল কমান্ডগুলি কীভাবে একটি প্রস্থান কোড ফেরত দেয় এবং কী পরিস্থিতিতে তারা কোন শূন্য-ত্রুটিযুক্ত (ত্রুটি) প্রস্থান কোডটি ফিরিয়ে দেবে এবং কীভাবে হ্যান্ডেল করা উচিত তা সচেতন সিদ্ধান্ত নিতে হবে।

বুঝুন এবং সম্ভবত text=Trueওরফে ব্যবহার করুনuniversal_newlines=True

পাইথন 3 যেহেতু পাইথনের অভ্যন্তরীণ স্ট্রিংগুলি ইউনিকোড স্ট্রিং। তবে কোনও গ্যারান্টি নেই যে একটি সাবপ্রসেস ইউনিকোড আউটপুট, বা স্ট্রিংগুলিতে উত্পন্ন করে।

(যদি তাত্ক্ষণিকভাবে তাত্ক্ষণিকভাবে সুস্পষ্ট না হয় তবে নেড ব্যাচেল্ডারের প্র্যাগমেটিক ইউনিকোডের প্রস্তাব দেওয়া হয়েছে, যদি পুরোপুরি বাধ্যতামূলক না হয় তবে পড়ুন you লিঙ্কের পিছনে একটি 36 মিনিটের ভিডিও উপস্থাপনা রয়েছে যদি আপনি পছন্দ করেন তবে পৃষ্ঠাটি নিজেই পড়া সম্ভবত সম্ভবত উল্লেখযোগ্যভাবে কম সময় নিবে। )

গভীর নীচে, পাইথনকে একটি bytesবাফার আনতে হবে এবং এটি কোনওভাবে ব্যাখ্যা করতে হবে। যদি এটিতে বাইনারি ডেটা থাকে তবে এটি কোনও ইউনিকোড স্ট্রিংয়ে ডিকোড করা উচিত নয় , কারণ এটি ত্রুটি-প্রবণ এবং বাগ-প্ররোচিত আচরণ - অবিকল আচরণের ধরণ যা বহু পাইথন 2 স্ক্রিপ্টগুলিকে ছাঁটাই করে তোলে, আগে কোনও উপায় থাকার আগে এনকোডযুক্ত পাঠ্য এবং বাইনারি ডেটার মধ্যে সঠিকভাবে পার্থক্য করুন।

এর মাধ্যমে text=True, আপনি পাইথনকে বলছেন যে আপনি আসলে সিস্টেমের ডিফল্ট এনকোডিংয়ে পাঠ্য ডেটা প্রত্যাশা করতে পারেন এবং এটি পাইথনের (ইউনিকোড) স্ট্রিংয়ে পাইথনের সর্বোত্তম দক্ষতার (সাধারণত ইউটিএফ -8) কোনও মাঝারি পর্যন্ত তারিখ সিস্টেম, সম্ভবত উইন্ডোজ বাদে?)

যদি আপনি এটির অনুরোধ না করেন তবে পাইথন আপনাকে কেবল bytesস্ট্রিং stdoutএবং stderrস্ট্রিংগুলি দেবে। কিছু হয়তো পরে বাতলান আপনি না জানে যে, তারা টেক্সট স্ট্রিং ছিল সব পরে, এবং তাদের এনকোডিং জানি। তারপরে, আপনি সেগুলি ডিকোড করতে পারেন।

normal = subprocess.run([external, arg],
    stdout=subprocess.PIPE, stderr=subprocess.PIPE,
    check=True,
    text=True)
print(normal.stdout)

convoluted = subprocess.run([external, arg],
    stdout=subprocess.PIPE, stderr=subprocess.PIPE,
    check=True)
# You have to know (or guess) the encoding
print(convoluted.stdout.decode('utf-8'))

পাইথন ৩.7 textকীওয়ার্ড আর্গুমেন্টটির জন্য স্বল্প এবং আরও বর্ণনামূলক এবং বোধগম্য নাম উপস্থাপন করেছিল যা আগে কিছুটা বিভ্রান্তিকরভাবে বলা হয়েছিল universal_newlines

shell=Trueবনাম বুঝতেshell=False

সঙ্গে shell=Trueআপনি আপনার শেল একটি একক পংক্তি পাস, এবং শেল সেখান থেকে এটা লাগে।

আপনার সাথে shell=Falseশেলকে বাইপাস করে ওএস-এ যুক্তিগুলির একটি তালিকা পাস করুন।

যখন আপনার শেল নেই, আপনি একটি প্রক্রিয়া সংরক্ষণ করুন এবং যথেষ্ট পরিমাণে লুকানো জটিলতা থেকে মুক্তি পাবেন , যা বাগগুলি বা এমনকি সুরক্ষার সমস্যাগুলিও বহন করতে পারে এবং নাও করতে পারে।

অন্যদিকে, যখন আপনার কাছে শেল নেই তখন আপনার পুনঃনির্দেশ, ওয়াইল্ডকার্ড সম্প্রসারণ, কাজের নিয়ন্ত্রণ এবং প্রচুর পরিমাণে অন্যান্য শেল বৈশিষ্ট্য নেই।

একটি সাধারণ ভুল ব্যবহার করা হয় shell=True এবং তারপরে পাইথনটিকে টোকেনের একটি তালিকা বা তার বিপরীতে পাস করা। এটি কিছু ক্ষেত্রে কাজ করার ক্ষেত্রে ঘটে তবে সত্যই এটি সংজ্ঞায়িত এবং আকর্ষণীয় উপায়ে ভেঙে যেতে পারে।

# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)

"তবে এটি আমার পক্ষে কাজ করে" এমন সাধারণ প্রতিক্রিয়া কোনও কার্যকর প্রত্যাখ্যান নয় যদি আপনি বুঝতে না পারেন কোন পরিস্থিতিতে কী কারণে এটি কাজ করা বন্ধ করতে পারে।

পুনরুদ্ধার উদাহরণ

খুব প্রায়শই, শেলের বৈশিষ্ট্যগুলি পাইথন কোডের সাথে প্রতিস্থাপন করা যেতে পারে। সরল ওক বাsed স্ক্রিপ্টগুলি সম্ভবত সহজেই এর পরিবর্তে পাইথনে অনুবাদ করা উচিত।

আংশিকভাবে এটি চিত্রিত করার জন্য, এখানে একটি সাধারণ তবে সামান্য নিরীহ উদাহরণ রয়েছে যা অনেকগুলি শেল বৈশিষ্ট্যযুক্ত।

cmd = '''while read -r x;
   do ping -c 3 "$x" | grep 'round-trip min/avg/max'
   done <hosts.txt'''

# Trivial but horrible
results = subprocess.run(
    cmd, shell=True, universal_newlines=True, check=True)
print(results.stdout)

# Reimplement with shell=False
with open('hosts.txt') as hosts:
    for host in hosts:
        host = host.rstrip('\n')  # drop newline
        ping = subprocess.run(
             ['ping', '-c', '3', host],
             text=True,
             stdout=subprocess.PIPE,
             check=True)
        for line in ping.stdout.split('\n'):
             if 'round-trip min/avg/max' in line:
                 print('{}: {}'.format(host, line))

এখানে কিছু বিষয় লক্ষণীয়:

  • আপনার সাথে shell=Falseশেলটির জন্য স্ট্রিংগুলির চারপাশে প্রয়োজনীয় উদ্ধৃতিগুলির প্রয়োজন নেই। যাই হোক না কেন উদ্ধৃতি স্থাপন সম্ভবত একটি ত্রুটি।
  • সাব-প্রসেসে যতটা সম্ভব কম কোড চালানো প্রায়শই বোধগম্য হয়। এটি আপনাকে আপনার পাইথন কোডের মধ্যে থেকে কার্যকরকরণের উপর আরও নিয়ন্ত্রণ দেয়।
  • এটি বলার পরে, জটিল শেল পাইপলাইনগুলি ক্লান্তিকর এবং কখনও কখনও পাইথনে পুনরায় বাস্তবায়ন করতে চ্যালেঞ্জের হয়।

রিফ্যাক্টরড কোডটি চিত্রিত করে যে শেলটি আপনার জন্য খুব সংশ্লেষের সিনট্যাক্স দিয়ে সত্যিকার অর্থে কী করে - আরও ভাল বা আরও খারাপের জন্য। পাইথন বলছেন স্পষ্ট অন্তর্নিহিত বেশী ভালো কিন্তু পাইথন কোড হয় বরং বাগাড়ম্বরপূর্ণ এবং তর্কসাপেক্ষ আরো জটিল চেয়ে সত্যিই দেখায়। অন্যদিকে, এটি বেশ কয়েকটি পয়েন্ট সরবরাহ করে যেখানে আপনি অন্য যে কোনও কিছুর মাঝে নিয়ন্ত্রণ দখল করতে পারবেন, যেমন তুচ্ছভাবে বর্ধনের দ্বারা উদাহরণস্বরূপ আমরা শেল কমান্ড আউটপুট সহ হোস্টের নামটি সহজেই অন্তর্ভুক্ত করতে পারি। (এটি কোনওভাবেই শেলটি করতে চ্যালেঞ্জিং নয়, তবে আরও একটি ডাইভারশন এবং সম্ভবত অন্য কোনও প্রক্রিয়া ব্যয় করে))

কমন শেল কনস্ট্রাক্টস

সম্পূর্ণতার জন্য, এখানে এই কয়েকটি শেল বৈশিষ্ট্যগুলির সংক্ষিপ্ত বিবরণ এবং সেগুলি কীভাবে সম্ভবত পাইথন সুবিধাগুলি দিয়ে প্রতিস্থাপন করা যায় সে সম্পর্কে কিছু নোট রয়েছে।

  • গ্লোব্বিং ওরফে ওয়াইল্ডকার্ড প্রসারণটি glob.glob()সাধারণ পাইথন স্ট্রিং তুলনার মতো বা প্রায়শই প্রতিস্থাপন করা যেতে পারে for file in os.listdir('.'): if not file.endswith('.png'): continue। বাশের অন্যান্য বিভিন্ন সম্প্রসারণ সুবিধা রয়েছে যেমন .{png,jpg}ব্রেস প্রসারণ এবং {1..100}তিল্ড সম্প্রসারণ ( ~আপনার বাড়ির ডিরেক্টরিতে প্রসারিত হয় এবং আরও সাধারণভাবে ~accountঅন্য ব্যবহারকারীর হোম ডিরেক্টরিতে প্রসারিত হয় )
  • শেল ভেরিয়েবলগুলির মতো $SHELLবা $my_exported_varকখনও কখনও পাইথন ভেরিয়েবলগুলির সাথে সহজেই প্রতিস্থাপন করা যায়। রপ্তানী শেল ভেরিয়েবল পাওয়া যায় যেমন যেমন os.environ['SHELL'](অর্থ exportপরিবর্তনশীল subprocesses উপলব্ধ করা হয় -। একটি পরিবর্তনশীল যা স্পষ্টত পাইথন শেল একটি subprocess, অথবা বিপরীতভাবে ভাইস যেমন চলমান উপলব্ধ হবে না subprocesses জন্য উপলব্ধ নয় env=শব্দ subprocessপদ্ধতির পক্ষে যুক্তি আপনাকে অভিধান হিসাবে সাবপ্রসেসের পরিবেশকে সংজ্ঞায়িত করতে দেয়, সুতরাং পাইথন ভেরিয়েবলটি একটি সাবপ্রসেসের জন্য দৃশ্যমান করার এক উপায়) সঙ্গে shell=Falseযদি আপনি কোন কোট অপসারণ কিভাবে বুঝতে হবে; উদাহরণস্বরূপ, cd "$HOME"সমানos.chdir(os.environ['HOME']) ডিরেক্টরি নামের প্রায় উদ্ধৃতি ছাড়া । (খুব প্রায়ইcdযাইহোক, দরকারী বা প্রয়োজনীয় নয় এবং অনেক নতুন নতুন ভেরিয়েবলের চারপাশে ডাবল উক্তি বাদ দেন এবং একদিন অবধি এটি নিয়ে পালিয়ে যান ... )
  • পুনঃনির্দেশ আপনাকে একটি স্ট্যান্ডার্ড ইনপুট হিসাবে কোনও ফাইল থেকে পড়তে এবং কোনও স্ট্যান্ডার্ড আউটপুট কোনও ফাইলে লেখার অনুমতি দেয়। লেখার জন্য এবং পড়ার জন্য grep 'foo' <inputfile >outputfileখোলে এবং এর বিষয়বস্তুগুলিকে স্ট্যান্ডার্ড ইনপুট হিসাবে পাস করে , যার স্ট্যান্ডার্ড আউটপুট এর পরে অবতরণ করে । নেটিভ পাইথন কোড দিয়ে প্রতিস্থাপন করা সাধারণত এটি কঠিন নয়।outputfileinputfilegrepoutputfile
  • পাইপলাইনগুলি পুনঃনির্দেশের একটি রূপ। echo foo | nlদুটি সাব-প্রসেসেস চালায়, যেখানে এর স্ট্যান্ডার্ড আউটপুট echoহ'ল স্ট্যান্ডার্ড ইনপুট nl( ইউএস -এর মতো সিস্টেমে, এটি একটি একক ফাইল হ্যান্ডেল) standard আপনি যদি পাইপলাইনের এক বা উভয় প্রান্তটি স্থানীয় পাইথন কোডের সাথে প্রতিস্থাপন করতে না পারেন তবে সম্ভবত শেলটি ব্যবহারের কথা ভাবুন, বিশেষত পাইপলাইনে যদি দুটি বা তিনটির বেশি প্রক্রিয়া থাকে (তবে pipesপাইথন স্ট্যান্ডার্ড লাইব্রেরির মডিউলটি দেখুন বা একটি সংখ্যা আরও আধুনিক এবং বহুমুখী তৃতীয় পক্ষের প্রতিযোগীদের)।
  • কাজের নিয়ন্ত্রণ আপনাকে চাকরিতে বাধা দেয়, তাদের পটভূমিতে চালাতে দেয়, অগ্রভাগে ফিরিয়ে দিতে পারে ইত্যাদি ইত্যাদি বন্ধ করতে এবং প্রক্রিয়া চালিয়ে যাওয়ার প্রাথমিক ইউনিক্স সংকেত অবশ্যই পাইথন থেকে পাওয়া যায়। তবে চাকরিগুলি শেলের মধ্যে একটি উচ্চ স্তরের বিমূর্তি যা প্রক্রিয়া গ্রুপগুলি ইত্যাদির সাথে জড়িত। যা আপনাকে পাইথন থেকে এই জাতীয় কিছু করতে চাইলে আপনাকে বুঝতে হবে।
  • শেলটি উদ্ধৃত করা সম্ভাব্য বিভ্রান্তিকর হয় যতক্ষণ না আপনি বুঝতে পারছেন যে সবকিছুই মূলত একটি স্ট্রিং। এর ls -l /সমতুল্য 'ls' '-l' '/'তবে আক্ষরিক প্রায় উদ্ধৃতি সম্পূর্ণ completelyচ্ছিক। শেল মেটাচার্যাক্টর সমন্বিত স্ট্রোকগুলি প্যারামিটার সম্প্রসারণ, সাদা স্থান টোকেনাইজেশন এবং ওয়াইল্ডকার্ড সম্প্রসারণের মধ্য দিয়ে যায়; ডাবল কোটস হোয়াইটস্পেস টোকেনাইজেশন এবং ওয়াইল্ডকার্ড সম্প্রসারণ রোধ করে তবে প্যারামিটার বিস্তৃতি (পরিবর্তনশীল বিকল্প, কমান্ড প্রতিস্থাপন এবং ব্যাকস্ল্যাশ প্রক্রিয়াজাতকরণ) অনুমতি দেয়। এটি তাত্ত্বিকভাবে সহজ তবে বিস্ময়কর হতে পারে, বিশেষত যখন ব্যাখ্যার বিভিন্ন স্তর থাকে (উদাহরণস্বরূপ একটি রিমোট শেল কমান্ড)।

shবাশের মধ্যে পার্থক্য বুঝুন

subprocessআপনার শেল কমান্ডগুলি চালনা করে /bin/shআপনি যদি অন্যভাবে অনুরোধ না করেন (উইন্ডোজে অবশ্যই এটি যেখানে COMSPECভেরিয়েবলের মান ব্যবহার করে )। এর অর্থ হ'ল বিভিন্ন বাশ-কেবল বৈশিষ্ট্য যেমন অ্যারে [[ইত্যাদি উপলভ্য নয়।

আপনার যদি কেবল বাশ-কেবল সিনট্যাক্স ব্যবহার করার প্রয়োজন হয় তবে আপনি শেলের দিকে যেতে executable='/bin/bash'পারেন (যেখানে অবশ্যই যদি আপনার ব্যাশ অন্য কোথাও ইনস্টল করা থাকে তবে আপনাকে পাথ সামঞ্জস্য করতে হবে)।

subprocess.run('''
    # This for loop syntax is Bash only
    for((i=1;i<=$#;i++)); do
        # Arrays are Bash-only
        array[i]+=123
    done''',
    shell=True, check=True,
    executable='/bin/bash')

subprocessতার পিতামাতার থেকে পৃথক এবং এটি পরিবর্তন করতে পারে না

কিছুটা সাধারণ ভুল এমন কিছু করছে

subprocess.run('foo=bar', shell=True)
subprocess.run('echo "$foo"', shell=True)  # Doesn't work

যা কমনীয়তার অভাব বাদ দিয়ে "সাবপ্রসেস" নামের "সাব" অংশটি বোঝার মৌলিক অভাবকেও বিশ্বাসঘাতকতা করে।

একটি শিশু প্রক্রিয়া পাইথন থেকে সম্পূর্ণ পৃথকভাবে চলে এবং যখন এটি শেষ হয়, পাইথন কোন কিছুর ধারণা রাখে না (অস্পষ্ট সূচকগুলি ছাড়াও এটি শিশু প্রক্রিয়া থেকে প্রস্থান পরিস্থিতি এবং আউটপুট থেকে বেরিয়ে আসতে পারে)। একটি শিশু সাধারণত পিতামাতার পরিবেশ পরিবর্তন করতে পারে না; এটি কোনও পরিবর্তনশীল সেট করতে পারে না, কার্যকরী ডিরেক্টরি পরিবর্তন করতে পারে, বা অনেক কথায়, পিতামাতার সহযোগিতা ছাড়াই তার পিতামাতার সাথে যোগাযোগ করতে পারে।

এই বিশেষ ক্ষেত্রে তাত্ক্ষণিক সংশোধন হ'ল উভয় কমান্ড একটি একক সাবপ্রসেসে চালানো;

subprocess.run('foo=bar; echo "$foo"', shell=True)

যদিও স্পষ্টতই এই নির্দিষ্ট ব্যবহারের ক্ষেত্রে শেলের কোনও প্রয়োজন হয় না। মনে রাখবেন, আপনি বর্তমান প্রক্রিয়াটির পরিবেশকে (এবং এটির শিশুরাও) এর মাধ্যমে পরিচালনা করতে পারেন

os.environ['foo'] = 'bar'

বা একটি পরিবেশ প্রক্রিয়া একটি শিশু প্রক্রিয়া সাথে পাস করুন

subprocess.run('echo "$foo"', shell=True, env={'foo': 'bar'})

(সুস্পষ্ট রিফ্যাক্টরিংয়ের কথা উল্লেখ না করা subprocess.run(['echo', 'bar']); তবে echoঅবশ্যই প্রথমে সাব-প্রসেসে চালিত কোনও কিছুর একটি দুর্বল উদাহরণ)।

পাইথন থেকে পাইথন চালাবেন না

এটি সামান্য সন্দেহজনক পরামর্শ; অবশ্যই এমন পরিস্থিতি রয়েছে যেখানে এটি অর্থবোধ করে না বা পাইথন স্ক্রিপ্ট থেকে পাইপথন দোভাষীকে একটি উপ-প্রসেস হিসাবে চালানোর জন্য এমনকি একান্ত প্রয়োজন। তবে খুব ঘন ঘন, সঠিক পন্থাটি কেবল importআপনার কলিং স্ক্রিপ্টে অন্য পাইথন মডিউলে থাকে এবং সরাসরি এর ক্রিয়াকলাপগুলিকে কল করে।

অন্য পাইথন স্ক্রিপ্ট যদি আপনার নিয়ন্ত্রণে থাকে এবং এটি কোনও মডিউল না হয় তবে এটিকে একটিতে রূপান্তর করার বিষয়টি বিবেচনা করুন । (এই উত্তরটি ইতিমধ্যে অনেক দীর্ঘ তাই আমি বিশদটি এখানে প্রকাশ করব না))

আপনার যদি সমান্তরালতা প্রয়োজন হয় তবে আপনি multiprocessingমডিউলের সাহায্যে পাইথন ফাংশনগুলি সাবপ্রসেসিতে চালাতে পারেন এছাড়াও রয়েছে threadingযা একটি একক প্রক্রিয়াতে একাধিক টাস্ক চালায় (যা আরও বেশি হালকা এবং আপনাকে আরও নিয়ন্ত্রণ দেয়, তবে প্রক্রিয়াটির মধ্যে থাকা থ্রেডগুলিতে আরও জোর দেওয়া হয় এবং এটি একটি জিআইএল-এর সাথে আবদ্ধ থাকে ))


2
আপনি কীভাবে পাইথনকে উপ-প্রসেস হিসাবে কল করা এড়াতে পারেন তার আরও বিশদ বিবরণের জন্য, এই উত্তরটি স্পর্শকাতরভাবে অনুরূপ প্রশ্নের উপর দেখুন।
ট্রিপলি

4
এটি আমার মনের ভাব ঘুরিয়ে দেয় যে কীভাবে প্রশ্ন থেকে কমান্ডটি অজ্ঞাতসারে চালাতে হয় তা দেখানোর জন্য আমাকে এই জাতীয় প্রাথমিক প্রশ্নের নতুন উত্তর পোস্ট করতে হয়েছিল। আপনার উত্তর দীর্ঘ তবে আমি এরকম উদাহরণ দেখছি না। সম্পর্কিত নয়: কার্গো-কাল্টিং এড়ান। যদি চেক_ক্যাল () আপনার ক্ষেত্রে কাজ করে তবে এটি ব্যবহার করুন। আমাকে এমন একটি কোড ঠিক করতে হয়েছিল যা run()অন্ধভাবে ব্যবহার করা হয়েছিল । অনুপস্থিতি check=Trueএকটি ত্রুটি সৃষ্টি করেছিল যা চেক_ক্যাল ব্যবহার করা হলে এড়ানো যেত - "চেক" নামে রয়েছে, আপনি এটি হারাতে পারবেন না - এটি সঠিক ডিফল্ট: নীরবে ত্রুটিগুলি উপেক্ষা করবেন না। আমি আর পড়িনি।
jfs

1
@jfs প্রতিক্রিয়াটির জন্য ধন্যবাদ, আমি আসলে বাশ বনাম সম্পর্কে একটি বিভাগ যুক্ত করার পরিকল্পনা করছিলাম shতবে আপনি আমাকে এতে মারধর করেছেন। আমি প্রাথমিক পর্যায়ে বিশদগুলিকে বানান করার চেষ্টা করছি যাতে প্রাথমিকভাবে যাদের সাহায্য করার জন্য এই সমস্যাগুলি সুস্পষ্ট না হয় যাতে এটি কিছুটা দীর্ঘায়িত হয়। আপনার অন্যথায় যথেষ্ট পর্যাপ্ত হওয়া উচিত; +1
ট্রিপলি

না stderr/stdout = subprocess.PIPEডিফল্ট সেটিংস চেয়ে উচ্চতর পারফরম্যান্স ওভারহেড আছে?
স্ট্রিংগার্স

1
@ স্ট্রিংগারগুলি আমি পরীক্ষা করে দেখিনি, তবে কেন এটি হওয়া উচিত তা আমি দেখছি না। যদি আপনি সেই পাইপগুলিকে এমন কোনও কিছুর সাথে সংযুক্ত করেন যা কিছু প্রক্রিয়াজাতকরণ করে, তবে অবশ্যই সেই প্রক্রিয়াজাতকরণটির জন্য প্রয়োজন হবে; কিন্তু পাইপে নিজেই এটি ঘটে না। ডিফল্ট হ'ল স্টডআউট বা স্টডারকে মোটেও ক্যাপচার না করা, অর্থাত এখানে যা কিছু মুদ্রিত হয় ঠিক তেমন পাইথনের দৃশ্যমানতা এবং নিয়ন্ত্রণের বাইরে os.system()
ট্রিপলি

41

সাব-প্রসেস সহ এটি কল করুন

import subprocess
subprocess.Popen("cwm --rdf test.rdf --ntriples > test.nt")

আপনি যে ত্রুটিটি পাচ্ছেন তা মনে হচ্ছে কারণ সার্ভারে কোনও অদলবদল নেই, আপনাকে সার্ভারে অদলবদল করা উচিত আবার স্ক্রিপ্টটি চালানো উচিত run


3
swapমডিউল অবশ্যই আছে কারণ শেল কাজ থেকে কমান্ড চলছে।
সোভেন মারনাচ

2
সার্ভারে নয়, যখন সে সার্ভারে এটি চালায় তখন একটি আমদানি ত্রুটি রয়েছে।
জাকব বোয়ের

@ এমকেএন: "তারপরে আমি কেবলমাত্র সেই আউটপুটটি অনুলিপি করে টার্মিনালে একটি অনুলিপি পেস্ট করেছি এবং এন্টার টিপুন এবং এটি কাজ করে ..." - আপনি সার্ভারে বা আপনার মেশিনে এটি চেষ্টা করেছিলেন?
সোভেন মারনাচ

এটি কি আপনি একা একা কম্পিউটারে এটি চালাচ্ছেন তবে আপনার সার্ভারে চালানোর সময় এটি কাজ করছে না? অথবা আপনি এটি সার্ভার টার্মিনালে চালাতে সক্ষম হন তবে সার্ভারটি নিজেই নয়
জাকব বোয়ার

1
এটি ভুল যদি আপনি ব্যবহার না করেন shell=Trueতবে আপনার একাধিক যুক্তি পাস করার জন্য একটি তালিকা ব্যবহার করা উচিত, ['a', 'b', 'c']পরিবর্তে ব্যবহার করুন 'a b c'। যদিও একটি নির্দোষ বিভাজন > fileকমান্ডের (শেল পুনর্নির্দেশ) কারণে কাজ করবে না । আরও বিশদ
jfs

18

কমান্ডগুলি কার্যকর করার জন্য আপনি প্যাসিটার -c সহ বাশ প্রোগ্রামটি ব্যবহার করতে পারবেন:

bashCommand = "cwm --rdf test.rdf --ntriples > test.nt"
output = subprocess.check_output(['bash','-c', bashCommand])

2
subprocess.check_output(bashCommand, shell=True)একই জিনিস। যদি আপনার কমান্ডটি স্থির স্ট্রিং থাকে তবে এটিকে নিজে একটি তালিকায় পার্স করার চেষ্টা করুন এবং এড়িয়ে চলুন shell=True; যদিও এক্ষেত্রে আপনার পুনঃনির্দেশের জন্য শেলটি প্রয়োজন, অন্যথায় আপনার এটি খাঁটি পাইথনকে রিফ্যাক্টর করতে হবে -with open('test.nt', 'w') as dest: output = subprocess.check_output(['cwm' ,'--rdf', 'test.rdf', '--ntriples'], stdout=dest, shell=False)
ট্রিপলি

@ ট্রিপলির দ্রষ্টব্য: /bin/sh(সাবপ্রসেস দ্বারা ব্যবহৃত) অগত্যা নয় bash(আপনি বাশিজম ব্যবহার করতে পারবেন না)। যদিও একটি executable='/bin/bashইচ্ছা করতে পারেন ব্যবহার করতে পারেন । এখানে একটি কোড উদাহরণ রয়েছে
jfs

2
। এটা প্রথম উত্তর যেখানে কমান্ড সফলভাবে (গ্রহণ করেন এবং 2nd জনপ্রিয় উত্তর শুধু ভুল একটি অপ্রধান টাল শুরু করা উচিত হল: check_output()এখানে বেহুদা (আউটপুট সবসময় কারণে খালি হয় > fileফেরৎ; ব্যবহার check_call()। পরিবর্তে
JFS

16

আপনি ব্যবহার করতে পারেন subprocess, তবে আমি সর্বদা অনুভব করেছি যে এটি করার কোনও 'পাইথোনিক' উপায় নয়। সুতরাং আমি সুলতান (নির্লজ্জ প্লাগ) তৈরি করেছি যা কমান্ড লাইন ফাংশনগুলি চালানো সহজ করে তোলে।

https://github.com/aeroxis/sultan


3
সাবাশ! সাব-প্রসেসের চেয়ে অনেক ক্লিনার এবং আরও স্বজ্ঞাত।
এমজেডি 2

তোমাকে অনেক ধন্যবাদ! শুনে আমি খুশি!
ডেভিড ড্যানিয়েল

2
এটিকে সততার সাথে স্ট্যান্ডার্ড লাইব্রেরিতে গ্রহণ করা উচিত।
জোশুয়া ডিটওয়েলার

1
সুলতান ব্যবহার করে টার্মিনাল থেকে আউটপুট ক্যাপচার করার কোনও উপায় আছে?
আলভাস 29:58

হ্যাঁ আপনি আলভাস করতে পারেন ... এটি কীভাবে করা যায় সে সম্পর্কে এখানে ডকস রয়েছে: সুলতান.ড্রেডহেডসকস.আইও
ডেভিড ড্যানিয়েল

7

ত্রুটি অনুসারে আপনি সার্ভারে স্ব্যাপ নামের একটি প্যাকেজ মিস করছেন । এটি /usr/bin/cwmপ্রয়োজন। আপনি যদি উবুন্টু / ডেবিয়ানে থাকেন তবে python-swapপ্রবণতা ব্যবহার করে ইনস্টল করুন ।


আমি যখন এটি সরাসরি টার্মিনালে চালিত করি তখন এটি কাজ করে ... তাই অদলবদল অবশ্যই সেখানে থাকতে হবে, তাই না?
এমকেএন

দুটি বিকল্প আছে। হয় এটি সন্ধান করতে পারে না swapবা এটি এটি প্রথম স্থানে আমদানি করা উচিত হয়নি। আপনি import swapনিজে করতে পারেন ? এটা কি কাজ করে?
কিচিক

এইচএম আমি পারছি না যদি আমি টার্মিনালে পাইথন টাইপ করে পাইথন শুরু করি এবং আমি আমদানি সোয়াপ টাইপ করি তবে আমি "ImportError: swap নামে কোনও মডিউল" ত্রুটিটি পেয়েছি। আজব জিনিসটি এখনও এটি কাজ করে যখন আমি সার্ভারের টার্মিনালে সরাসরি সিডব্লিউএম কমান্ডটি চালিত করি
mkn

sys.pathএটি কোথায় কাজ করছে এবং কোথায় নেই তা মুদ্রণের চেষ্টা করুন । তারপরে মুদ্রিত ফোল্ডারে অদলবদল ফোল্ডার বা swap.py সন্ধান করার চেষ্টা করুন। সোভেন যেমন বলেছিল, সেই রাস্তাগুলিতে কোনও সমস্যা হতে পারে এবং এটি আপনাকে এটি বের করতে সহায়তা করবে।
কিচিক

4

এছাড়াও আপনি 'os.popen' ব্যবহার করতে পারেন। উদাহরণ:

import os

command = os.popen('ls -al')
print(command.read())
print(command.close())

আউটপুট:

total 16
drwxr-xr-x 2 root root 4096 ago 13 21:53 .
drwxr-xr-x 4 root root 4096 ago 13 01:50 ..
-rw-r--r-- 1 root root 1278 ago 13 21:12 bot.py
-rw-r--r-- 1 root root   77 ago 13 21:53 test.py

None

1
ডকুমেন্টেশনে একটি বড় লাল বাক্স রয়েছে: " সংস্করণ ২.6 থেকে অবচয়: এই ফাংশনটি অপ্রচলিত the subprocessমডিউলটি ব্যবহার করুন ।"
ট্রিপলি

1
ন্যায্যতাতে, os.popenআর এই সতর্কতা নেই, এবং এটি subprocess.Popen()এখন প্রায় সরু মোড়ক ।
ট্রিপলি

4

শেল ছাড়াই কমান্ডটি চালাতে, কমান্ডটি একটি তালিকা হিসাবে পাস করুন এবং পাইথনে পুনঃনির্দেশটি ব্যবহার করে [subprocess]:

#!/usr/bin/env python
import subprocess

with open('test.nt', 'wb', 0) as file:
    subprocess.check_call("cwm --rdf test.rdf --ntriples".split(),
                          stdout=file)

দ্রষ্টব্য: > test.ntশেষে নেই stdout=fileপুনঃনির্দেশ কার্যকর করে।


পাইথনে শেলটি ব্যবহার করে কমান্ডটি চালনার জন্য কমান্ডটি স্ট্রিং হিসাবে পাস করুন এবং সক্ষম করুন shell=True:

#!/usr/bin/env python
import subprocess

subprocess.check_call("cwm --rdf test.rdf --ntriples > test.nt",
                      shell=True)

এখানে শেলটি আউটপুট পুনঃনির্দেশের জন্য দায়বদ্ধ ( > test.ntকমান্ডে রয়েছে)।


বাশ কমান্ড চালিত বাশ কমান্ড চালানোর জন্য, ব্যাশ নির্বাহযোগ্য স্পষ্টভাবে উদাহরণস্বরূপ, ব্যাশ প্রক্রিয়া প্রতিস্থাপন অনুকরণ করতে :

#!/usr/bin/env python
import subprocess

subprocess.check_call('program <(command) <(another-command)',
                      shell=True, executable='/bin/bash')

সম্ভবত উল্লেখ করা উচিত যে .split()যখন উদ্ধৃত স্ট্রিংগুলি রয়েছে তখন এগুলি যথাযথ নয় There একটি পৃথক রুটিন রয়েছে shlex.split()যা নির্বিচারে জটিল শেল সিনট্যাক্স সহ অনুলিপি করে।
ট্রিপলি

.split()এই ক্ষেত্রে কাজটি ট্রিপলই করুন । shlex.split()কখনও কখনও দরকারী হতে পারে তবে এটি কিছু ক্ষেত্রে ব্যর্থও হতে পারে। উল্লেখযোগ্য অনেকগুলি বিষয় রয়েছে। আপনি উপরে সরবরাহ করা সাবপ্রসেসি ট্যাগ বর্ণনার লিঙ্কটি দিয়ে শুরু করতে পারেন।
jfs

0

এটি করার অজগর উপায়টি ব্যবহার করছে subprocess.Popen

subprocess.Popen প্রথম তালিকাটি কোনও কমান্ড লাইন আর্গুমেন্ট অনুসরণ করার পরে চালানো কমান্ড বলে একটি তালিকা গ্রহণ করে।

উদাহরণ হিসাবে:

import subprocess

args = ['echo', 'Hello!']
subprocess.Popen(args) // same as running `echo Hello!` on cmd line

args2 = ['echo', '-v', '"Hello Again"']
subprocess.Popen(args2) // same as running 'echo -v "Hello Again!"` on cmd line

না, শেষ উদাহরণটি echo -v '"Hello Again!"'ডাবল কোটসের চারপাশে একক উদ্ধৃতি দিয়ে চলার সমান ।
ট্রিপল

এছাড়াও, সঠিকভাবে ব্যবহার করতে subprocesss.Popen, আপনাকে ফলস্বরূপ প্রক্রিয়া অবজেক্টটি পরিচালনা করতে হবে (কমপক্ষে, wait()এটি একটি জম্বি প্রক্রিয়াতে রূপান্তরিত হতে আটকাতে একটি সম্পাদন করুন )।
ট্রিপলি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.