از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
سیستم عامل پایتون و دستورات فرعی Popen
سرفصلهای مطلب
معرفی
پایتون چندین گزینه برای اجرای فرآیندهای خارجی و تعامل با سیستم عامل ارائه می دهد. با این حال، روش ها برای پایتون 2 و 3 متفاوت است. پایتون 2 چندین متد در آن دارد os
ماژول، که در حال حاضر منسوخ شده و جایگزین شده است subprocess
ماژول، که گزینه ترجیحی در پایتون 3 است.
در طول این مقاله در مورد انواع مختلف صحبت خواهیم کرد os
و subprocess
روش ها، روش استفاده از آنها، تفاوت آنها با یکدیگر، روی از چه نسخه ای از پایتون باید استفاده کرد و حتی چگونه دستورات قدیمی را به دستورات جدیدتر تبدیل کرد.
امیدواریم تا پایان این مقاله درک بهتری از روش فراخوانی دستورات خارجی از کد پایتون و روشی که باید برای انجام آن استفاده کنید، داشته باشید.
اولش بزرگتره os.popen*
مواد و روش ها.
روش های os.popen*
این os
ماژول چهار روش مختلف را ارائه می دهد که به ما امکان می دهد با سیستم عامل تعامل داشته باشیم (درست مانند خط فرمان) و ایجاد یک لوله به دستورات دیگر این روش هایی که من به آنها اشاره می کنم عبارتند از: popen
، popen2
، popen3
، و popen4
، که همه آنها در بخش های بعدی توضیح داده شده است.
هدف هر یک از این روش ها این است که بتوانید برنامه های دیگر را از کد پایتون خود فراخوانی کنید. این می تواند یک فایل اجرایی دیگر را فراخوانی کند، مانند برنامه C++ کامپایل شده خودتان، یا یک دستور پوسته مانند ls
یا mkdir
.
os.popen
این os.popen
متد یک لوله را از یک دستور باز می کند. این لوله به فرمان اجازه می دهد تا خروجی خود را به دستور دیگری ارسال کند. خروجی یک فایل باز است که توسط برنامه های دیگر قابل دسترسی است.
نحو به شرح زیر است:
os.popen(command(, mode(, bufsize)))
اینجا command
پارامتر چیزی است که شما اجرا می کنید و خروجی آن از طریق یک فایل باز در دسترس خواهد بود. بحث و جدل mode
مشخص می کند که آیا این فایل خروجی قابل خواندن (‘r’) یا قابل نوشتن (‘w’) است یا خیر. الحاق یک ‘b’ به mode
فایل را در حالت باینری باز می کند. بنابراین، برای مثال “rb” یک شی فایل باینری قابل خواندن تولید می کند.
برای بازیابی کد خروجی دستور اجرا شده، باید از close()
روش شی فایل
این bufsize
پارامتر می گوید popen
چه مقدار داده باید بافر شود و می تواند یکی از مقادیر زیر را در نظر بگیرد:
- 0 = بافر نشده (مقدار پیش فرض)
- 1 = خط بافر شده است
- N = اندازه تقریبی بافر، زمانی که N > 0; و مقدار پیش فرض، زمانی که N <0 باشد
این روش برای پلتفرم های یونیکس و ویندوز موجود است و از نسخه 2.6 پایتون منسوخ شده است. اگر در حال حاضر از این روش استفاده می کنید و می خواهید به نسخه Python 3 سوئیچ کنید، در اینجا معادل آن است. subprocess
نسخه برای پایتون 3:
روش | جایگزین توسط |
---|---|
pipe = os.popen(‘cmd’, ‘r’, bufsize) | pipe = Popen(‘cmd’, shell=True, bufsize=bufsize, stdout=PIPE).stdout |
pipe = os.popen(‘cmd’, ‘w’, bufsize) | pipe = Popen(‘cmd’, shell=True, bufsize=bufsize, stdin=PIPE).stdin |
کد زیر نمونه ای از روش استفاده از آن را نشان می دهد os.popen
روش:
import os
p = os.popen('ls -la')
print(p.read())
کد بالا از سیستم عامل می خواهد که همه فایل ها را در فهرست فعلی فهرست کند. خروجی روش ما که در آن ذخیره می شود p
، یک فایل باز است که در خط آخر کد خوانده و چاپ می شود. نتیجه این کد (در زمینه فهرست فعلی من) به شرح زیر است:
$ python popen_test.py
total 32
drwxr-xr-x 7 scott staff 238 Nov 9 09:13 .
drwxr-xr-x 29 scott staff 986 Nov 9 09:08 ..
-rw-r--r-- 1 scott staff 52 Nov 9 09:13 popen2_test.py
-rw-r--r-- 1 scott staff 55 Nov 9 09:14 popen3_test.py
-rw-r--r-- 1 scott staff 53 Nov 9 09:14 popen4_test.py
-rw-r--r-- 1 scott staff 49 Nov 9 09:13 popen_test.py
-rw-r--r-- 1 scott staff 0 Nov 9 09:13 subprocess_popen_test.py
os.popen2
این روش بسیار شبیه به روش قبلی است. تفاوت اصلی در خروجی روش است. در این مورد دو شی فایل را برمی گرداند، یکی برای stdin و یک فایل دیگر برای stdout.
نحو به شرح زیر است:
popen2(cmd(, mode(, bufsize)))
این آرگومان ها همان معنای روش قبلی را دارند. os.popen
.
این popen2
روش برای هر دو سیستم عامل یونیکس و ویندوز در دسترس است. با این حال، فقط در پایتون 2 یافت می شود. باز هم اگر می خواهید از آن استفاده کنید subprocess
نسخه به جای آن (با جزئیات بیشتر در زیر نشان داده شده است)، به جای آن از موارد زیر استفاده کنید:
روش | جایگزین توسط |
---|---|
(child_stdin، child_stdout) = os.popen2(‘cmd’، حالت، bufsize) |
p = Popen(‘cmd’، shell=True، bufsize=bufsize، stdin=PIPE، stdout=PIPE، close_fds=True) |
کد زیر یک مثال را نشان می دهد روی روش استفاده از این روش:
import os
in, out = os.popen2('ls -la')
print(out.read())
این کد همان نتایجی را ایجاد می کند که در خروجی کد اول در بالا نشان داده شده است. تفاوت در اینجا این است که خروجی از popen2
متد از دو فایل تشکیل شده است. بنابراین، خط دوم کد دو متغیر را تعریف می کند: in
و out
. در سطر آخر فایل خروجی را می خوانیم out
و print آن را به console.
os.popen3
این روش بسیار شبیه به روش های قبلی است. با این حال، تفاوت این است که خروجی دستور مجموعه ای از سه فایل است: stdin، stdout و stderr.
نحو عبارت است از:
os.popen3(cmd(, mode(, bufsize)))
جایی که استدلال ها cmd
، mode
، و bufsize
همان مشخصات روش های قبلی را دارند. این روش برای پلتفرم های یونیکس و ویندوز در دسترس است.
توجه داشته باشید که این روش منسوخ شده است و مستندات پایتون به ما توصیه می کند که آن را جایگزین کنیم popen3
روش به شرح زیر است:
روش | جایگزین توسط |
---|---|
(child_stdin, |
p = Popen(‘cmd’, shell=True, bufsize=bufsize, |
همانطور که در مثال های قبلی، کد زیر همان نتیجه ای را که در مثال اول ما مشاهده شد، ایجاد می کند.
import os
in, out, err = os.popen3('ls -la')
print(out.read())
اما در این حالت باید سه فایل stdin، stdout و stderr را تعریف کنیم. لیست فایل های ما ls -la
دستور در ذخیره می شود out
فایل.
os.popen4
همانطور که احتمالا حدس زدید، os.popen4
روش مشابه روش های قبلی است. با این حال، در این مورد، تنها دو فایل را برمی گرداند، یکی برای stdin و دیگری برای stdout و stderr.
این روش برای پلتفرم های یونیکس و ویندوز موجود است و (تعجب!) نیز از نسخه 2.6 منسوخ شده است. برای جایگزینی آن با متن مربوطه subprocess
Popen
تماس بگیرید، موارد زیر را انجام دهید:
روش | جایگزین توسط |
---|---|
(child_stdin، child_stdout_and_stderr) = os.popen4(‘cmd’، حالت، bufsize) |
p = Popen(‘cmd’, shell=True, bufsize=bufsize, |
کد زیر همان نتیجه را در مثال های قبلی ایجاد می کند که در خروجی کد اول در بالا نشان داده شده است.
import os
in, out = os.popen4('ls -la')
print(we.read())
همانطور که از کد بالا می بینیم، روش بسیار شبیه به آن است popen2
. با این حال out
فایل موجود در برنامه نتایج ترکیبی هر دو جریان stdout و stderr را نشان می دهد.
خلاصه تفاوت ها
تفاوت های بین متفاوت popen*
دستورات همگی مربوط به خروجی خود هستند که در جدول زیر خلاصه شده است:
روش | استدلال ها |
---|---|
ظاهر شود | stdout |
popen2 | stdin، stdout |
popen3 | stdin، stdout، stderr |
popen4 | stdin، stdout و stderr |
علاوه بر این popen2
، popen3
، و popen4
فقط در پایتون 2 در دسترس هستند اما در پایتون 3 موجود نیستند. پایتون 3 این موارد را در دسترس دارد popen
روش، اما توصیه می شود از subprocess
ماژول به جای آن، که در بخش بعدی با جزئیات بیشتر توضیح خواهیم داد.
susbprocess. روش Popen
این ماژول زیر فرآیند با هدف جایگزینی چندین روش موجود در ایجاد شده است os
ماژول، که چندان کارآمد در نظر گرفته نمی شد. در این ماژول، ما جدید را پیدا می کنیم Popen
کلاس
اسناد پایتون استفاده از Popen
در موارد پیشرفته، زمانی که روش های دیگر مانند subprocess.call
نمی تواند نیازهای ما را برآورده کند. این روش امکان اجرای یک برنامه را در کودکی فراهم می کند process. زیرا این توسط سیستم عامل به صورت جداگانه اجرا می شود process، نتایج به پلت فرم وابسته است.
پارامترهای موجود به شرح زیر است:
subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)
یک تفاوت اصلی از Popen
این است که یک کلاس است و نه فقط یک متد. بنابراین، هنگامی که ما تماس بگیرید subprocess.Popen
، ما در واقع سازنده کلاس را فراخوانی می کنیم Popen
.
چندین آرگومان در سازنده وجود دارد. مهمترین چیز برای درک این است args
، که حاوی دستور برای process می خواهیم اجرا کنیم می توان آن را به عنوان دنباله ای از پارامترها (از طریق یک آرایه) یا به عنوان یک رشته فرمان منفرد مشخص کرد.
دومین استدلالی که درک آن مهم است این است shell
، که به صورت پیش فرض است False
. در یونیکس، زمانی که باید دستوری را اجرا کنیم که متعلق به پوسته است، مانند ls -la
، باید تنظیم کنیم shell=True
.
به عنوان مثال، کد زیر دستور یونیکس را فراخوانی می کند ls -la
از طریق یک پوسته
import subprocess
subprocess.Popen('ls -la', shell=True)
نتایج را می توان در خروجی زیر مشاهده کرد:
$ python subprocess_popen_test.py
total 40
drwxr-xr-x 7 scott staff 238 Nov 9 09:13 .
drwxr-xr-x 29 scott staff 986 Nov 9 09:08 ..
-rw-r--r-- 1 scott staff 52 Nov 9 09:13 popen2_test.py
-rw-r--r-- 1 scott staff 55 Nov 9 09:14 popen3_test.py
-rw-r--r-- 1 scott staff 53 Nov 9 09:14 popen4_test.py
-rw-r--r-- 1 scott staff 49 Nov 9 09:13 popen_test.py
-rw-r--r-- 1 scott staff 56 Nov 9 09:16 subprocess_popen_test.py
با استفاده از مثال زیر از یک ماشین ویندوز، میتوانیم تفاوتهای استفاده از آن را ببینیم shell
پارامتر راحت تر در اینجا ما Microsoft Excel را از پوسته یا به عنوان یک برنامه اجرایی باز می کنیم. از پوسته، درست مثل این است که اکسل را از یک پنجره فرمان باز کنیم.
کد زیر اکسل را از پوسته باز می کند (توجه داشته باشید که باید مشخص کنیم shell=True
):
import subprocess
subprocess.Popen("start excel", shell=True)
با این حال، میتوانیم با فراخوانی فایل اجرایی اکسل، همان نتایج را دریافت کنیم. در این مورد، ما از پوسته استفاده نمی کنیم، بنابراین آن را با مقدار پیش فرض آن (False
) اما باید مسیر کامل فایل اجرایی را مشخص کنیم.
import subprocess
subprocess.Popen("C:\Program Files (x86)\Microsoft Office\Office15\excel.exe")
علاوه بر این، هنگامی که ما نمونه Popen
کلاس، ما به چندین روش مفید دسترسی داریم:
روش | شرح |
---|---|
Popen.poll() |
بررسی می کند که آیا کودک process خاتمه یافته است. |
Popen.wait() |
منتظر بچه باش process خاتمه دادن |
Popen.communicate() |
اجازه می دهد تا با process. |
Popen.send_signal() |
به کودک سیگنال می فرستد process. |
Popen.terminate() |
کودک را متوقف می کند process. |
Popen.kill() |
کودکی را می کشد process. |
لیست کامل را می توان در اسناد فرعی. متداول ترین روش مورد استفاده در اینجا است communicate
.
این communicate
متد به ما امکان می دهد داده ها را از ورودی استاندارد بخوانیم و همچنین به ما امکان می دهد داده ها را به خروجی استاندارد ارسال کنیم. یک تاپل تعریف شده را برمی گرداند (stdoutdata, stderrdata)
.
به عنوان مثال، کد زیر ویندوز را ترکیب می کند dir
و sort
دستورات
import subprocess
p1 = subprocess.Popen('dir', shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p2 = subprocess.Popen('sort /R', shell=True, stdin=p1.stdout)
p1.stdout.close()
out, err = p2.communicate()
به منظور ترکیب هر دو دستور، ما دو فرآیند فرعی ایجاد می کنیم، یکی برای dir
فرمان و دیگری برای sort
فرمان از آنجایی که می خواهیم به ترتیب معکوس مرتب کنیم، اضافه می کنیم /R
گزینه به sort
زنگ زدن.
stdout را تعریف می کنیم process 1 به عنوان PIPE، که به ما امکان می دهد از خروجی استفاده کنیم process 1 به عنوان ورودی برای process 2. سپس باید stdout of را ببندیم process 1، بنابراین می توان از آن به عنوان ورودی استفاده کرد process 2. ارتباط بین process از طریق به دست می آید communicate
روش.
اجرای این مورد از پوسته فرمان ویندوز موارد زیر را ایجاد می کند:
> python subprocess_pipe_test.py
11/09/2017 08:52 PM 234 subprocess_pipe_test.py
11/09/2017 07:13 PM 99 subprocess_pipe_test2.py
11/09/2017 07:08 PM 66 subprocess_pipe_test3.py
11/09/2017 07:01 PM 56 subprocess_pipe_test4.py
11/09/2017 06:48 PM <DIR> ..
11/09/2017 06:48 PM <DIR> .
Volume Serial Number is 2E4E-56A3
Volume in drive D is ECA
Directory of D:\MyPopen
4 File(s) 455 bytes
2 Dir(s) 18,634,326,016 bytes free
بسته شدن
این os
روش ها در گذشته گزینه خوبی بودند، اما در حال حاضر subprocess
ماژول چندین روش دارد که استفاده از آنها قدرتمندتر و کارآمدتر است. از جمله ابزارهای موجود است Popen
کلاس، که می تواند در موارد پیچیده تر استفاده شود. این کلاس همچنین شامل communicate
روشی که به ما کمک میکند تا دستورات مختلف را برای عملکرد پیچیدهتر کنار هم قرار دهیم.
از چی استفاده میکنی popen*
روش ها برای، و شما کدام را ترجیح می دهید؟ در نظرات به ما اطلاع دهید!
(برچسبها به ترجمه)# python
منتشر شده در 1403-01-29 04:55:04