এখানে পূর্ববর্তী উত্তরগুলিকে কিছুটা প্রসারিত করতে, বেশ কয়েকটি বিবরণ রয়েছে যা সাধারণত উপেক্ষা করা হয়।
- পছন্দ
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
খোলে এবং এর বিষয়বস্তুগুলিকে স্ট্যান্ডার্ড ইনপুট হিসাবে পাস করে , যার স্ট্যান্ডার্ড আউটপুট এর পরে অবতরণ করে । নেটিভ পাইথন কোড দিয়ে প্রতিস্থাপন করা সাধারণত এটি কঠিন নয়।outputfile
inputfile
grep
outputfile
- পাইপলাইনগুলি পুনঃনির্দেশের একটি রূপ।
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
যা একটি একক প্রক্রিয়াতে একাধিক টাস্ক চালায় (যা আরও বেশি হালকা এবং আপনাকে আরও নিয়ন্ত্রণ দেয়, তবে প্রক্রিয়াটির মধ্যে থাকা থ্রেডগুলিতে আরও জোর দেওয়া হয় এবং এটি একটি জিআইএল-এর সাথে আবদ্ধ থাকে ))
cwm
। আপনার নিজের মধ্যে এমন কিছু কনফিগারেশন রয়েছে.bashrc
যা ইন্টারেক্টিভ বাশ ব্যবহারের জন্য পরিবেশ নির্ধারণ করে?