【问题标题】:Why does this command work with os.system() but not subprocess.Popen()?为什么这个命令适用于 os.system() 而不是 subprocess.Popen()?
【发布时间】:2012-06-23 22:38:01
【问题描述】:

我想从 q 中删除一些作业。删除作业的命令是qdel JOBid

最初,我尝试使用 subprocess 模块,但出现错误: #!/usr/bin/env python

 import sys, os, subprocess as sp

 lo = sys.argv[1]
 hi = sys.argv[2]

 lo = int(lo)
 hi = int(hi)


for i in range(lo,hi):
    print "i is %d"%i
    p=sp.Popen(['qdel %d'%i],stdout=sp.PIPE)
    #os.system('qdel %d'%i)

所以这不起作用。我得到的错误是

Traceback (most recent call last):
File "del.py", line 14, in <module>
p=sp.Popen(['qdel %d'%i],stdout=sp.PIPE)
File "/usr/lib64/python2.6/subprocess.py", line 639, in __init__
errread, errwrite)
File "/usr/lib64/python2.6/subprocess.py", line 1228, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory

然后我注释掉 subprocess 行并使用 os 并立即工作。我想我还没有完全理解子流程模块

#!/usr/bin/env python

import sys, os, subprocess as sp

lo = sys.argv[1]
hi = sys.argv[2]

lo = int(lo)
hi = int(hi)


    for i in range(lo,hi):
         print "i is %d"%i
         #p=sp.Popen(['qdel %d'%i],stdout=sp.PIPE)
         os.system('qdel %d'%i)

上面的代码完美无缺。我只是想知道子流程模块的原因和优势是什么。另外,我使用的是 unix shell

【问题讨论】:

    标签: python subprocess


    【解决方案1】:

    您想在 Popen 调用中使用 shell=True。

    p=sp.Popen(['qdel %d'%i], shell=True, stdout=sp.PIPE)
    

    【讨论】:

    • 那么如果shell是假的,那么它在哪里尝试执行命令?
    • @Chris2021 使用shell=False,它只是使用os.execvp() 运行进程。使用 shell=True,它会调用您的默认 shell 并使其执行提供的字符串。
    【解决方案2】:

    如果您阅读manual,您会发现您对Popen 的调用是错误的:您应该传递的不是单个命令,而是一组参数:

    p=sp.Popen(['qdel', '%d'%i],stdout=sp.PIPE)
    

    或者,正如sc0tt's answer 指出的那样,您可以使用shell=True,但这在更复杂的情况下有一些缺点:您必须手动转义命令中的所有变量数据,以防它包含,例如,带有空格或任何更可能有害的文件名(如;

    【讨论】:

    • 你不会仍然需要使用shell=True 吗?如果您不指定shell=True,Popen 是否不希望参数列表中的第一项是要执行的程序的路径?
    • @sc0tt 来自man-page for execvp:如果指定的文件名不包含斜杠 (/) 字符,则函数 execlp()execvp() 将复制 shell 在搜索可执行文件时的操作.
    【解决方案3】:

    我也遇到了同样的问题。使用 shell=True 作为参数之一解决了我的问题。

    【讨论】:

      猜你喜欢
      • 2014-11-06
      • 1970-01-01
      • 1970-01-01
      • 2018-04-24
      • 1970-01-01
      • 2012-05-11
      • 1970-01-01
      • 2020-09-07
      • 2018-06-25
      相关资源
      最近更新 更多