آموزش subprocess python
آموزش subprocess python

آموزش subprocess python

زمان تقریبی مطالعه: 6 دقیقه

آموزش subprocess در پایتون

معرفی کتابخانه

کتابخانه subprocess در پایتون به شما برای تعامل با سیستم عامل کمک میکند ، با استفاده از این کتابخانه شما میتوانید فرایند های دیگه را در سیستم عامل اجرا کنید . متاسفانه در برخی از آموزش ها subprocess را به عنوان کتابخانه ای برای کار با cmd یا bash معرفی میکنند که اشتباهه ،cmd یا bash نیز نرم افزاری هست که با اجرای آن فرایندی در سیستم عامل آغاز میشود.

استفاده از subprocess

مثل تمام کتابخانه های دیگه python شما با استفاده از کامند import میتونید کتابخانه subprocess را وارد برنامه خودتون کنید.

استفاده از این کتابخانه بدون آنکه با یکسری از مفاهیم آشنایی داشته باشید به نظر سخت خواهد آمد ولی زمانی که مفهم هر دستوری که وارد میکنید را دقیقا یاد بگیرید و درک کنید هیچ چیز سختی وجود نخواهد داشت.

import subprocess

بعد از import کردن باید یکی از متد های subprocess را برای ادامه کار انتخاب کنید. متد پیشنهادی توستعه دهندگان run هستش که در ادامه متوجه دلیل پیشنهاد این متد خواهید شد.

اولین متد call است ، با استفاده از این متد میتونید کامند های خودتون را اجرا کنید. موضوعی که باید به بهش توجه کنید این است که تمام متد ها برای اجرا دستورات هستن ولی در روند اجرا با یک دیگر متفاوتن.

1- متند call کامند را از کاربر دریافت میکنید و بعد از جرا یک عدد بر میگرداند. این عدد اگر 0 باشد نشان دهنده اجرای صحیح کامند هستش و اگر غیر از 0 باشید یعنی در اجرای کامند به مشکل برخورده. اما توجه داشته باشید که درصورت وجود مشکل در روند اجرا کامند برنامه توقف نمیشود.

2 – موضوع بعدی در رابطه با خروجی دستور هستش . در متد call خروجی برای شما نمایش داده می‌شود ولی به صورت دیفالت شما نمیتونید خروجی را ذخیره کنید .

3 – موضوع آخر روند اجرا هستش ، زمانی که فرایندی را با متد call شروع میکند تا زمانی که فرایند به صورت کامل اجرا نشود کد های بعدی شما اجرا نخواهند شد .

استفاده از متد call

بعد از import کردن کتابخانه subprocess و انتخاب متد نوبت میرسد به کار با متد شکل کلی دستور به این شکل است:

import subprocess 
subprocess.call('ls')

کد بالا کامند “ls” که برای دریافت محتوایات یک دایرکتوری در لینوکس استفاده میشود را اجرا میکند که معادل کامند dir در ویندوز هستش اما اگر همین قطع کد بالا را با کامند dir در ویندوز اجرا کنید ارور دریافت خواهید کرد که در ادامه متوجه دلیل این موضوع خواهید شد .

خب ما تا به اینجا یک دستور ساده را با پایتون اجرا کردیم ، حالا سئوال این است اگر کامندی که ما استفاده میکنیم بیشتر از یک کلمه باشد باید چه ؟ یا ممکن است یک دستور سویچ های داشته باشد.

برای مثال کامند ls با سویچ l-

آیا اگر به این صورت دستور را وارد کنیم درست است ؟

import subprocess 
subprocess.call('ls -l')

کد بالا اشتباه هستش و بعد از اجرا ارور دریافت خواهید کرد !

آموزش subprocess python

دلیل این ارور چیزی است که در اول مقاله در بخش معرفی هم بهش اشاره کردیم و در ادامه درباره اش توضیح خواهیم داد

 

مفهوم CLI

subprocess به صورت مستقیم خود برنامه را اجرا میکند ، در سیستم عامل لینوکس کامند ls خود یک برنامه است در دایرکتوری bin ، زمانی که شما در subprocess دستور “ls -l ” را وارد میکنید subprocess به دنبال برنامه ای با همین اسم میگردد ولی همچین برنامه ای وجود ندارد ، ولی زمانی که” ls” وارد میکنید اسم دقیق برنامه را وارد کردین

اما در ویندوز اگر شما dir را وارد کنید ارور دریافت خواهید کرد زیاد dir خود یک برنامه نیست بلکه دستوری است که در برنامه cmd وجود دارد .

توجه داشته CLI یا واسط خط فرمان با bash یا cmd متفاوت است و در موارد زیاد دیده شده که این دو با یک دیگر اشتباه گرفته میشود.

برای این که این موضوع را بهتر درک کنید میتوان از GUI مثال زد ،وقتی از رابط کاربری گرافیگی ( GUI ) حرف میزنیم در واقع از یک روش ارتباط با سیستم عامل صحبت میکنیم ، این یک مفهموم است، حالا وقتی نوبت به عملیاتی کردن این مفهموم میرسد ما شاهد استفاده از نرم افزار های مختلف در سیستم عامل های مختلف هستیم .

برای مثال ، در لینوکس ما میتونیم از GNOME ، KDE ، MATE Desktop استفاده کنیم که هر کدوم خصوصیات خودشان را دارند.

در محیط متنی نیز ما میتوانیم از نرم افزار های مختلف استفاده کنیم و این نرم افزار ها متن هایی که ما وارد میکنیم را تفسیر میکنند ، برای مثال زمانی که که دستور ls -l را وارد میکنم در ترمینال لینوکس ، متن دستور به برنامه bash داده میشود و این برنامه متن دستور را تفسیر میکند که مثلا اگر بعد از کلمه اول کلمه دیگری آمد به عنوان ورودی به برنامه ls داده شود ، خود این برنامه ها میتوانن شامل دستوراتی باشن که در بالا هم مثال زدیم ، dir یک برنامه مجزا نیست و داخل برنامه cmd قرار دارد.

 

وارد کردن دستور و سویچ در متد call

با توضیحاتی که داده شده اکنون سئوال این است

چگونه دستور ” ls -l ” را وارد کنیم ؟

برای دستورات چند کلمه ای دو راه وجود دارد اولی استفاده از آرایه و دومی استفاده از پارامتر shell

روش آرایه :

در این روش باید از کلمه یک عنصر لیست باشد

به این صورت

import subprocess 
subprocess.call(['ls','l'])

روش shell :

در این روش باید پارمنتر shell را مساوی با True قرار دهید

به این صورت

import subprocess 
subprocess.call('ls -l',shell=True)

در این روش برنامه ls به صورت مستقیم اجرا نمی‌شود و تفسیر متن دستور به نرم افزار bash واگذار می‌شود که بالاتر درباره این مورد توضیحاتی دادیم

آموزش subprocess python

این روش به دلایل امنیتی توصیه نمی‌شود

متد check_output

تا به اینجا ما با استفاده از متد call دستورات را اجرا کردیم ، ولی در موارد زیاد ما به خروجی دستور نیاز دارید .

برای ردیافت خروجی دستور از متد check_output استفاده میکنیم ، روش استفاده دقیقا مثل متد call هست فقط در خروجی به جای عدد ، خروجی دستور را برمیگرداند که میتوانید در یک متغیر ذخیره کنید .

اما موضوعی که هست خروجی به صورت باینری برگردانند میشود که باید به متن تبدیل ب ، برای این کار باید از پارامتر text استفاده کنید .

import subprocess
subprocess.check_output("ls",text=True)

متد check_call

تا به اینجا ما اجرای دستور و دریافت خروجی را یادگرفتیم ، حالا در واقعی ممکن است نیاز باشد به اینکه در صورتی که کامند با خطا مواجه شد برنامه توقف شود یا ارور را پردازش کرد ، در متد call برخی ارور ها نادیده گرفته میشود ، یعنی در صورت خطا فقط عدد 1 ر ا برمیگرداند و برنامه ادامه فرایند را طی میکنید .

البته به این مورد هم دقیقت کنید که در برخی خطا ها در متد call هم برنامه توقف میشود.

 

متد run

تا به اینجا ما سه متد را برسی کردیم ، ولی همونطور که در اول آموزش نوشته شد توسعه دهندگان متد run را پیشنهاد میدهد ، دلیل این موضوع این است که متد run کار هر سه متد قبلی را انجام میدهد ، متد run در آپدیت های subprocess به این کتابخانه اضافه شده است و متد های قبلی به دلیل وجود در برنامه قدیمی از کتابخانه حذف نشدن تا برنامه ها به مشکل برنخورند.

متد run تقریبا مثل متد call عمل میکنه ولی خروجی یک class هستش و از داخل class میتوانید به مواردی که نیاز دارید دسترسی داشته باشید .

import subprocess

i = subprocess.run("dir",shell=True)

print (i)
print(type(i))


#output ( خروجی کد ) 

CompletedProcess(args='dir', returncode=0)
<class 'subprocess.CompletedProcess'>

اگر متد run را بدون هیچگونه پارامتری استفاده کنید فقط یک عدد برمیگرداند مثل متد call

برای دریافت همین عدد باید به این صورت عمل کرد

import subprocess
i = subprocess.run("dir",shell=True)
print (i.returncode)

#output
 0

این عدد مثل متد call اگر 0 بود به معنای اجرای صحیح دستور است

برخی پارامتر ها مشترک هست ، مثل پارامتر shell که در همه متد ها وجود داره و دیگر به این پارامتر نمیپردازیم

در ادامه پارامتر های دیگه را برسی میکنیم

 

قبل از هر پارامتری شما باید باید stdout , stderr آشنا شوید

stdout :

stdout مخفف Standard output هستش به معنی خروج استاندار ، زمانی که متد run خروجی داشته باشه داخل stdout قرار میگیرد .

stderr :

stderr مخفف Standard error به معنی ارور استاندار هستش ، زمانی که متد run اروری داشته باشد داخل این پارامتر قرار میگیرد

پارامتر capture_output و text:

برای گرفتن خروجی از دستور باید پارامتر capture_output را مساوی با True قرار بدین ، بعد از اجرای متد خروجی در stdout قرار میگیرید و میتواند به خروجی دسترسی داشته باشید

import subprocess

i = subprocess.run("dir",shell=True,capture_output=True)
print(i.stdout)

قطع کد بالا خروجی را به صورت باینری ذخیره میکنید

برای تبدیل کردن خروجی به متن باید از پارامتر text استفاده کنید , باید پارامتر text را مساوی True قرار دهید

import subprocess

i = subprocess.run("dir",shell=True,capture_output=True,text=True)
print(i.stdout)

پارامتر timeout :

در مواقعی اجرای یک دستور زمان زیاد نیاز دارد و با متد run تا زمان اجرای کامل دستور برنامه را نگه میدارد

و بعد از اجرای کامل بقیه کدهای اجرا میشود

برای کنترل مدت زمانی که متد run میتوند برای اجرای یک دستور صبر کنید میتوان از پارامتر timeout استفاده کرد

import subprocess

i = subprocess.run("dir",shell=True,timeout=5)
print(i.stdout)

پارامتر check:

متد run مثل متد call در صورتی که کامند به ارور بر بخورد برنامه را متوقف نمیکنید ،با این حال شما میتوانید با استفاده از پارامتر check رفتاری شبیه به متد check_call داشته باشید

import subprocess

i = subprocess.run("dir",shell=True,check=True)
print(i.stdout)

سخن پایانی

استفاده از subprocess در خیلی از موارد به کمک ما خواهد امد اما در صورتی که موارد امنیتی را رعایت نکنید به بزرگترین دشمن شما تبدیل خواهد شد

یک چشم پوش ساده میتواند باعث باگی مثل RCE شود

ممنون که با ما همراه بودین

 

اگر باز هم سئوالی درباره subprocess داشتید حتما داخل کامنت ها بنویسید

Rate this post