92 votes

Vérifier si un programme existe à partir d'un script python.

Comment vérifier si un programme existe à partir d'un script python ?

Disons que vous voulez vérifier si wget o curl sont disponibles. Nous supposerons qu'ils doivent être dans le chemin.

Le mieux serait de voir une solution multiplateforme mais pour l'instant, Linux suffit.

Des conseils :

  • exécuter la commande et vérifier le code de retour n'est pas toujours suffisant car certains outils renvoient un résultat différent de 0 même lorsque vous essayez --version .
  • rien ne doit être visible à l'écran lors de la vérification de la commande

De plus, j'apprécierais une solution plus générale, du genre is_tool(name)

184voto

Six Points 1734

Shutil.which

Permettez-moi de recommander une option qui n'a pas encore été discutée : une implémentation Python de which et plus particulièrement shutil.which . Il a été introduit dans Python 3.3 et est multiplateforme, supportant Linux, Mac et Windows. Il est également disponible dans Python 2.x via quelcraft . Vous pouvez aussi simplement déchirer le code pour which tout droit sorti de l'usine ici et l'insérer dans votre programme.

def is_tool(name):
    """Check whether `name` is on PATH and marked as executable."""

    # from whichcraft import which
    from shutil import which

    return which(name) is not None

distutils.spawn.find_executable

Une autre option qui a déjà été mentionnée est distutils.spawn.find_executable .

find_executable La docstring de l'article est la suivante :

Tente de trouver 'executable' dans les répertoires listés dans 'path'.

Si vous êtes attentif, vous remarquerez que le nom de la fonction est quelque peu trompeur. Contrairement à which , find_executable ne vérifie pas réellement que executable est marqué comme exécutable, seulement qu'il est sur le PATH. Il est donc tout à fait possible (bien que peu probable) que find_executable indique qu'un programme est disponible alors qu'il ne l'est pas.

Par exemple, supposons que vous ayez un fichier /usr/bin/wget qui n'est pas marqué comme exécutable. Exécution de wget à partir du shell entraînera l'erreur suivante : bash : /usr/bin/wget : Permission refusée . which('wget') is not None retournera Faux, mais find_executable('wget') is not None retournera Vrai. Vous pouvez probablement vous en sortir en utilisant l'une ou l'autre de ces fonctions, mais il s'agit d'un élément dont il faut être conscient dans le cas de find_executable .

def is_tool(name):
    """Check whether `name` is on PATH."""

    from distutils.spawn import find_executable

    return find_executable(name) is not None

52voto

Sven Marnach Points 133943

Le plus simple est d'essayer d'exécuter le programme avec les paramètres souhaités, et de traiter l'exception si elle n'existe pas :

try:
    subprocess.call(["wget", "your", "parameters", "here"])
except FileNotFoundError:
    # handle file not found error.

C'est un modèle courant en Python : EAFP

En Python 2, vous deviez attraper OsError à la place, puisque les classes d'exceptions plus fines pour les erreurs du système d'exploitation n'existaient pas encore :

try:
    subprocess.call(["wget", "your", "parameters", "here"])
except OSError as e:
    if e.errno == errno.ENOENT:
        # handle file not found error.
    else:
        # Something else went wrong while trying to run `wget`
        raise

15voto

J_Zar Points 957

Vous pouvez utiliser un appel de sous-processus au binaire nécessaire avec :

  • "lequel" : *nix
  • "où" : Win 2003 et plus récent (Xp a un addon)

pour obtenir le chemin de l'exécutable (en supposant qu'il soit dans le chemin de l'environnement).

import os 
import platform
import subprocess

cmd = "where" if platform.system() == "Windows" else "which"
try: 
    subprocess.call([cmd, your_executable_to_check_here])
except: 
    print "No executable"

ou utilisez simplement wh.py script de Ned Batchelder, qui est une implémentation multiplateforme "qui" :

http://nedbatchelder.com/code/utilities/wh_py.html

13voto

sorin Points 23747
import subprocess
import os

def is_tool(name):
    try:
        devnull = open(os.devnull)
        subprocess.Popen([name], stdout=devnull, stderr=devnull).communicate()
    except OSError as e:
        if e.errno == os.errno.ENOENT:
            return False
    return True

12voto

Martin Richard Points 914

J'irais pour :

import distutils.spawn

def is_tool(name):
  return distutils.spawn.find_executable(name) is not None

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X