subprocess.call

Dna*_*iel 1 python subprocess

我是subprocess.call函数的新手,我尝试过同一个调用的不同组合,但它不起作用.

我正在尝试执行以下命令:

cmd = 'sort -k1,1 -k4,4n -k5,5n '+outpath+fnametempout+' > '+outpath+fnameout
print cmd
Run Code Online (Sandbox Code Playgroud)

如果我尝试通话,我会收到错误消息:

cmd = cmd.split(" ")
print cmd
subprocess.call(cmd)
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

sort: stat failed: >: No such file or directory
Run Code Online (Sandbox Code Playgroud)

mgi*_*son 9

这样做,您需要shell=True允许shell重定向工作.

subprocess.call('sort -k1,1 -k4,4n -k5,5n '+outpath+fnametempout,shell=True)
Run Code Online (Sandbox Code Playgroud)

更好的方法是:

with open(outpath+fnameout,'w') as fout: #context manager is OK since `call` blocks :)
    subprocess.call(cmd,stdout=fout)
Run Code Online (Sandbox Code Playgroud)

这样可以避免产生一个shell,并且可以防止shell注入攻击.这里cmd是一个原始列表,例如

cmd = 'sort -k1,1 -k4,4n -k5,5n '+outpath+fnametempout
cmd = cmd.split()
Run Code Online (Sandbox Code Playgroud)

还应该说python有非常好的排序工具,所以我怀疑实际上有必要sort通过子进程传递作业.


最后,不是使用str.split从字符串中拆分参数,而是使用它可能更好,shlex.split因为它将正确处理引用的字符串.

>>> import shlex
>>> cmd = "foo -b -c 'arg in quotes'"
>>> print cmd.split()
['foo', '-b', '-c', "'arg", 'in', "quotes'"]
>>> print shlex.split(cmd)
['foo', '-b', '-c', 'arg in quotes']
Run Code Online (Sandbox Code Playgroud)

  • +1.但是`shlex`的事情有点错误.首先构建`list`而不是`str`始终是最好的事情.如果您不可避免地有一个`str`,并且您正在使用`shell = True`(或者您在Windows上),那么只需传递`str`即可.如果你必须拆分字符串,那么肯定使用`shlex.split`而不是`str.split`.但这应该是你最后的选择,而不是你的第一次.在这种情况下,没有理由进行任何拆分. (2认同)