Создайте исполняемый процесс без использования оболочки на Python 2.5 и ниже - PullRequest
1 голос
/ 11 сентября 2009

Как раз то, что написано в названии:

  1. Модуль subprocess нельзя использовать, так как он должен работать на 2,4 и 2,5
  2. Процесс Shell не должен вызываться для передачи аргументов.

Чтобы объяснить (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 без моего контроля).

Наконец, я должен быть в состоянии передать аргументы этой программе ('arg' в приведенном выше примере).

Как можно поступить так в Python 2.5 и 2.4?

Ответы [ 2 ]

3 голосов
/ 11 сентября 2009

Вам, вероятно, нужно использовать модуль подпроцесса, который доступен в Python 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.PIPE в stderr и stdout для подавления сообщений. См. Ссылку выше для более подробной информации.

0 голосов
/ 11 сентября 2009

Как описано выше, вы можете (и должны) использовать модуль подпроцесс .

По умолчанию параметр shell равен False. Это хорошо и вполне безопасно. Кроме того, вам не нужно передавать полный путь, просто передайте имя исполняемого файла и аргументы в виде последовательности (кортеж или список).

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"])

Вы также можете использовать эти две вспомогательные функции, уже определенные в модуле подпроцесса:

# Their arguments are the same as the Popen constructor
retcode = subprocess.call(["echo", "2"])
subprocess.check_call(["echo", "2"])

Помните, что вы можете перенаправить stdout и / или stderr на PIPE, и, таким образом, он не будет выводиться на экран (но вывод все еще доступен для чтения вашей программой на python). По умолчанию stdout и stderr оба None, что означает без перенаправления , что означает, что они будут использовать тот же stdout / stderr, что и ваша программа на python.

Кроме того, вы можете использовать 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)
...