کار با subprocess

  • مدرس: علی بیگدلی
  • تاریخ انتشار: 1402/05/04
  • تعداد بازدید: 396

ماژول subprocess پایتون توابع آسانی را فراهم می کند که به ما امکان می دهد فرآیندی جدید طرح ریزی کرده و کدهای بازگشتی آنها را بدست آوریم. این ماژول در Python v2.4 معرفی شده است.

در این درس ، ما توابع مختلفی را که با ماژول subprocess در دسترس است و نحوه استفاده از آنها را مطالعه خواهیم کرد.

ماژول subprocess پایتون ابزاری قدرتمند است و برای جایگزینی ماژول ها / توابع مختلف قدیمی موجود در پایتون معرفی شد ، مانند:

  • os.system
  • os.spawn and related functions
  • os.popen and related functions
  • popen2.*
  • commands.*

 لطفا توجه داشته باشید که جایگزینی ها همانطور که هست نبودند و برای انتقال به استفاده از ماژول subprocess  به برخی اصلاحات در برنامه نیاز بود.

subprocess.call()

از این تابع برای اجرای یک دستور و دریافت کد برگشت دستور استفاده می شود. بیایید سریع یک نمونه کد را بررسی کنیم:

import subprocess

#linux
print(subprocess.call(["ls", "-l"]))

بیایید درک کنیم که در برنامه فوق چه اتفاقی افتاده است:

  • هنگامی که یک لیست آرگومان منتقل می شود ، اولین آرگومان به عنوان اجرایی تفسیر می شود.
  • پارامترهای از پارامتر دوم به بعد به عنوان آرگومان های خط فرمان برای برنامه در نظر گرفته می شوند.

ما همچنین می توانستیم  یه صورت زیر عمل کنیم:

import subprocess

#linux
print(subprocess.call('ls -l', shell=True))

#windows
print(subprocess.call('dir', shell=True))

با True بودن shell ، تابع call آن را به عنوان دستور کامل و به همان شکل که هست اجرا می کند. خروجی همه پرونده ها و دایرکتوری ها را در پوشه فعلی نشان می دهد.

توجه داشته باشید که در سیستم های مبتنی بر POSIX ، کد بازگشت 0 برای موفقیت و 1 تا 255 برای هر چیز دیگری است. این کدهای خروج توسط اسکریپت های ماشین برای ارزیابی وقایع موفقیت و شکست تفسیر می شوند.

subprocess.run()

این تابع دقیقاً مانند روش فراخوانی عمل می کند و برای اجرای یک دستور و دریافت کد برگشت دستور استفاده می شود. بیایید سریع یک نمونه کد را بررسی کنیم:

import subprocess

#linux
print(subprocess.run(["ls", "-l"]))

توجه داشته باشید که تابع run () در پایتون 3.5 اضافه شده است. یک تفاوت واضح بین عملکرد run () و call () این است که عملکرد call () از پارامترهای ورودی و بررسی پشتیبانی نمی کند.

subprocess.check_call()

این تابع مانند تابع call () عمل می کند اما اگر در اجرای دستور مشخص خطایی رخ دهد ، یک استثنا به نام CalledProcessError را ایجاد می کند. بیایید سریع یک نمونه کد را بررسی کنیم:

import subprocess

#linux
print(subprocess.check_call("false"))

#windows
print(subprocess.check_call('dir',shell=True))

ما از دستور false استفاده کردیم زیرا همیشه با کد بازگشت خطا برمی گردد.

subprocess.check_output()

وقتی از تابع () call برای اجرای یک دستور استفاده می کنیم ، خروجی به پردازش والد محدود می شود و برای برنامه فراخوانی غیرقابل بازیابی است. ما می توانیم از تابع () check_output برای گرفتن خروجی برای استفاده های بعدی استفاده کنیم. بیایید سریع یک نمونه کد را بررسی کنیم:

import subprocess
output = subprocess.check_output(['ls', '-1'])
print("Output is {} bytes long.".format(len(output)))

subprocess.communicate()

ما می توانیم از comunicate() در این ماژول پایتون برای خواندن ورودی و فرم خروجی خود فرآیند استفاده کنیم. stdout خروجی فرآیند است و در صورت بروز خطا stderr جمع می شود. بیایید سریع یک نمونه کد را بررسی کنیم:

import subprocess
process = subprocess.Popen(
    ['cat', 'hello.py'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = process.communicate()
print(stdout)

توجه داشته باشید که ما یک اسکریپت hello.py داریم که فقط می گوید print("hello").

subprocess.Popen()

 Popen برای اجرای یک برنامه کوچکتر در یک فرآیند جدید استفاده می شود. می توانیم از آن برای اجرای برخی از دستورات پوسته استفاده کنیم. بیایید به استفاده از Popen از طریق یک برنامه ساده بپردازیم.

import subprocess

process = subprocess.Popen(['ls', '-ltr'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

print(process.communicate())

process = subprocess.Popen(['echo', 'Pankaj'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=None)

print(process.communicate())

process = subprocess.Popen(['ping', '-c 1', 'journaldev.com'], stdout=subprocess.PIPE)

print(process.communicate())

خروجی:

(b'total 8\n-rw-r--r--  1 pankaj  staff  396 Dec  9 22:00 subprocess_popen.py\n', b'')
(b'Pankaj\n', b'')
(b'PING journaldev.com (209.124.77.163): 56 data bytes\n64 bytes from 209.124.77.163: icmp_seq=0 ttl=53 time=474.153 ms\n\n--- journaldev.com ping statistics ---\n1 packets transmitted, 1 packets received, 0.0% packet loss\nround-trip min/avg/max/stddev = 474.153/474.153/474.153/0.000 ms\n', None)

برای اطلاعات بیشتر به این لینک زیر مراحعه نمایید