إنشاء ملف قابل للتنفيذ العملية دون استخدام قذيفة على بايثون 2.5 و أدناه
-
05-07-2019 - |
سؤال
مجرد ما يقول العنوان:
- على
subprocess
الوحدة لا يمكن أن يستخدم هذا يجب أن تعمل على 2.4 و 2.5 - شل العملية لا ينبغي أن تكون ولدت لتمرير الحجج.
شرح (2), النظر في التعليمات البرمجية التالية:
>>> x=os.system('foo arg')
sh: foo: not found
>>> x=os.popen('foo arg')
sh: foo: not found
>>>
كما ترون os.system
و os.popen
يعمل على إعطاء الأوامر ("foo") عن طريق نظام قذيفة ("sh").أنا لا أريد أن يحدث هذا (وإلا القبيح 'غير موجود' رسائل مطبوعة على برنامج stderr دون إرادتي).
أخيرا, يجب أن تكون قادرة على تمرير الوسائط هذا البرنامج ('ب' في المثال أعلاه).
كيف يمكن للمرء أن تذهب عن القيام بذلك في بايثون 2.5 2.4?
المحلول
ربما تحتاج إلى استخدام subprocess الوحدة التي تتوفر في بيثون 2.4
Popen("/home/user/foo" + " arg")
>>> Popen("foo arg", shell=False)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.6/subprocess.py", line 595, in __init__
errread, errwrite)
File "/usr/lib/python2.6/subprocess.py", line 1092, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
سوف تحتاج إلى تضمين المسار الكامل منذ كنت لا تستخدم قذيفة.
http://docs.python.org/library/subprocess.html#replacing-os-system
بدلا من ذلك يمكنك أيضا تمرير subprocess.الأنابيب إلى stderr و stdout لقمع الرسائل.انظر الرابط أعلاه لمزيد من التفاصيل.
نصائح أخرى
كما هو موضح سابقا ، يمكنك (ويجب) استخدام subprocess وحدة نمطية.
بشكل افتراضي ، shell
المعلمة False
.هذا هو جيدة و آمنة تماما.أيضا, أنت لا تحتاج إلى تمرير المسار الكامل فقط تمرير الملف القابل للتنفيذ اسم و الحجج كما تسلسل (tuple أو قائمة).
import subprocess
# This works fine
p = subprocess.Popen(["echo","2"])
# These will raise OSError exception:
p = subprocess.Popen("echo 2")
p = subprocess.Popen(["echo 2"])
p = subprocess.Popen(["echa", "2"])
يمكنك أيضا استخدام هذه اثنين من وظائف الراحة المعرفة مسبقا في subprocess وحدة:
# Their arguments are the same as the Popen constructor
retcode = subprocess.call(["echo", "2"])
subprocess.check_call(["echo", "2"])
تذكر يمكنك إعادة توجيه stdout
و/أو stderr
إلى PIPE
, وبالتالي لن تكون مطبوعة على الشاشة (لكن الانتاج لا تزال متاحة للقراءة بواسطة برنامج بيثون).بشكل افتراضي ، stdout
و stderr
على حد سواء None
, مما يعني لا إعادة توجيه, مما يعني أنها سوف تستخدم نفس المعياري/stderr الخاص بك برنامج بيثون.
كما يمكنك استخدام shell=True
وإعادة توجيه stdout
.stderr
إلى الأنابيب ، وبالتالي لا أن تكون الرسالة مطبوعة:
# This will work fine, but no output will be printed
p = subprocess.Popen("echo 2", shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# This will NOT raise an exception, and the shell error message is redirected to PIPE
p = subprocess.Popen("echa 2", shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)