O Windows não consegue encontrar o arquivo em subprocess.call ()


103

Eu estou recebendo o seguinte erro:

WindowsError: [Error 2] The system cannot find the file specified

Meu código é:

subprocess.call(["<<executable file found in PATH>>"])

Windows 7 de 64 bits. Python 3.x mais recente, estável.

Alguma ideia?

Obrigado,


e o que é esse arquivo executável?
— SilentGhost

A parte executável "android" do Android SDK
— Sri

2
E se é acessível em PATH
— Sri

você pode executá-lo a partir da linha de comando?
— SilentGhost

Um pequeno histórico do que estou tentando realizar. Isso é para Opendevice - um projeto de código aberto para converter aplicativos HTML5 em aplicativos específicos para dispositivos. Estou tentando substituir os.system () em bitbucket.org/srirangan/opendevice/src/tip/tools/net/srirangan/… para subprocess.call ()
— Sri

Respostas:


178

Quando o comando é um shell embutido, adicione 'shell = True' à chamada.

Por exemplo, para dirvocê digitaria:

import subprocess
subprocess.call('dir', shell=True)

Para citar a documentação:

A única vez que você precisa especificar shell = True no Windows é quando o comando que você deseja executar está embutido no shell (por exemplo, dir ou copiar). Você não precisa de shell = True para executar um arquivo em lote ou executável baseado em console.


14
Isso ocorre porque nenhum executável é chamado dir.exeenquanto houver um /bin/lsin * nix. diré implementado por CMD.EXE muito como cdé implementado pela festa .
— Apalala

1
Isso é fortemente desencorajado. docs.python.org/2/library/…
— nu everest

11
@nueverest Somente quando a string de comando é construída a partir de uma entrada externa
— Jirka

A alternativa (mais segura para entrada externa) é obter o PATHdo os.environe pesquisá-lo manualmente.
— asmeurer de

Consulte stackoverflow.com/a/32799942/3912576 para obter uma solução muito mais apropriada para esse problema.
— SimonBiggs

33

No Windows, acredito que o subprocessmódulo não fica no a PATHmenos que você passeshell=True porque ele usa CreateProcess()nos bastidores. No entanto, shell=Truepode ser um risco de segurança se você passar argumentos que podem vir de fora do seu programa. Para tornar, subprocessno entanto, capaz de encontrar o executável correto, você pode usar shutil.which. Suponha que o executável em seu PATHseja denominado frob:

subprocess.call([shutil.which('frob'), arg1, arg2])

(Isso funciona no Python 3.3 e superior.)


4
Qualquer opção de python 2?
— Naramsim

1
Você está certo e está sugerindo a maneira certa de consertar. Esta resposta deve ser aceita. A resposta aceita atualmente não explica a causa e sugere uma solução que pode ser perigosa em alguns casos.
— David Ferenczy Rogožan

18

No Windows, você deve chamar por meio do cmd.exe. Como Apalala mencionou, os comandos do Windows são implementados em cmd.exe não como executáveis ​​separados.

por exemplo

subprocess.call(['cmd', '/c', 'dir'])

/ c diz ao cmd para executar o comando a seguir

Isso é mais seguro do que usar shell = True, que permite injeções de shell.


Como manteria a tela aberta?
— Moondra de

2
@Moondra, Se bem entendi, tente em /kvez de /c. Digite cmd /?na linha de comando para obter detalhes.
— User5910

@ User5910 Obrigado. Vou tentar quando tiver uma chance.
— Moondra de

3

Se você estiver usando o PowerShell, então estará subprocess.call(['powershell','-command','dir']). O Powershell suporta uma grande parte dos comandos POSIX


2

Depois de muito questionar, descobri que executar um arquivo localizado em C: \ Windows \ System32 \ enquanto uma versão de 32 bits do python em uma máquina de 64 bits é um problema potencial, porque o Windows está tentando superar o processo, e redirecionar chamadas para C: \ Windows \ System32 para C: \ Windows \ SysWOW64.

Encontrei um exemplo de como corrigir isso aqui: http://code.activestate.com/recipes/578035-disable-file-system-redirector/


1

Para citar a documentação:

"Antes do Python 3.5, essas três funções compreendiam a API de alto nível para subprocessar. Agora você pode usar run () em muitos casos, mas muitos códigos existentes chamam essas funções."

SO: em vez de subprocess.call, use subprocess.run para Python 3.5 e superior


Verdadeiro e útil.
— Erick G. Hagstrom

0

Eu encontrei o mesmo problema enquanto chamava um PHP. A razão é que o PHP não está no PATH, então o comando PHP não foi encontrado. Mas o PowerShell descobriu que ele existe no local atual e sugere a substituição de 'PHP' por '. \ PHP' se eu confiar neste comando. Então funciona bem.

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.