2008-12-11 102 views
16

me gustaría ejecutar varios comandos en una fila:Ejecutar comandos secuencialmente en Python

es decir (sólo para ilustrar mi necesidad):

cmd (la cáscara)

entonces

cd dir

y

ls

y leer el resultado de la LS.

¿Alguna idea con el módulo de subproceso?

ACTUALIZACIÓN:

cd dir y ls son sólo un ejemplo. Necesito ejecutar comandos complejos (siguiendo un orden particular, sin ningún tipo de canalización). De hecho, me gustaría un shell de subproceso y la capacidad de ejecutar muchos comandos en él.

+3

tal vez debería escribir un script de shell en lugar de un script en Python – hop

Respuesta

19

Hay una manera fácil de ejecutar una secuencia de comandos.

haga lo siguiente en subprocess.Popen

"command1; command2; command3" 

O, si le pegan con ventanas, tiene varias opciones.

  • Crear un archivo temporal "BAT", y proporcionar esta a subprocess.Popen

  • Crear una secuencia de comandos con "\ n" separadores en una única cadena larga.

Uso "" "s, como este.

""" 
command1 
command2 
command3 
""" 

O, si tiene que hacer las cosas poco a poco, lo que tiene que hacer algo como esto.

class Command(object): 
    def __init__(self, text): 
     self.text = text 
    def execute(self): 
     self.proc= subprocess.Popen(... self.text ...) 
     self.proc.wait() 

class CommandSequence(Command): 
    def __init__(self, *steps): 
     self.steps = steps 
    def execute(self): 
     for s in self.steps: 
      s.execute() 

que permitirá usted para construir una secuencia de comandos.

+2

'subprocess.Popen ("LS")' obras. Sin embargo, 'subprocess.Popen (" ls; ls ")' falla para mí. Error: 'Rastreo (llamada más reciente pasado): Archivo "", línea 1, en Archivo "/usr/lib64/python2.6/subprocess.py", línea 639, en __init__ errread, errwrite) Archivo "/usr/lib64/python2.6/subprocess.py", línea 1228, en _execute_child raise child_exception OSError: [Errno 2] No existe tal archivo o directorio' –

+0

Esto falló porque Popen espera una lista como su primer argumento y solo "ls" es equivalente a ["ls"]. Intenta encontrar un ejecutable con el nombre "ls; ls" que obviamente no está allí. –

+0

¿No se ejecutaría desde la clase CommandSequence sobre la ejecución() de la clase Command? Si es así, ¿cómo funciona s.execute? – user97662

2

Sí, la función subprocess.Popen() apoya un argumento cwd de palabras clave, con la que se puede establecer el directorio en el que se ejecuta el proceso de.

supongo que el primer paso, del casco, no se necesita, si lo que quieres es para ejecutar ls, no hay necesidad de ejecutarlo a través de un shell.

Por supuesto, también podría simplemente pasar el directorio deseado como argumento al ls.

Actualización: podría valer la pena señalar que para las conchas típicas, cd se implementa en el propio shell, no es un comando externo en el disco. Esto se debe a que necesita cambiar el directorio actual del proceso, lo cual debe hacerse desde dentro del proceso. Como los comandos se ejecutan como secundarios procesados, generados por el shell, no pueden hacer esto.

1

Finding 'bar' en todos los archivos cuyo nombre contiene 'foo':

from subprocess import Popen, PIPE 
find_process = Popen(['find', '-iname', '*foo*'], stdout=PIPE) 
grep_process = Popen(['xargs', 'grep', 'bar'], stdin=find_process.stdout, stdout=PIPE) 
out, err = grep_process.communicate() 

'out' y 'ERR' son objetos de cadena que contienen la salida estándar y, finalmente, la salida de error.

21

Para hacer eso, usted tendría que:

  • suministrar el argumento shell=True en la llamada de subprocess.Popen, y
  • separar los comandos con:
    • ; si se ejecuta bajo un shell * nix (bash, ceniza, sh, ksh, csh, tcsh, zsh etc)
    • & si se ejecuta bajo la cmd.exe de Ventanas
+1

O para Windows, puede usar && para que un comando que cometa errores impida la ejecución de los comandos después de él. – twasbrillig

+0

@twasbrillig Interesante; No sabía que cmd.exe compartió este separador de comandos con shells de Unix. Debería actualizar mi conocimiento. ¡Gracias! – tzot

+0

Gracias, esto es invaluable y fue realmente difícil de encontrar. – CodeMonkey

-1

continuación script en Python 3 tienen la función de lo que se fue apenas excute:

import sys 
import subprocess 

def cd(self,line): 
    proc1 = subprocess.Popen(['cd'],stdin=subprocess.PIPE) 
    proc1.communicate() 

def ls(self,line): 
    proc2 = subprocess.Popen(['ls','-l'],stdin=subprocess.PIPE) 
    proc2.communicate() 

def dir(silf,line): 
    proc3 = subprocess.Popen(['cd',args],stdin=subprocess.PIPE) 
    proc3.communicate(sys.argv[1]) 
+0

es incorrecto. 'cd' no tiene ningún efecto sobre el elemento primario y es probable que OP quiera incorporarse al comando de shell (' Popen() 'no ejecuta el shell a menos que lo solicite explícitamente, aunque en este caso no será de ayuda). – jfs

Cuestiones relacionadas