اجرای پروسه در پایتون با ماژول Subprocess

برای اجرای پروسه در پایتون میتونیم از ماژول های os.system و subprocess استفاده کنیم

تو این پست با subprocess اشنا میشیم.

این مثال رو ببینید

کد بالا دستور `ls -l` رو در سیستم عامل اجرا میکنه

Popen اجرای دستور رو شروع میکنه ولی منتظر نمیمونه که پروسه تموم بشه این متد communicate هست که اینکارو میکنه

متد communicate یک پارامتر timeout میگیره که اگه اجرای پروسه بیشتر از این مقدار طول بکشه خطای TimeoutExpired ایجاد میشه

برای اینکه خروجی و خطاهای احتمالی دستور رو بگیرید باید `stdout=PIPE` و `stderr=PIPE` قرار بدید

stdout خروجی پروسه هست

stderr خروجی پروسه زمانی که خطا داشته باشه یعنی درواقع خروجی خطای پروسه

برای مثال اگه ‍‍`ls` رو اجرا کنید stdout میشه لیست فایلها و دایرکتوری های مسیر جاری و stderr خالی خواهد بود

ولی اگه ‍‍`ls -XXXX` که یک دستور اشتباه هست رو اجرا کنید stdout خالی خواهد بود و stderr مقدار زیر رو خواهد داشت

برای اینکه stderr به stdout بره و هردو رو یکجا داشته باشید باید `stderr=STDOUT` قرار بدید

 

برای اطمینان از اتمام پروسه، از متد wait هم میتونید استفاده کنید، این متد فقط کد خروجی (exit code) رو برمیگردونه

تو لینوکس برای اینکه exit code دستوری که اجرا کردید رو ببینید

 

با Popen میتونید مسیر جاری رو عوض کنید تا دستور تو اون مسیر اجرا بشه

و یا متغیر محیطی تنظیم کنید

 

برای اتمام پروسه هم میتونید از متدهای terminate و kill استفاده کنید که اگه اولی رو اجرا کنید سیگنال SIGTERM و دومی سیگنال SIGKILL رو به پروسه میفرسته

منبع کد

 

Popen به صورت پیش فرض اسم برنامه و سوییچ های مورد نظر شما رو در قالب لیست میگیره اینجا ‍‍`ls` اسم برنامه و `l-` سوییچ مورد نظر ماست

شما میتونید با کمک shlex دستورتون رو به لیست تبدیل کنید اینجوری برنامتون شاید یه مقدار قشنگتر بشه

حالا اگه بخوایم یه دستوری مثل ‍‍‍`ps aux | grep x` رو اجرا کنیم داریم

عملگر | خروجی دستور سمت چپش رو به ورودی دستور سمت راستش میفرسته

به خطا میخوریم چون پایتون انتظار داره تمام مقادیر بعد از اسم برنامه سوییچ برنامه باشه ولی اینجا `|` و `grep` سوییچ برنامه `ps` نیست بلکه یک عملگر و یک برنامه هستن.

برای اجرای این دستور دو تا راه حل داریم

اولی

و راه حل دوم این هست که `shell=True` بزاریم که در اینصورت دیگه نباید لیست بدیم و دستور مورد نظر رو در قالب رشته به Popen میدیم

حالا اگه تو لینوکس باشید پایتون دستور مورد نظر رو با `bin/sh/` اجرا میکنه به صوت زیر

که در اینصورت 3 تا پروسس `ps`، ‍`sh` و `grep` ایجاد میشه

روش بالا دوتا ایراد داره

اول اینکه از نظر امنیتی خیلی مناسب نیست

دوم هم اینکه اگه برای مثال متد terminate رو اجرا کنید سیگنال SIGTERM فقط به پروسه `sh` ارسال میشه و فقط اون بسته میشه و زیر پروسس ها باز میمونن

برای حل مشکل دوم میتونید از این راه حل استفاده کنید.

 

دریافت خروجی پروسه به صورت استریم

برای اینکه خروجی پروسه رو به صورت استریم بگیرید

از کانتکس منیجر استفاده کردیم تا زمانی که پروسه تموم شد stdout و stderr اون که بافر هستن بسته شن، اگه از communicate استفاده میکردیم خودش همین کارو میکرد (که چون خروجی رو استریم میخوایم communicate به کارمون نمیاد)

 

مستندات ماژول subprocess رو هم بخونید.

پاسخی بگذارید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *