No Python, existe uma maneira portátil e simples de testar se existe um programa executável?
Por simples, quero dizer algo como o which
comando que seria perfeito. Eu não quero procurar PATH manualmente ou algo que envolva tentar executá-lo com Popen
& al e ver se ele falha (é o que estou fazendo agora, mas imagine que seja launchmissiles
)
which
, o módulo de terceiros: code.activestate.com/pypm/whichRespostas:
A maneira mais fácil de pensar:
Editar : amostra de código atualizada para incluir lógica para lidar com o caso em que o argumento fornecido já é um caminho completo para o executável, ou seja, "what / bin / ls". Isso imita o comportamento do comando UNIX 'what'.
Editar : atualizado para usar os.path.isfile () em vez de os.path.exists () por comentários.
Edit :
path.strip('"')
parece que a coisa errada a fazer aqui. Nem o Windows nem o POSIX parecem incentivar os itens PATH citados.fonte
PATHEXT
env var porquecommand
é tão válida quantocommand.com
como éscript
vsscript.bat
Eu sei que esta é uma pergunta antiga, mas você pode usar
distutils.spawn.find_executable
. Isso foi documentado desde o python 2.4 e existe desde o python 1.6.Além disso, o Python 3.3 agora oferece
shutil.which()
.fonte
win32
, adistutils.spawn.find_executable
implementação procura apenas em.exe
vez de usar a lista de extensões para procurar a configuração%PATHEXT%
. Isso não é ótimo, mas pode funcionar para todos os casos de que alguém precisa.from distutils import spawn
php_path = spawn.find_executable("php")
distutils.spawn
não está disponível de maneira confiável: com minha instalação do sistema (/ usr / bin / python) do Python 2.7.6 no OS X 10.10, receboAttributeError: 'module' object has no attribute 'spawn'
:, embora estranhamente funcione na mesma máquina com a mesma versão do Python, mas em uma instalação virtualenv.import distutils.spawn
seguir afrom distutils import spawn
sintaxe, e não apenasimport distutils
. Caso contrário, pode não estar acessível e você obterá o que foi mencionado acima,AttributeError
mesmo que esteja lá.O Python 3.3 agora oferece shutil.which () .
fonte
Para python 3.2 e versões anteriores:
Esta é uma linha da resposta de Jay , também aqui como uma função lambda:
Ou, por último, recuado como uma função:
Para python 3.3 e posterior:
Como uma linha de resposta de Jan-Philip Gehrcke :
Como um def:
fonte
x
onde deveria estarcmd
os.path.join(path, cmd)
é um arquivo, não? Afinal, diretórios também pode ter o conjunto de bits executável ...mkdir -p -- "$HOME"/bin/dummy && PATH="$PATH":"$HOME"/bin && python -c 'import os; print any(os.access(os.path.join(path, "dummy"), os.X_OK) for path in os.environ["PATH"].split(os.pathsep))' && rmdir -- "$HOME"/bin/dummy
and os.path.isfile(...)
para os lugares apropriados é suficiente para correçãoLembre-se de especificar a extensão do arquivo no Windows. Caso contrário, você precisará escrever um tópico muito complicado
is_exe
para o Windows usandoPATHEXT
a variável de ambiente. Você pode apenas querer usar o FindPath .OTOH, por que você está se preocupando em procurar o executável? O sistema operacional fará isso por você como parte da
popen
chamada e gerará uma exceção se o executável não for encontrado. Tudo o que você precisa fazer é capturar a exceção correta para o SO fornecido. Observe que, no Windows,subprocess.Popen(exe, shell=True)
falhará silenciosamente seexe
não for encontrado.Incorporando
PATHEXT
na implementação acima dewhich
(na resposta de Jay):fonte
yield
nosext_candidates
, deu-me uma melhor compreensão de como que as obras de palavra-chavePara plataformas * nix (Linux e OS X)
Isso parece estar funcionando para mim:
Editado para funcionar no Linux, graças a Mestreion
O que estamos fazendo aqui é usar o comando embutido
type
e verificar o código de saída. Se não houver esse comando,type
sairá com 1 (ou um código de status diferente de zero).A parte sobre stdout e stderr é apenas para silenciar a saída do
type
comando, pois estamos interessados apenas no código de status de saída.Exemplo de uso:
fonte
type
é um shell embutido, não um arquivo executável, portantosubprocess.call()
falha aqui.OSError: [Errno 2] No such file or directory
. Talvez no Mactype
é um comando realshell=True
e substituir["type", cmd]
por"type " + cmd
Veja o módulo os.path para algumas funções úteis nos nomes de caminho. Para verificar se um arquivo existente é executável, use os.access (caminho, modo) , com o modo os.X_OK.
Edição: As
which()
implementações sugeridas estão faltando uma pista - usandoos.path.join()
para criar nomes de arquivos completos.fonte
Com base em que é mais fácil pedir perdão do que permissão, eu apenas tentaria usá-lo e capturar o erro (neste caso, OSError - verifiquei se o arquivo não existe e o arquivo não é executável e ambos fornecem o OSError).
Ajuda se o executável tem algo como um
--version
sinalizador que é um rápido não funcionamento.Essa não é uma solução geral, mas será a maneira mais fácil para muitos casos de uso - aqueles em que o código precisa procurar um único executável conhecido.
fonte
--version
um programa chamadolaunchmissiles
!launchmissies
existe, a menos que queira lançar mísseis? Melhor para executá-lo e agir de acordo com status de saída / exceçõesgit
que provavelmente não deseja executar às cegas.Sei que estou sendo um pouco necromante aqui, mas me deparei com essa pergunta e a solução aceita não funcionou para mim em todos os casos. Achei que seria útil enviar de qualquer maneira. Em particular, a detecção do modo "executável" e o requisito de fornecer a extensão do arquivo. Além disso, o python3.3
shutil.which
(usaPATHEXT
) e o python2.4 +distutils.spawn.find_executable
(apenas tenta adicionar'.exe'
) funcionam apenas em um subconjunto de casos.Então, escrevi uma versão "super" (com base na resposta aceita e na
PATHEXT
sugestão de Suraj). Esta versãowhich
faz a tarefa um pouco mais detalhadamente e tenta primeiro uma série de técnicas de "fase larga" em primeiro lugar e, eventualmente, tenta pesquisas mais refinadas noPATH
espaço:O uso fica assim:
A solução aceita não funcionou para mim neste caso, uma vez que havia arquivos como
meld.1
,meld.ico
,meld.doap
, etc, também no diretório, um dos quais foram devolvidos em vez (presumivelmente desde lexicographically primeiro) porque o teste executável na resposta aceita foi incompleta e dando falso-positivo.fonte
O melhor exemplo deve ser o módulo bulit-in python shutil.which () no Python 3. O link é https://hg.python.org/cpython/file/default/Lib/shutil.py
fonte
Encontrei algo no StackOverflow que resolveu o problema para mim. Isso funciona desde que o executável tenha uma opção (como --help ou --version) que produz algo e retorna um status de saída igual a zero. Consulte Suprimir saída em chamadas do Python para executáveis - o "resultado" no final do trecho de código nesta resposta será zero se o executável estiver no caminho, caso contrário, é mais provável que seja 1.
fonte
Isso parece bastante simples e funciona tanto em python 2 quanto em 3
fonte
command -v executable
outype executable
para ser universal. Há casos em que nos Macs não retorna os resultados esperados.Uma pergunta importante é " Por que você precisa testar se existe um executável?" Talvez você não? ;-)
Recentemente, eu precisava dessa funcionalidade para iniciar o visualizador de arquivos PNG. Eu queria interagir com alguns espectadores predefinidos e executar o primeiro que existe. Felizmente, me deparei
os.startfile
. É muito melhor! Simples, portátil e usa o visualizador padrão no sistema:Atualização: Eu estava errado em
os.startfile
ser portátil ... É apenas o Windows. No Mac, você deve executar oopen
comando. Exdg_open
no Unix. Há um problema de Python ao adicionar suporte para Mac e Unixos.startfile
.fonte
Você pode tentar a biblioteca externa chamada "sh" ( http://amoffat.github.io/sh/ ).
fonte
Adicionado suporte ao windows
fonte
você pode dizer se existe um arquivo com o módulo os. um executável em particular parece bastante portável, considerando que muitas coisas são executáveis no nix que não estão no Windows e vice-versa.
fonte
Parece que a escolha óbvia é "what", analisando os resultados via popen, mas você pode simular isso usando a classe os. No pseudopython, ficaria assim:
fonte
which
comando; existe uma versão do UnxUtils, mas você deve saber / especificar a extensão, caso contrário, o programa não será encontrado.Então, basicamente, você deseja encontrar um arquivo no sistema de arquivos montado (não necessariamente nos diretórios PATH) e verificar se é executável. Isso se traduz no seguinte plano:
Eu diria que fazer isso de maneira portátil exigirá muito poder e tempo de computação. É realmente o que você precisa?
fonte
Existe um script what.py em uma distribuição padrão do Python (por exemplo, no Windows
'\PythonXX\Tools\Scripts\which.py'
).EDIT:
which.py
depende,ls
portanto, não é multiplataforma.fonte
Nenhum dos exemplos anteriores funciona em todas as plataformas. Geralmente eles não funcionam no Windows, porque você pode executar sem a extensão do arquivo e registrar uma nova extensão. Por exemplo, no Windows, se o python estiver bem instalado, basta executar 'file.py' e ele funcionará.
A única solução válida e portátil que eu tinha era executar o comando e ver o código de erro. Qualquer executável decente deve ter um conjunto de parâmetros de chamada que não farão nada.
fonte
Usando a biblioteca de malhas python:
fonte
which(1)
que não está presente em todos os sistemas.