Bash : Vérifier qu’une commande existe

	Comment vérifier qu'une commande existe en Bash ?
	Comment vérifier la disponibilité des prérequis d'un script ?

Une méthode permettant de vérifier qu’une commande existe consiste à tester le retour de « command -v <commande_a_tester> » :

fhh@mafalda ~ $ command -v ls
alias ls='ls --color=auto'
fhh@mafalda ~ $ echo $?
0
fhh@mafalda ~ $ command -v ls > /dev/null && echo "ls existe"
ls existe

Si la commande existe et est accessible via le PATH ou au chemin spécifié, « command -v » retourne « 0 », sinon, le retour est supérieur à « 0 » :

fhh@mafalda ~ $ command -v youhou # youhou n'existe pas dans le PATH ou comme commande interne :
fhh@mafalda ~ $ echo $?
1
fhh@mafalda ~ $ command -v ../../usr/bin/date # date est accessible au chemin spécifié :
fhh@mafalda ~ $ echo $?
0

Vérifier les prérequis d’un script

Dans un script une manière de tester les prérequis (programmes nécessaires à l’exécution du code) consiste à placer la liste des dépendances dans une variable et à tester leur disponibilité. Ce qui peut donner une fonction du genre de « checkrequirements » :

#!/bin/bash
 
_needed_commands="ls ps dhclient /sbin/dhclient ./montest.sh /bin/bash truc machin" ;
 
checkrequirements () {
        command -v command >/dev/null 2>&1 || {
                echo "WARNING> \"command\" not found. Check requirements skipped !"
                return 1 ;
        }
        for requirement in ${_needed_commands} ; do
                echo -n "checking for \"$requirement\" ... " ;
                command -v ${requirement} > /dev/null && {
                        echo "ok" ;
                        continue ;
                } || {
                        echo "required but not found !" ;
                        _return=1 ;
                }
                done
        [ -z "${_return}" ] || { 
                echo "ERR > Requirement missing." >&2 ; 
                exit 1 ;
        }
}
 
checkrequirements

qui donne à l’exécution :

1
2
3
4
5
6
7
8
9
10
11
12
fhh@mafalda ~ $ ./montest.sh 
checking for "ls" ... ok
checking for "ps" ... ok
checking for "dhclient" ... required but not found !
checking for "/sbin/dhclient" ... ok
checking for "./montest.sh" ... ok
checking for "/bin/bash" ... ok
checking for "truc" ... required but not found !
checking for "machin" ... required but not found !
ERR > Requirement missing.
fhh@mafalda ~ $ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games

Note : Ligne 4, « dhclient » est marqué comme non trouvé car il n’est pas dans les répertoires du PATH de l’utilisateur. En revanche, en spécifiant le chemin complet vers le binaire (en absolu), ligne 5, la dépendance est trouvée. Ligne 6, on voit que les chemins peuvent être spécifié en relatif.

Plus d’infos sur « command »

L’option « -v », en minuscule, affiche :

  • la commande seule s’il s’agit d’une commande interne ;
  • le chemin absolu vers la commande si elle est dans le PATH ou relatif si elle à été précisée en relatif ;
  • la définition de l’alias s’il s’agit d’un alias ;
fhh@aaricia ~ $ command -v test
test
fhh@aaricia ~ $ command -v date
/usr/bin/date
fhh@aaricia ~ $ command -v ../../usr/bin/date
../../usr/bin/date
fhh@aaricia ~ $ command -v ls
alias ls='ls --color=auto'
fhh@aaricia ~ $ yop () { echo "Fonction yop" ;}
fhh@aaricia ~ $ command -v yop
yop

L’option « -V », en majuscule, affiche les mêmes informations que son homologue minuscule mais dans un format accès « lisibilité utilisateur » :

fhh@aaricia ~ $ command -V test
test is a shell builtin
fhh@aaricia ~ $ command -V date
date is /usr/bin/date
fhh@aaricia ~ $ command -V ../../usr/bin/date
../../usr/bin/date is ../../usr/bin/date
fhh@aaricia ~ $ command -V ls
ls is aliased to `ls --color=auto'
fhh@aaricia ~ $ yop () { echo "Fonction yop" ;}
yop is a function
yop ()
{
    echo "Fonction yop"
}

Notez le comportement de l’option sur une fonction …

L’option « -p » execute la commande « originale » c’est à dire directement depuis le PATH :

fhh@aaricia ~ $ alias date="date +%s"
fhh@aaricia ~ $ date
1378889936
fhh@aaricia ~ $ command -p date
Wed Sep 11 10:59:20 CEST 2013

Dans cet exemple, l’option « -p » permet d’utiliser « date » directement et non l’alias défini pour cette commande.

Note : dans cet exemple, « command -p date » équivaut à « \date ».

3 réflexions au sujet de « Bash : Vérifier qu’une commande existe »

    1. C’est passé 😉 Merci pour ce retour. En effet, l’exemple concerne « bash ». De manière générale, « bash » est quasi aussi rependu qu' »sh » ce qui n’est pas le cas de « ksh »… Pour ma part, je reste donc basique sans me priver de confort donc « bash » plutôt que « ksh » et qu' »sh ». Mais c’est purement personnel.

  1. Bonsoir,
    Lorsque je programme en POSIX sh, qui ne comporte pas ‘command’, j’ai tendance à tester la présence de l’exécutable dans /usr/bin, avec test.
    Quelque chose du genre:
    [ -x "/usr/bin/date" ] && printf "%s\n" "date is installed"
    Même si parfois les exécutables sont dans /sbin ou dans /usr/local/bin, je trouve cette manère très efficace.
    Avec ksh, j’utilise whence + test comme ceci:
    [ -n "$(whence date)" ] && print "date is installed"
    Cordialement

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *