为什么这个命令适用于os.system()而不是subprocess.Popen()?

时间:2012-06-21 16:21:15

标签: python subprocess

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

最初,我尝试使用子进程模块,但是我收到了一个错误:      #!/ 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

然后我注释掉了子流程并使用了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

3 个答案:

答案 0 :(得分:3)

如果您阅读manual,您可以看到您对Popen的调用是错误的:您应该传递的不是一个命令,而是一组参数:

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

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

答案 1 :(得分:2)

你想在你的Popen电话上使用shell = True。

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

答案 2 :(得分:0)

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