2012-07-19 22 views
13

ejecuto un comando en Python usando la función subprocess.Popen() como el siguiente:pitón: elevar child_exception, OSError: [Errno 2] No existe el fichero o directorio

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) 

En el shell funciona muy bien y sin error, pero en Python me sale:

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 

busqué el error, pero ninguno de ellos resolvió mi problema. ¿Alguien sabe cuál es la causa de este problema? Gracias.

Respuesta

18

Si va a pasar el comando como una cadena al Popen y si los comandos tienen derivaciones a otros comandos allí, debe usar la palabra clave shell=True.

No estoy particularmente familiarizado con el comando omp, pero esto huele mucho a un uso inútil del gato. Me gustaría pensar que una mejor manera de lograr esto sería:

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) 

O, si no es un uso inútil de gato (Usted realmente necesita para canalizar el archivo en medio de la entrada estándar), se puede hacer eso con subproceso también:

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) 
+0

¡Tienes razón! Una pregunta más, si shell = False, ¿deberían los args ser una lista, verdad? ¿Cuál es la diferencia entre estas dos formas? –

+1

Para responder a su pregunta, ese comando que almaceno en el archivo tiene 9000 líneas de longitud, mi sistema operativo me dará "arg list too long error" :) –

+2

@da_zhuang - sí, con 'shell = False', los argumentos son típicamente una lista. Usé la función 'shlex.split' que toma una cadena y la divide en una lista de la misma forma que un shell típico. con 'shell = True', pasas una cadena y esa cadena es evaluada por un shell. con 'shell = False' pasas una cadena o una lista. Si es una cadena, se evalúa como si fuera el único comando. ('" ls -l "' fallaría ya que no existe el comando 'ls -l', solo' ls'). Si se trata de una lista, cada elemento se toma como argumento. '[" ls "," -l "]' – mgilson

0

este error se ha producido para mí también con guiones tox, resulta que un virtualenv se crea con tox que tiene una trayectoria asolute con longitud de 96 caracteres, pero cada vez que toma la papelera absoluta'/ pip 'ruta a cerca de 123 caracteres, hay un error de invocación, OSError2.

'ERROR: no invocación (Error 2), OSError: [Errno 2] No existe el fichero o directorio'

Python: Python 2.7.6 virtualenv: 15.1.0 tox: 2.9.1 PIP: 9.0.1 ubuntu 14.04 prueba se ejecutó con cobertura: Django (1.8-1.11) pruebas con py27, py35 cada

Resolución: he creado mi virtualenv (con trazado de abs < = (96-100) caracteres) primero donde se instala tox, cloné mi proyecto para ser utilizado con esta instalación tox y vi rtualenv, tox crea sus propios virtualenvs ahora y funciona bien.

Espero que ayude.

Cuestiones relacionadas