python:raise child_exception,OSError:[Errno 2]没有这样的文件或目录

Sha*_*ang 18 python popen

我使用subprocess.popen()函数在python中执行命令,如下所示:

omp_cmd = 'cat %s | omp -h %s -u %s -w %s -p %s -X -' %(temp_xml, self.host_IP, self.username, self.password, self.port)
xmlResult = Popen(omp_cmd, stdout=PIPE, stderr=STDOUT)
Run Code Online (Sandbox Code Playgroud)

在shell中它运行正常没有错误,但在python我得到:

  File "/home/project/vrm/apps/audit/models.py", line 148, in sendOMP
    xmlResult = Popen(omp_cmd, stdout=PIPE, stderr=STDOUT)
  File "/usr/local/lib/python2.7/subprocess.py", line 679, in __init__
    errread, errwrite)
  File "/usr/local/lib/python2.7/subprocess.py", line 1228, in _execute_child
    raise child_exception
  OSError: [Errno 2] No such file or directory
Run Code Online (Sandbox Code Playgroud)

我搜索了错误,但没有一个解决了我的问题.有谁知道这个问题的原因是什么?谢谢.

mgi*_*son 23

如果您要将命令作为字符串传递给命令,Popen并且命令中包含其他命令的管道,则需要使用shell=True关键字.

我对这个omp命令并不是特别熟悉,但这有点像无用的猫一样.我认为实现这一目标的更好方法是:

import shlex
omp_cmd = 'omp -h %s -u %s -w %s -p %s -X %s' %(self.host_IP, self.username, self.password, self.port, temp_xml)
xmlResult = Popen(shlex.split(omp_cmd), stdout=PIPE, stderr=STDOUT)
Run Code Online (Sandbox Code Playgroud)

或者,如果它不是无用的cat(你真的需要通过stdin管道文件),你也可以用子进程来做到这一点:

import shlex
omp_cmd = 'omp -h %s -u %s -w %s -p %s -X -' %(self.host_IP, self.username, self.password)
with open(temp_xml) as stdin:
    xmlResult = Popen(shlex.split(omp_cmd), stdin=stdin, stdout=PIPE, stderr=STDOUT)
Run Code Online (Sandbox Code Playgroud)

  • @da_zhuang - 是的,使用`shell = False`,args通常是一个列表.我使用了`shlex.split`函数,它接受一个字符串并将其拆分为一个列表,就像典型的shell一样.使用`shell = True`,您传递一个字符串,该字符串由shell评估.使用`shell = False`传递字符串或列表.如果是字符串,则将其评估为它是唯一的命令.(`"ls -l"`会失败,因为没有命令`ls -l`,只有`ls`).如果它是一个列表,则将每个元素作为参数.`["ls"," - l"]` (2认同)