كيفية تنفيذ أوامر شل في بايثون باستخدام طريقة تشغيل العملية الفرعية

How Execute Shell Commands Python Using Subprocess Run Method



Subprocess عبارة عن وحدة Python مضمنة يمكن استخدامها لإنشاء عمليات جديدة والتفاعل مع تدفقات بيانات الإدخال والإخراج. بعبارات أبسط ، يمكنك استخدامه لتشغيل أوامر shell وتشغيل ثنائيات قابلة للتنفيذ عادة ما تكون مبعثرة في مجلدات سلة مختلفة عبر نظام ملفات Linux. يمكنك أيضًا توفير مسار كامل لثنائي قابل للتنفيذ واستخدام أي مفاتيح تبديل سطر أوامر مرتبطة بالثنائي. تشرح هذه المقالة كيفية استخدام وحدة العملية الفرعية وطريقة تشغيلها في تطبيقات Python. تم اختبار جميع عينات الكود في المقالة باستخدام Python 3.8.2 على Ubuntu 20.04.

طريقة Subprocess.run

تأخذ طريقة Subprocess.run قائمة بالمتغيرات. عندما يتم استدعاء الأسلوب ، فإنه ينفذ الأمر وينتظر انتهاء العملية ، ويعيد كائن CompletedProcess في النهاية. يقوم الكائن CompletedProcess بإرجاع stdout ، stderr ، الوسائط الأصلية المستخدمة أثناء استدعاء الطريقة ، وكود الإرجاع. يشير Stdout إلى تدفق البيانات الناتج عن الأمر ، بينما يشير stderr إلى أي أخطاء تظهر أثناء تنفيذ البرنامج. أي رمز إرجاع غير صفري (رمز الإنهاء) يعني خطأ في تنفيذ الأمر في طريقة subprocess.run.







مثال 1: إخراج محتويات ملف نصي باستخدام طريقة Subprocess.run

سيخرج الأمر أدناه محتويات ملف data.txt ، بافتراض أنه يحتوي على name = John string.



يستورد عملية فرعية
عملية فرعية.يركض(['قط'و 'data.txt'])

سيؤدي تشغيل الكود أعلاه إلى إرجاع المخرجات التالية:



اسم=يوحنا
اكتملت العملية(أرجس=['قط'و 'data.txt']ورمز الإرجاع=0)

العنصر الأول في وسيطة القائمة هو اسم الأمر المراد تنفيذه. يعتبر أي عنصر في القائمة يتبع العنصر الأول خيارات سطر أوامر أو رموز تبديل. يمكنك أيضًا استخدام شرطة مفردة وشرطات مزدوجة لتحديد الخيارات. على سبيل المثال ، لسرد الملفات والمجلدات في دليل ، سيكون الرمز subprocess.run ([ls، -l]. في معظم هذه الحالات ، يمكنك اعتبار أي وسيطة مفصولة بمسافات في أمر shell كعنصر فردي في القائمة المقدمة إلى طريقة subprocess.run.





مثال 2: قمع إخراج طريقة Subprocess.run

لمنع إخراج طريقة subprocess.run ، سيتعين عليك توفير stdout = subprocess.DEVNULL و stderr = subprocess.DEVNULL كوسائط إضافية.

يستورد عملية فرعية

عملية فرعية.يركض(['قط'و 'data.txt']وstdout=عملية فرعية.ديفنولو
ستدير=عملية فرعية.ديفنول)

سيؤدي تشغيل الكود أعلاه إلى إنتاج المخرجات التالية:



CompletedProcess (args = ['cat'، 'data.txt'] ، كود الإرجاع = 0)

مثال 3: التقاط إخراج طريقة Subprocess.run

لالتقاط ناتج طريقة subprocess.run ، استخدم وسيطة إضافية تسمى capture_output = True.

يستورد عملية فرعية
انتاج= عملية فرعية.يركض(['قط'و 'data.txt']والتقاط_خرج=حقيقي)
مطبعة (انتاج)

سيؤدي تشغيل الكود أعلاه إلى إنتاج المخرجات التالية:

اكتملت العملية(أرجس=['قط'و 'data.txt']ورمز الإرجاع=0و
stdout=ب'name = جونن'وستدير=ب')

يمكنك الوصول بشكل فردي إلى قيم stdout و stderr باستخدام طرق output.stdout و output.stderr. يتم إنتاج الإخراج كتسلسل بايت. للحصول على سلسلة كإخراج ، استخدم طريقة output.stdout.decode (utf-8). يمكنك أيضًا توفير text = True كوسيطة إضافية لاستدعاء subprocess.run للحصول على الإخراج بتنسيق سلسلة. للحصول على رمز حالة الخروج ، يمكنك استخدام طريقة output.returncode.

مثال 4: رفع الاستثناء عند فشل الأمر المنفذ بواسطة طريقة Subprocess.run

لإثارة استثناء عند إنهاء الأمر بحالة غير صفرية ، استخدم الوسيطة check = True.

يستورد عملية فرعية
عملية فرعية.يركض(['قط'و 'data.tx']والتقاط_خرج=حقيقيونص=حقيقيوالتحقق من=حقيقي)

سيؤدي تشغيل الكود أعلاه إلى إنتاج المخرجات التالية:

رفع CalledProcessError (retcode ، process.args ،
subprocess.CalledProcessError: الأمر '[' cat '،' data.tx ']'
أعاد حالة خروج غير صفرية 1.

مثال 5: قم بتمرير سلسلة إلى أمر تم تنفيذه بواسطة طريقة Subprocess.run

يمكنك تمرير سلسلة إلى الأمر ليتم تنفيذه بواسطة طريقة subprocess.run باستخدام وسيطة input = 'string'.

يستورد عملية فرعية
انتاج= عملية فرعية.يركض(['قط']و إدخال='data.txt'والتقاط_خرج=حقيقيو
نص=حقيقيوالتحقق من=حقيقي)
مطبعة (انتاج)

سيؤدي تشغيل الكود أعلاه إلى إنتاج المخرجات التالية:

CompletedProcess (args = ['cat'] ، returncode = 0 ، stdout = 'data.txt' ، stderr = '')

كما ترى ، فإن الكود أعلاه يمرر data.txt كسلسلة وليس ككائن ملف. لتمرير data.txt كملف ، استخدم الوسيطة stdin.

مع افتح('data.txt') كماF:
انتاج= عملية فرعية.يركض(['قط']وستدين=Fوالتقاط_خرج=حقيقيو
نص=حقيقيوالتحقق من=حقيقي)
مطبعة (انتاج)

سيؤدي تشغيل الكود أعلاه إلى إنتاج المخرجات التالية:

CompletedProcess (args = ['cat']، returncode = 0، stdout = 'name = John n'، stderr = '')

مثال 6: تنفيذ الأمر مباشرة في Shell باستخدام أسلوب Subprocess.run

من الممكن تشغيل أمر ما مباشرة في الصَدَفة كما هو ، بدلاً من استخدام تقسيم سلسلة في الأمر الرئيسي والخيارات التي تليها. للقيام بذلك ، يجب أن تمرر shell = True كوسيطة إضافية. ومع ذلك ، لم يشجع مطورو Python هذا لأن استخدام shell = True يمكن أن يؤدي إلى مشكلات أمنية. يمكنك قراءة المزيد حول الآثار الأمنية من هنا .

يستورد عملية فرعية
عملية فرعية.يركض('القط' data.txt ''وصدفة=حقيقي)

سيؤدي تشغيل الكود أعلاه إلى إنتاج المخرجات التالية:

الاسم = جون

استنتاج

تعتبر طريقة subprocess.run في Python قوية جدًا ، حيث تتيح لك تشغيل أوامر shell داخل python نفسها. يساعد هذا في تقييد كل التعليمات البرمجية على Python نفسها دون الحاجة إلى وجود تعليمات برمجية إضافية للقذيفة في ملفات منفصلة. ومع ذلك ، قد يكون من الصعب جدًا ترميز أوامر shell بشكل صحيح في قائمة Python. يمكنك استخدام طريقة shlex.split () لترميز أوامر shell البسيطة ، ولكن في الأوامر الطويلة والمعقدة - خاصة تلك التي تحتوي على رموز الأنابيب - يفشل shlex في تقسيم الأمر بشكل صحيح. في مثل هذه الحالات ، يمكن أن يكون تصحيح الأخطاء مشكلة صعبة. يمكنك استخدام وسيطة shell = True لتجنب ذلك ، ولكن هناك مخاوف أمنية معينة مرتبطة بهذا الإجراء.