Comment vérifier si la commande existe dans un script shell?

j'écris mon premier script shell. Dans mon script je voudrais vérifier si une commande existe, et si pas le cas, installez l'exécutable. Comment puis-je vérifier si cette commande existe?

if #check that foobar command doesnt exist
then
    #now install foobar
fi
118
demandé sur Andrew 2011-09-23 03:34:25

8 réponses

en général, cela dépend de votre shell, mais si vous utilisez bash, zsh, ksh ou sh (tel que fourni par dash), ce qui suit devrait fonctionner:

if ! type "$foobar_command_name" > /dev/null; then
  # install foobar here
fi

pour un vrai script d'installation, vous voudriez probablement être sûr que type ne retourne pas avec succès dans le cas où il y a un alias foobar . À bash vous pourriez faire quelque chose comme ceci:

if ! foobar_loc="$(type -p "$foobar_command_name")" || [[ -z $foobar_loc ]]; then
  # install foobar here
fi
191
répondu Ivan Tarasov 2018-03-25 21:59:44

essayez d'utiliser type :

type foobar

par exemple:

$ type ls
ls is aliased to `ls --color=auto'

$ type foobar
-bash: type: foobar: not found

C'est préférable à which pour quelques raisons:

1) les implémentations par défaut which ne prennent en charge que l'option -a qui affiche toutes les options, vous devez donc trouver une version alternative pour prendre en charge les alias

2) type vous dira exactement ce que vous regardez (que ce soit une fonction bash ou un alias ou un bon binaire).

3) le type n'a pas besoin d'un sous-processus

4) le type ne peut pas être masqué par un binaire (par exemple, sur une machine linux, si vous créez un programme appelé which qui apparaît dans path avant le vrai which , les choses frappent le ventilateur. type , d'un autre côté, est un shell intégré [Oui, un subordonné l'a fait par inadvertance une fois]

30
répondu Foo Bah 2011-09-23 00:04:00

vérifiez si un programme existe à partir d'un script Bash couvre très bien cela. Dans n'importe quel script shell, il est préférable d'exécuter command -v $command_name pour tester si $command_name peut être exécuté. Dans bash, vous pouvez utiliser hash $command_name , qui hache aussi le résultat de n'importe quelle recherche de chemin, ou type -P $binary_name si vous voulez seulement voir des binaires (pas de fonctions etc.)

16
répondu Morten 2017-05-23 12:10:44

cinq voies, 4 pour bash et 1 addition pour zsh:

  • type foobar &> /dev/null
  • hash foobar &> /dev/null
  • command -v foobar &> /dev/null
  • which foobar &> /dev/null
  • (( $+commands[foobar] )) (zsh seulement)

vous pouvez mettre n'importe lequel d'entre eux à votre if clause. D'après mes tests ( https://www.topbug.net/blog/2016/10/11/speed-test-check-the-existence-of-a-command-in-bash-and-zsh / ), la 1ère et la 3ème méthode sont recommandées en bash et la 5ème méthode est recommandée en zsh en termes de vitesse.

16
répondu xuhdev 2016-10-11 17:45:14

la question ne spécifie pas de coquille, donc pour ceux qui utilisent fish (friendly interactive shell):

if command --search foo >/dev/null do
  echo exists
else
  echo does not exist
end

pour la compatibilité POSIX de base, utilisez le drapeau -v qui est un alias pour --search ou -s .

11
répondu Dennis 2017-03-08 17:23:05

which <cmd>

voir aussi options which supports pour les alias si applicable à votre cas.

exemple

$ which foobar
which: no foobar in (/usr/local/bin:/usr/bin:/cygdrive/c/Program Files (x86)/PC Connectivity Solution:/cygdrive/c/Windows/system32/System32/WindowsPowerShell/v1.0:/cygdrive/d/Program Files (x86)/Graphviz 2.28/bin:/cygdrive/d/Program Files (x86)/GNU/GnuPG
$ if [ $? -eq 0 ]; then echo "foobar is found in PATH"; else echo "foobar is NOT found in PATH, of course it does not mean it is not installed."; fi
foobar is NOT found in PATH, of course it does not mean it is not installed.
$

PS: notez que tout ce qui est installé ne peut pas être dans PATH. Habituellement pour vérifier si quelque chose est" installé " ou pas, on utilise des commandes d'installation pertinentes au système D'exploitation. Par exemple: rpm -qa | grep -i "foobar" pour RHEL.

1
répondu Kashyap 2011-09-22 23:44:43

une fonction que j'ai dans un script d'installation fait pour exactement cela

function assertInstalled() {
    for var in "$@"; do
        if ! which $var &> /dev/null; then
            echo "Install $var!"
            exit 1
        fi
    done
}

exemple d'appel:

assertInstalled zsh vim wget python pip git cmake fc-cache
0
répondu mgild 2016-11-10 03:03:52

Une fonction qui fonctionne dans les deux bash et zsh:

# Return the first pathname in $PATH for name in 
function cmd_path () {
  if [[ $ZSH_VERSION ]]; then
    whence -cp "" 2> /dev/null
  else  # bash
     type -P ""  # No output if not in $PATH
  fi
}

Non-zero est retourné si la commande ne se trouve pas dans $PATH .

0
répondu Tom Hale 2018-09-01 11:21:39