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?


2

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 ...?


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


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.


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")

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 ...)


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"])

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"')

4

Experimentar

import subprocess
subprocess.call(["C:/Documents and Settings/flow_model/flow.exe"])

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.


2
import os
path = "C:/Documents and Settings/flow_model/"
os.chdir(path)
os.system("flow.exe")

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)

1

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

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


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.


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.


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.


Você se esqueceu de um fechamento "em os.system?
Suraj Rao de
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.