Executando um programa externo (executável) em Python?

92

Acabei de começar a trabalhar em Python e tenho tentado executar um executável externo de Python.

Tenho um executável para um programa escrito em Fortran. Digamos que o nome do executável seja flow.exe. E meu executável está localizado em C:\Documents and Settings\flow_model. Tentei os comandos os.system e popen, mas até agora não consegui fazer funcionar. O código a seguir parece que abre a janela de comando, mas não executa o modelo.

# Import system modules
import sys, string, os, arcgisscripting
os.system("C:/Documents and Settings/flow_model/flow.exe")

Como posso consertar isso?

Mesut
fonte
2
Possível duplicata de Chamando um comando externo em Python
mkobit

Respostas:

45

Esses espaços em branco podem ser realmente um incômodo :-(. Tente os.chdir('C:/Documents\ and\ Settings/')seguir por caminhos relativos para os.system, subprocessmétodos ou qualquer outra coisa ...

Se as tentativas de melhor esforço para contornar o obstáculo dos espaços em branco continuarem falhando, minha próxima sugestão é evitar espaços em branco em seus caminhos cruciais. Você não poderia fazer um diretório sem espaços em branco, copiar o .exearquivo crucial lá e tentar isso ? Esses espaços destruidores são absolutamente essenciais para o seu bem-estar ...?

Alex Martelli
fonte
1
Alex, obrigado. Isso também funcionou. Eu tenho mais uma pergunta, se você não se importa. E se meu executável estiver perguntando o nome do meu arquivo de entrada? Tentei fazer isso usando stdin, mas não consegui até agora?
Mesut
2
@mesut, o que esse executável está usando para "pedir" o nome do arquivo? Se for sua própria entrada padrão, por exemplo, você pode usar subprocess.Popenpara canalizar os valores desejados para lá. Se for mais profundo (usando a entrada "console"), tente wexpect, sage.math.washington.edu/home/goreckc/sage/wexpect .
Alex Martelli
o arquivo de entrada é um arquivo .txt básico na mesma pasta. O código agora abre o exe da janela cmd. E o executável pede o nome do arquivo de entrada. Existe uma maneira de definir este nome (talvez como um caminho) dentro do código? Tentei subprocess.popen e tentei olhar nas variáveis. Eu pensei que eu poderia usar stdin, mas realmente não funcionou. Eu realmente apreciaria se você pudesse me dar uma amostra com subprocess.popen com o executável localizado em C: \ flow_model, o nome do executável como flow.exe e o nome do arquivo de entrada localizado na mesma pasta que sac_bsl.txt
Mesut
A parte "pedir o nome do arquivo de entrada" é a problemática. Não saber nada sobre como esse exe é codificado, como já mencionei, wexpecté a solução mais provável, pois permite simular exatamente o que aquele arquivo exe veria quando chamado em uma janela cmd.
Alex Martelli
42

Se estiver usando Python 2.7 ou superior (especialmente antes do Python 3.5), você pode usar o seguinte:

import subprocess
  • subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False) Executa o comando descrito por args. Espera a conclusão do comando e retorna o atributo returncode.
  • subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False) Executa o comando com argumentos. Aguarda a conclusão do comando. Se o código de retorno for zero, retorna, caso contrário, gera CalledProcessError. O objeto CalledProcessError terá o código de retorno no atributo returncode

Exemplo: subprocess.check_call([r"C:\pathToYourProgram\yourProgram.exe", "your", "arguments", "comma", "separated"])

Em strings Python regulares, a combinação de caracteres \ U sinaliza um escape de ponto de código Unicode estendido.

Aqui está o link para a documentação: http://docs.python.org/3.2/library/subprocess.html

Para Python 3.5+, agora você pode usar run () em muitos casos: https://docs.python.org/3.5/library/subprocess.html#subprocess.run

Ida N
fonte
7
Python 3.6.3 recomenda run ()
Ricardo Zorio
33

A maneira mais simples é:

import os
os.startfile("C:\Documents and Settings\flow_model\flow.exe")

Funciona; Eu tentei.

Alguém
fonte
funcionando corretamente, mas há uma maneira de adicionar parâmetros como -start e assim por diante?
Bassem Shahin
1
Não funciona: module 'os' has no attribute 'startfile'. (Usando python3.6)
not2qubit
Aparentemente não funciona em nada relacionado ao Windows, ao contrário da impressão que a documentação dá.
not2qubit
24

Eu tentaria inserir um 'r' na frente do seu caminho se eu fosse você, para indicar que é uma string bruta - e então você não terá que usar barras. Por exemplo:

os.system(r"C:\Documents and Settings\flow_model\flow.exe")
Jon Mills
fonte
19

Seu uso está correto. Aposto que seu programa externo, flow.exe, precisa ser executado em seu diretório, pois acessa alguns arquivos externos nele armazenados.

Então você pode tentar:

import sys, string, os, arcgisscripting
os.chdir('c:\\documents and settings\\flow_model')
os.system('"C:\\Documents and Settings\\flow_model\\flow.exe"')

(Cuidado com as aspas duplas dentro das aspas simples ...)

Adrien Plisson
fonte
Funciona perfeitamente. Como armazenar os resultados diretamente em um dataframe?
Sade
11

Use subprocesso , é um módulo menor, por isso é executado .exemais rápido.

import subprocess
subprocess.Popen([r"U:\Year 8\kerbal space program\KSP.exe"])
Frodo Baggins
fonte
1
Você quer dizer que começa o .exemais rápido?
Peter Mortensen
7

Usando os.system :

import os
os.system(r'"C:/Documents and Settings/flow_model/flow.exe"')
Romy
fonte
4

Experimentar

import subprocess
subprocess.call(["C:/Documents and Settings/flow_model/flow.exe"])
int3
fonte
tentei e a mesma coisa aconteceu. parece que ele abre a janela cmd, mas não executa o executável. Tentei o executável separadamente e funciona bem. Também movi a pasta como C: / flow_model. Não fez diferença. ??
Mesut
2

Se fosse eu, colocaria o arquivo EXE no diretório raiz (C :) e veria se funciona assim. Em caso afirmativo, são provavelmente os (já mencionados) espaços no nome do diretório. Caso contrário, podem ser algumas variáveis ​​de ambiente.

Além disso, tente verificar seu stderr (usando uma resposta anterior de int3):

import subprocess
process = subprocess.Popen(["C:/Documents and Settings/flow_model/flow.exe"], \
                           stderr = subprocess.PIPE)
if process.stderr:
    print process.stderr.readlines()

O código pode não estar totalmente correto, já que geralmente não uso Popen ou Windows, mas devo dar a ideia. Pode ser que a mensagem de erro esteja no fluxo de erros.

extrânon
fonte
2
import os
path = "C:/Documents and Settings/flow_model/"
os.chdir(path)
os.system("flow.exe")
John
fonte
1
Adicione uma explicação de por que seu código resolve esta questão.
rje
Esta postagem está basicamente tratando o arquivo * .exe sendo executado como você faria com o arquivo * .bat do Windows.
SamAct
2

em python 2.6, use a string entre aspas "e apóstrofos". Também altere um / para duplo //. Seu exemplo de trabalho será semelhante a este:

import os
os.system("'C://Documents and Settings//flow_model//flow.exe'") 

Além disso, você pode usar quaisquer parâmetros se o seu programa os ingerir.

os.system('C://"Program Files (x86)"//Maxima-gcl-5.37.3//gnuplot//bin//gnuplot -e "plot [-10:10] sin(x),atan(x),cos(atan(x)); pause mouse"')

finalmente, você pode usar a variável de string, por exemplo, plotagem usando gnuplot diretamente do python:

this_program='C://"Program Files (x86)"//Maxima-gcl-5.37.3//gnuplot//bin//gnuplot'

this_par='-e "set polar; plot [-2*pi:2*pi] [-3:3] [-3:3] t*sin(t); pause -1"'
os.system(this_program+" "+this_par)
Bomba Ps
fonte
1

Isso está tentando executar C:\Documentscom argumentos de "and", "Settings/flow_model/flow.exe"?

Além disso, você pode considerar subprocess.call().

Thanatos
fonte
0

Esse é o uso correto, mas talvez os espaços no nome do caminho estejam bagunçando as coisas por algum motivo.

Você também pode executar o programa em cmd.exe para ver qualquer saída de flow.exe que possa indicar um erro.

Dan Olson
fonte
0

Existem muitas soluções diferentes, e os resultados dependerão fortemente de:

  • o sistema operacional que você está usando: Windows, Cygwin, Linux, MacOS
  • a versão python que você está usando: Python2 ou Python3x

Como eu descobri algumas coisas que dizem funcionar apenas no Windows, provavelmente não funciona, provavelmente porque eu uso o Cygwin, que está superando o sistema operacional para lidar com os caminhos do Windows. Outras coisas só funcionam em sistemas operacionais baseados em * nix puro ou em Python2 ou 3.

Aqui estão minhas descobertas:

  • De um modo geral, os.system()é o método mais tolerante.
  • os.startfile()é o menos indulgente. (Somente Windows && se você tiver sorte)
  • subprocess.Popen([...]) não recomendado
  • subprocess.run(winView, shell=True) a forma recomendada!
  • Lembrar que usar subprocesspara qualquer coisa pode representar um risco à segurança .

Tente esse:

import os, subprocess
...
winView = '/cygdrive/c/Windows/explorer.exe %s' % somefile
...
# chose one of these:
os.system(winView)
subprocess.Popen(['/cygdrive/c/Windows/explorer.exe', 'somefile.png'])
subprocess.run(winView, shell=True)

P: Por que você deseja usar explorer no Windows?

R: Porque se você quiser apenas ver os resultados de algum novo arquivo, o explorer irá abrir automaticamente o arquivo com qualquer programa padrão do Windows que você definiu para aquele tipo de arquivo. Portanto, não há necessidade de especificar novamente o programa padrão a ser usado.

not2qubit
fonte
0

para a questão acima esta solução funciona.

apenas altere o caminho para onde seu arquivo executável está localizado.

import sys, string, os

os.chdir('C:\\Downloads\\xpdf-tools-win-4.00\\xpdf-tools-win-4.00\\bin64')

os.system("C:\\Downloads\\xpdf-tools-win-4.00\\xpdf-tools-win-4.00\bin64\\flowwork.exe")


'''import sys, string, os

os.chdir('C:\\Downloads\\xpdf-tools-win-4.00\\xpdf-tools-win-4.00\\bin64')

os.system(r"C:\\Downloads\\xpdf-tools-win-4.00\\xpdf-tools-win-4.00\bin64\\pdftopng.exe test1.pdf rootimage")'''

Aqui test1.pdf rootimage é para o meu código.

spurthi
fonte
Você se esqueceu de um fechamento "em os.system?
Suraj Rao de