Executar comandos sequencialmente em Python?
-
21-08-2019 - |
Pergunta
Eu gostaria de executar vários comandos em uma linha:
i. (Apenas para ilustrar a minha necessidade):
cmd
(a casca)
então
cd dir
e
ls
e ler o resultado da ls
.
Qualquer idéia com módulo subprocess
?
Update:
cd dir
e ls
são apenas um exemplo. Eu preciso executar comandos complexos (seguindo uma ordem particular, sem qualquer pipelining). Na verdade, eu gostaria de um shell subprocess ea capacidade de lançar muitos comandos nele.
Solução
Há uma maneira fácil de executar uma seqüência de comandos.
Use o seguinte em subprocess.Popen
"command1; command2; command3"
Ou, se você está preso com o Windows, você tem várias opções.
-
Crie um arquivo temporário "bat", e proporcionar isso para
subprocess.Popen
-
Criar uma seqüência de comandos com "\ n" separadores em uma única cadeia longa.
Use "" "s, como esta.
"""
command1
command2
command3
"""
Ou, se você tem que fazer as coisas aos poucos, você tem que fazer algo como isto.
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()
Isso permitirá que você construir uma seqüência de comandos.
Outras dicas
Para fazer isso, você teria que:
- fornecer o argumento
shell=True
na chamadasubprocess.Popen
, e - separar os comandos com:
-
;
se estiver rodando sob um shell * nix (bash, cinzas, sh, ksh, csh, tcsh, zsh etc) -
&
se estiver rodando sob ocmd.exe
do Windows
-
Finding 'bar' em cada arquivo cujo nome contém '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()
'fora' e 'err' são seqüência de objetos que contém a saída padrão e, finalmente, a saída de erro.
Sim, a função subprocess.Popen()
suporta um argumento cwd
palavra-chave, com o qual você pode definir o diretório corre o processo no.
Eu acho que o primeiro passo, o shell, não é necessário, se tudo que você quer é correr ls
, não há necessidade de executá-lo através de um shell.
É claro, você também pode apenas passar o diretório desejado como um argumento para ls
.
Update: pode valer a pena notar que para os reservatórios típicos, cd
é implementado no próprio reservatório, que não é um comando externo no disco. Isso é porque ele precisa mudar diretório atual do processo, o que deve ser feito de dentro do processo. Desde comandos executados como criança processado, gerado pelo shell, eles não podem fazer isso.
abaixo script python tem 3 funções que você quer apenas executar:
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])