উপশমে 'শেল = ট্রু' এর আসল অর্থ


260

আমি subprocessমডিউলটি দিয়ে বিভিন্ন প্রক্রিয়া কল করছি । তবে আমার একটা প্রশ্ন আছে।

নিম্নলিখিত কোডগুলিতে:

callProcess = subprocess.Popen(['ls', '-l'], shell=True)

এবং

callProcess = subprocess.Popen(['ls', '-l']) # without shell

দুটোই কাজ করে। দস্তাবেজগুলি পড়ার পরে, আমি shell=Trueশিখেছি এর অর্থ শেলটির মাধ্যমে কোডটি কার্যকর করা। অনুপস্থিতিতে এর অর্থ, প্রক্রিয়াটি সরাসরি শুরু হয়।

সুতরাং আমার ক্ষেত্রে আমার কী পছন্দ করা উচিত - আমার একটি প্রক্রিয়া চালানো এবং এটির ফলাফল পাওয়া দরকার get শেল থেকে বা এর বাইরে থেকে এটি কল করে আমার কী সুবিধা হবে।


21
প্রথম কমান্ডটি ভুল: ইউনিক্সে প্রোগ্রামের পরিবর্তে (শেল) -lপাস করা হয়েছে যদি । স্ট্রিং আর্গুমেন্ট বেশিরভাগ ক্ষেত্রে তালিকার পরিবর্তে ব্যবহার করা উচিত । /bin/shlsshell=Trueshell=True
jfs

1
পুনরায় "প্রক্রিয়া সরাসরি শুরু হয়": বাবু?
allyourcode

9
বিবৃতি "উভয় কাজ।" এই 2 টি কল সম্পর্কে ভুল এবং বিভ্রান্তিকর। কলগুলি ভিন্নভাবে কাজ করে। শুধু থেকে সুইচিং shell=Trueকরতে Falseএবং তদ্বিপরীত ত্রুটিপূর্ণ কিনা। দস্তাবেজগুলি থেকে : "শেল দিয়ে পসিক্সে = সত্য, (...) যদি আর্গুমেন্টগুলি একটি ক্রম হয় তবে প্রথম আইটেমটি কমান্ড স্ট্রিং নির্দিষ্ট করে এবং কোনও অতিরিক্ত আইটেম শেল নিজেই অতিরিক্ত আর্গুমেন্ট হিসাবে বিবেচিত হবে।" উইন্ডোজে স্বয়ংক্রিয় রূপান্তর রয়েছে , যা অনাকাঙ্ক্ষিত হতে পারে।
এমবিদেপল

আরও দেখুন stackoverflow.com/q/59641747/874188
tripleee

উত্তর:


183

শেলের মাধ্যমে কল না করার সুবিধাটি হ'ল আপনি 'রহস্য প্রোগ্রামটি' চালাচ্ছেন না। পসিক্সে, পরিবেশ পরিবর্তনশীল SHELLনিয়ন্ত্রণগুলি বাইনারিকে "শেল" হিসাবে ডাকা হয়। উইন্ডোজে কোনও বর্ন শেল অবতীর্ণ হয় না, কেবল সেমিডি.এক্সই।

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

শেলের মাধ্যমে চালনা শেলের স্বাভাবিক প্রক্রিয়া অনুসারে আপনাকে পরিবেশের ভেরিয়েবল এবং ফাইল গ্লোবগুলি প্রসারিত করতে দেয়। পসিক্স সিস্টেমে শেল ফাইল গ্লোবগুলি ফাইলের তালিকায় প্রসারিত করে। উইন্ডোজ, একটি ফাইল উল্লিখিত glob (যেমন, "*। *") উপর যাহাই হউক না কেন শেল দ্বারা প্রসারিত হয় না (তবে কমান্ড লাইনে বিভিন্ন পরিবেশের হয় cmd.exe দ্বারা প্রসারিত)।

আপনি যদি মনে করেন যে আপনি পরিবেশের পরিবর্তনশীল বিস্তৃতি এবং ফাইল গ্লোবগুলি চান, তবে ILSনেটওয়ার্ক সার্ভিসগুলিতে 1992-ইশ- এর আক্রমণগুলি অনুসন্ধান করুন যা শেলের মাধ্যমে উপ-প্রোগ্রামের অনুরোধ সম্পাদন করে। উদাহরণ sendmailজড়িত বিভিন্ন বাড়ির দরজা অন্তর্ভুক্ত ILS

সংক্ষেপে, ব্যবহার shell=False


2
উত্তর করার জন্য ধন্যবাদ. যদিও আমি সত্যিই সেই পর্যায়ে নেই যেখানে আমার শোষণ সম্পর্কে চিন্তা করা উচিত, তবে আমি বুঝতে পারি আপনি কী পাচ্ছেন।
ব্যবহারকারী225312

55
আপনি যদি শুরুতে গাফিল হন তবে কোনও পরিমাণ উদ্বেগ আপনাকে পরবর্তীতে ধরাতে সহায়তা করবে না। ;)
হান্টিকুট

আপনি যদি সাব-প্রসেসের সর্বাধিক স্মৃতি সীমাবদ্ধ করতে চান? stackoverflow.com/questions/3172470/…
প্রমোদ

8
সম্পর্কে বিবৃতি $SHELLসঠিক নয়। সাবপ্রসেসটি html উদ্ধৃত করতে: "ইউনিক্স সহ shell=True, শেলটি ডিফল্ট হয় /bin/sh।" (না $SHELL)
মার্সিন

1
@ ইউজার ২৪২৮০7:: হ্যাঁ, আপনি যদি পার্লের ব্যাকটিক অনুরোধটি ব্যবহার করেন, আপনি শেল আহবানটি ব্যবহার করছেন এবং একই সমস্যাগুলি খুলছেন। openআপনি যদি কোনও প্রোগ্রাম শুরু করতে এবং আউটপুট ক্যাপচার করার নিরাপদ উপায় চান তবে 3+ আরগ ব্যবহার করুন ।
শ্যাডোর্যাঞ্জার

137
>>> import subprocess
>>> subprocess.call('echo $HOME')
Traceback (most recent call last):
...
OSError: [Errno 2] No such file or directory
>>>
>>> subprocess.call('echo $HOME', shell=True)
/user/khong
0

শেল আর্গুমেন্টটিকে সত্যিকারের মান হিসাবে সেট করার ফলে সাবপ্রসেসটি একটি মধ্যবর্তী শেল প্রক্রিয়া তৈরি করে এবং কমান্ডটি চালাতে বলে। অন্য কথায়, একটি মধ্যবর্তী শেল ব্যবহারের অর্থ হ'ল কমান্ড চালনার আগে ভেরিয়েবল, গ্লোব প্যাটার্ন এবং কমান্ড স্ট্রিংয়ের অন্যান্য বিশেষ শেল বৈশিষ্ট্যগুলি প্রক্রিয়া করা হয়। এখানে, উদাহরণস্বরূপ, cho হোম ইকো কমান্ডের আগে প্রক্রিয়া করা হয়েছিল। প্রকৃতপক্ষে, শেল প্রসার সহ কমান্ডের ক্ষেত্রে এটি কমান্ডটি সাধারণ কমান্ড হিসাবে বিবেচিত ls -l হয়।

উত্স: সাবপ্রসেস মডিউল


16
কেন এটি নির্বাচিত উত্তর নয় তা জানেন না। এখন পর্যন্ত যা আসলে প্রশ্নের সাথে মেলে
রডরিগো লোপেজ গেরেরা

1
সম্মত হন। শেল = সত্য বলতে কী বোঝায় তা বোঝার জন্য এটি আমার পক্ষে একটি ভাল উদাহরণ।
ব্যবহারকারী 389955

2
শেল আর্গুমেন্টটিকে সত্যিকারের মান হিসাবে সেট করার ফলে একটি মধ্যবর্তী শেল প্রক্রিয়া সাব-প্রসেসের জন্ম দেয় এবং ওহ Oh শ্বর কমান্ডটি চালানোর জন্য এটি সব বলে দেয়। কেন এই উত্তর গৃহীত হয় না ??? কেন?
pouya

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

দুঃখিত, আমার আগের মন্তব্যটি আমার করার আগেই গিয়েছিল। পরিষ্কার হতে: আমি প্রায়শই শেল = সত্যের সাথে সাব-প্রসেসের ব্যবহার দেখতে পাই এবং কমান্ডটি একটি স্ট্রিং, যেমন 'ls -l', (আমি এই ত্রুটিটি এড়াতে আশা করি) তবে সাবপ্রসেসটি একটি তালিকা নেয় (এবং একটি স্ট্রিংকে একটি উপাদান তালিকা হিসাবে) । শেল (এবং সেই সাথে সুরক্ষা সংক্রান্ত সমস্যাগুলি ) চালিয়ে যাওয়ার জন্য একটি তালিকা সাবপ্রসেসক্ল্যাকাল (['ls', '-l']) ব্যবহার করুন
লিঙ্কন র্যান্ডাল ম্যাকফারল্যান্ড

42

শেল = সত্যের সাথে জিনিসগুলি যেখানে ভুল হতে পারে তার একটি উদাহরণ এখানে দেখানো হয়েছে

>>> from subprocess import call
>>> filename = input("What file would you like to display?\n")
What file would you like to display?
non_existent; rm -rf / # THIS WILL DELETE EVERYTHING IN ROOT PARTITION!!!
>>> call("cat " + filename, shell=True) # Uh-oh. This will end badly...

ডকটি এখানে চেক করুন: সাবপ্রসেস.কল ()


6
লিঙ্কটি খুব দরকারী। লিঙ্কটি যেমন বলেছে: অবিশ্বস্ত উত্স থেকে নিরবচ্ছিন্ন ইনপুট অন্তর্ভুক্তকারী শেল কমান্ডগুলি কার্যকর করা একটি প্রোগ্রামকে শেল ইনজেকশনের জন্য ঝুঁকিপূর্ণ করে তোলে, এটি একটি গুরুতর সুরক্ষা ত্রুটি যার ফলে স্বেচ্ছাসেবক কমান্ড কার্যকর হতে পারে। এই কারণে, শেল = ট্রু ব্যবহারের ক্ষেত্রে দৃ strongly়রূপে নিরুৎসাহিত করা হয় যেখানে বাহ্যিক ইনপুট থেকে কমান্ড স্ট্রিং তৈরি করা হয়।
jtuki

39

শেলের মাধ্যমে প্রোগ্রামগুলি সম্পাদন করার অর্থ হ'ল প্রোগ্রামটিতে পাস করা সমস্ত ব্যবহারকারীর ইনপুটটি অনুরোধ করা শেলের সিনট্যাক্স এবং শব্দার্থ বিধি অনুসারে ব্যাখ্যা করা। সর্বোপরি, এটি কেবল ব্যবহারকারীরই অসুবিধার কারণ হয় কারণ ব্যবহারকারীকে এই নিয়মগুলি মানতে হয়। উদাহরণস্বরূপ, উদ্ধৃতি চিহ্ন বা ফাঁকা স্থানগুলির মতো বিশেষ শেল অক্ষরযুক্ত পাথগুলি পালাতে হবে। সবচেয়ে খারাপ সময়ে, এটি সুরক্ষা ফাঁসের কারণ, কারণ ব্যবহারকারী স্বেচ্ছাসেবী প্রোগ্রামগুলি চালিয়ে যেতে পারে।

shell=Trueশব্দ বিভাজন বা পরামিতি বিস্তারের মতো নির্দিষ্ট শেল বৈশিষ্ট্যগুলি ব্যবহার করতে কখনও কখনও সুবিধাজনক। তবে, যদি এই জাতীয় বৈশিষ্ট্যটির প্রয়োজন হয়, তবে অন্যান্য মডিউলগুলি ব্যবহার করে আপনাকে দেওয়া হয় (যেমন os.path.expandvars()প্যারামিটার বিস্তারের shlexজন্য বা শব্দ বিভাজনের জন্য)। এর অর্থ আরও বেশি কাজ, তবে অন্যান্য সমস্যাগুলি এড়ানো।

সংক্ষেপে: shell=Trueসব উপায়ে এড়িয়ে চলুন ।


16

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

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

ওয়াইল্ডকার্ড সম্প্রসারণ, ভেরিয়েবল ইন্টারপোলেশন এবং পুনঃনির্দেশ সমস্ত দেশীয় পাইথন কনস্ট্রাক্টসগুলির সাথে প্রতিস্থাপন করা সহজ। পাইথনের একটি জটিল শেল পাইপলাইন যেখানে পাইথনগুলিতে অংশগুলি বা সমস্ত যুক্তিসঙ্গতভাবে পুনরায় লেখা যায় না এমন এক পরিস্থিতি হতে পারে যেখানে আপনি শেলটি ব্যবহারের বিষয়টি বিবেচনা করতে পারেন। আপনার এখনও পারফরম্যান্স এবং সুরক্ষা সম্পর্কিত প্রভাবগুলি নিশ্চিত হওয়া উচিত make

তুচ্ছ ক্ষেত্রে এড়াতে shell=True, কেবল প্রতিস্থাপন করুন

subprocess.Popen("command -with -options 'like this' and\\ an\\ argument", shell=True)

সঙ্গে

subprocess.Popen(['command', '-with','-options', 'like this', 'and an argument'])

লক্ষ্য করুন যে প্রথম আর্গুমেন্টটি স্ট্রিংগুলিতে execvp()কীভাবে পাস হবে তার তালিকা এবং কিভাবে স্ট্রিং এবং ব্যাকস্ল্যাশ-এস্কেডিং শেল মেটাচার্যাক্টরগুলি উদ্ধৃত করা সাধারণত প্রয়োজন হয় না (বা দরকারী, বা সঠিক)। সম্ভবত আরও দেখুন কখন শেল ভেরিয়েবলের চারপাশে উদ্ধৃতিগুলি लपेटতে হয়?

একদিকে যেমন, আপনি প্যাকেজটির Popenসরল subprocessমোড়কের মধ্যে কেউ যদি চান তা করেন তবে আপনি প্রায়শই এড়াতে চান। আপনার যদি সাম্প্রতিক পর্যায়ে পাইথন থাকে তবে আপনার সম্ভবত ব্যবহার করা উচিত subprocess.run

  • check=Trueএটির সাথে ব্যর্থ হবে যদি আপনি চালিত আদেশটি ব্যর্থ হয়।
  • সঙ্গে stdout=subprocess.PIPEকম্যান্ড এর আউটপুট গ্রহণ হবে।
  • কিছুটা অস্পষ্টভাবে, universal_newlines=Trueএটির সাথে সঠিক ইউনিকোড স্ট্রিংয়ের আউটপুট ডিকোড হবে (এটি bytesপাইথন 3 এ অন্যথায় সিস্টেমের এনকোডিংয়ের মধ্যে রয়েছে)।

যদি তা না হয় তবে অনেকগুলি কাজের জন্য, আপনি check_outputকোনও কমান্ড থেকে আউটপুট পেতে চান , এটি সফল হয়েছে কিনা তা পরীক্ষা করে নেওয়া হয়, বা check_callসংগ্রহের জন্য কোনও আউটপুট না থাকলে।

আমি ডেভিড কর্নের একটি উদ্ধৃতি দিয়ে বন্ধ করব: "পোর্টেবল শেল স্ক্রিপ্টের চেয়ে পোর্টেবল শেলটি লেখা সহজ" " এমনকি subprocess.run('echo "$HOME"', shell=True)উইন্ডোজ পোর্টেবল হয় না।


আমি ভেবেছিলাম উদ্ধৃতিটি ল্যারি ওয়াল থেকে এসেছে তবে গুগল আমাকে অন্যথায় বলে।
ট্রিপলি

এটি উচ্চ আলোচনার - তবে প্রতিস্থাপনের জন্য কোনও প্রযুক্তিগত পরামর্শ নেই: এখানে আমি ওএস-এক্স-তে, ম্যাক অ্যাপের পিডটি অর্জনের চেষ্টা করছি যা আমি 'ওপেন' এর মাধ্যমে চালু করেছি: প্রক্রিয়া = সাবপ্রসেস.পোপেন ('/ usr / bin / pgrep - এন '+ অ্যাপ_নাম, শেল = মিথ্যা, স্টডআউট = সাবপ্রসেস.পিপ, স্টার্ডার = সাবপ্রসেস.পি.পি.ই.) অ্যাপ_পিড, এরর = প্রসেস.কমিনিকেট () --- তবে আমি শেল = ট্রু ব্যবহার না করে এটি কাজ করে না। এখন কি?
মোটি শ্নের

কীভাবে এড়ানো যায় সে সম্পর্কে shell=Trueঅনেকগুলি প্রশ্ন রয়েছে , যার মধ্যে অনেকের দুর্দান্ত উত্তর রয়েছে। আপনি তার পরিবর্তে কেন এটি সম্পর্কে বাছাই হয়েছে ।
ট্রিপলি

প্রতিক্রিয়ার জন্য ধন্যবাদ সহজ উদাহরণ যুক্ত
ট্রিপলি

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.