Criar um processo executável sem usar escudo em Python 2.5 e abaixo
-
05-07-2019 - |
Pergunta
Apenas o que o título diz:
- O módulo
subprocess
não pode ser usado como isso deve funcionar em 2.4 e 2.5 - processo Shell não deve ser gerado para passar argumentos.
Para explicar (2), considere o seguinte código:
>>> x=os.system('foo arg')
sh: foo: not found
>>> x=os.popen('foo arg')
sh: foo: not found
>>>
Como você pode ver os.system
e os.popen
executa o comando dado ( "foo") através de um shell do sistema ( "sh"). Eu não quero que isso aconteça (caso contrário, feio 'não encontrado' mensagens são impressos no stderr programa sem meu controle).
Finalmente, eu deveria ser capaz de passar argumentos para este programa ( 'arg' no exemplo acima).
Como um iria sobre como fazer isso em Python 2.5 e 2.4?
Solução
Você provavelmente precisará usar o módulo de subprocesso que está disponível no Python 2.4
Popen("/home/user/foo" + " arg")
>>> Popen("foo arg", shell=False)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.6/subprocess.py", line 595, in __init__
errread, errwrite)
File "/usr/lib/python2.6/subprocess.py", line 1092, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
Você precisará incluir o caminho completo desde que você não está usando o shell.
http://docs.python.org/library/subprocess .html # substituindo-os-sistema
Como alternativa, você pode também passar subprocess.PIPE ao stderr e stdout para suprimir as mensagens. Veja o link acima para mais detalhes.
Outras dicas
Como descrito anteriormente, você pode (e deve) usar o subprocess módulo.
Por padrão, o parâmetro shell
é False
. Isso é bom, e bastante seguro. Além disso, você não precisa para passar o caminho completo, basta passar o nome do executável e os argumentos como uma sequência (tupla ou lista).
import subprocess
# This works fine
p = subprocess.Popen(["echo","2"])
# These will raise OSError exception:
p = subprocess.Popen("echo 2")
p = subprocess.Popen(["echo 2"])
p = subprocess.Popen(["echa", "2"])
Você também pode usar essas duas funções de conveniência já definidos no módulo subprocesso:
# Their arguments are the same as the Popen constructor
retcode = subprocess.call(["echo", "2"])
subprocess.check_call(["echo", "2"])
Lembre-se você pode redirecionar stdout
e / ou stderr
para PIPE
, e, portanto, não será impresso na tela (mas a saída ainda está disponível para leitura pelo seu programa de python). Por padrão, stdout
e stderr
são ambos None
, o que significa nenhum redirecionamento , o que significa que eles vão usar o mesmo stdout / stderr como seu programa de python.
Além disso, você pode usar shell=True
e redirecionar a stdout
.stderr
a um tubo e, portanto, nenhuma mensagem será impressa:
# This will work fine, but no output will be printed
p = subprocess.Popen("echo 2", shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# This will NOT raise an exception, and the shell error message is redirected to PIPE
p = subprocess.Popen("echa 2", shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)