【问题标题】:Create an executable process without using shell on Python 2.5 and below在 Python 2.5 及以下版本不使用 shell 创建可执行进程
【发布时间】:2010-11-27 08:06:07
【问题描述】:

正如标题所说:

  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.systemos.popen 通过系统 shell ("sh") 运行给定的命令 ("foo")。我不希望这种情况发生(否则,丑陋的“未找到”消息会在我无法控制的情况下打印到程序 stderr)。

最后,我应该能够将参数传递给这个程序(上例中的“arg”)。

如何在 Python 2.5 和 2.4 中执行此操作?

【问题讨论】:

    标签: python process fork subprocess popen


    【解决方案1】:

    您可能需要使用 Python 2.4 中提供的 subprocess 模块

    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
    

    您需要包含完整路径,因为您没有使用 shell。

    http://docs.python.org/library/subprocess.html#replacing-os-system

    您也可以将 subprocess.PIPE 传递给 stderr 和 stdout 以抑制消息。有关详细信息,请参阅上面的链接。

    【讨论】:

    • Err,子进程从 2.4 开始可用?我自欺欺人地认为它可以从 2.6 开始使用。
    【解决方案2】:

    如前所述,您可以(并且应该)使用subprocess 模块。

    默认情况下,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 程序读取)。默认情况下,stdoutstderr 都是None,这意味着没有重定向,这意味着它们将使用与您的python 程序相同的stdout/stderr。

    此外,您可以使用 shell=True 并将 stdout.stderr 重定向到 PIPE,因此不会打印任何消息:

    # 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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-07
      • 1970-01-01
      • 2018-03-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多