2519 votes

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

Comment puis-je vérifier si un programme existe? Il faut alors soit renvoyer une erreur et quitter ou continuer avec le script.

Il semble que ce devrait être facile, mais il a été estompe moi.

3534voto

lhunath Points 27045

Oui; éviter which. Non seulement est-il un processus externe vous lancer pour faire très peu (ce qui signifie fonctions internes telles que hash, type ou command sont beaucoup moins cher), vous pouvez également compter sur les objets internes à réellement faire ce que vous voulez, tandis que les effets des commandes externes peuvent facilement varier d'un système à l'autre.

Pourquoi s'en faire?

  • De nombreux systèmes d'exploitation ont un which qui n'a même pas de définir un statut de sortie, le sens de l' if which foo n'aurez même pas y travailler, et aura toujours le rapport qu' foo existe, même si elle n'est pas (à noter que certaines POSIX coquilles apparaissent pour ce faire, pour hash aussi).
  • De nombreux systèmes d'exploitation font which ne personnalisée et le mal des trucs comme changer la sortie ou même accrocher dans le gestionnaire de paquet.

Donc, ne pas utiliser which. Au lieu d'utiliser l'un de ces:

$ command -v foo >/dev/null 2>&1 || { echo >&2 "I require foo but it's not installed.  Aborting."; exit 1; }
$ type foo >/dev/null 2>&1 || { echo >&2 "I require foo but it's not installed.  Aborting."; exit 1; }
$ hash foo 2>/dev/null || { echo >&2 "I require foo but it's not installed.  Aborting."; exit 1; }

Si votre hash bang est - /bin/sh alors vous devez être attentif à ce que POSIX dit. type et hashs'codes de sortie ne sont pas très bien défini par POSIX, et hash est perçue à la sortie avec succès lorsque la commande n'existe pas (n'ont pas vu cela avec type encore). command'état de sortie est bien défini par POSIX, de sorte que l'on est probablement le plus sûr à utiliser.

Si votre script utilise bash si, POSIX règles ne comptent plus vraiment et les deux type et hash devenir parfaitement sûrs à utiliser. type a maintenant un -P à la recherche juste l' PATH et hash a l'effet secondaire que la commande de l'emplacement sera haché (pour accélérer la recherche de la prochaine fois que vous l'utilisez), qui est généralement une bonne chose puisque vous avez probablement vérifier son existence dans l'ordre de l'utiliser.

Comme simple exemple, voici une fonction qui s'exécute gdate si elle existe, sinon, date:

gnudate() {
    if hash gdate 2>/dev/null; then
        gdate "$@"
    else
        date "$@"
    fi
}

En résumé:

bash est votre shell/hashbang, utiliser systématiquement hash (pour les commandes) ou type (considérer built-ins et mots-clés).

Lors de l'écriture d'une POSIX script, utilisez command -v.

216voto

GregV Points 711

Je suis d'accord avec lhunath de décourager l'utilisation de l' which, et sa solution est parfaitement valable pour les utilisateurs de BASH. Cependant, pour être plus portable, command -v doit être utilisée à la place:

$ command -v foo >/dev/null 2>&1 || { echo "I require foo but it's not installed.  Aborting." >&2; exit 1; }

Commande command est conforme à POSIX, voir ici pour son spécifications: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/command.html

Remarque: type est conforme à POSIX, mais type -P ne l'est pas.

95voto

Josh Strater Points 377

J'ai une fonction définie dans mon .bashrc qui rend cela plus facile.

command_exists () {
    type "$1" &> /dev/null ;
}

Voici un exemple de la façon dont il est utilisé (à partir de mon .bash_profile.)

if command_exists mvim ; then
    export VISUAL="mvim --nofork"
fi

89voto

dreamlax Points 47152

Cela dépend si vous voulez savoir si il existe dans l'un des répertoires dans l' $PATH variable ou si vous connaissez l'emplacement absolu. Si vous voulez savoir si c'est dans l' $PATH variable

if which programname >/dev/null; then
    echo exists
else
    echo does not exist
fi

utiliser autrement

if [ -x /path/to/programname ]; then
    echo exists
else
    echo does not exist
fi

La redirection d' /dev/null/ dans le premier exemple supprime la sortie de l' which programme.

18voto

Marve Points 2471

Pour utiliser hash, comme @lhunath suggère, dans un script bash:

hash foo &> /dev/null
if [ $? -eq 1 ]; then
    echo >&2 "foo not found."
fi

Ce script s'exécute hash puis vérifie si le code de sortie de la commande la plus récente, la valeur stockée dans $?, est égale à 1. Si hash ne trouve pas d' foo, le code de sortie sera 1. Si foo est présent, le code de sortie sera 0.

&> /dev/null redirige erreur standard et la sortie standard d' hash , de sorte qu'il n'apparaisse pas à l'écran et echo >&2 écrit le message d'erreur standard.

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