2009-04-18 5 views
12

Je veux savoir si une commande existe sur un système POSIX à partir d'un script shell.Déterminez si une commande existe sur le système POSIX

Sur Linux, je peux faire ce qui suit:

if which <command>; then 
    ...snip... 
fi 

Cependant, Solaris et MacOS which ne donnent pas un code d'erreur de sortie lorsque la commande n'existe pas, ils impriment juste un message d'erreur à STDOUT.

Aussi, j'ai découvert récemment que la commande which lui-même est pas POSIX (voir http://www.opengroup.org/onlinepubs/009695399/utilities/)

Toutes les idées?

+2

related: [shell - Vérifier si un programme existe à partir d'un script bash] (http://stackoverflow.com/questions/592620/check-if-a-program-exists-from-a-bash-script) – mrak

+0

Merci, n'était pas si clair du dessous, cela m'a aidé @mrak 'if commande -v dropbox; then dropbox running' ... – Louis

Répondre

18

command -v est une commande POSIX spécifiée qui fait quoi.

Il est défini pour renvoyer> 0 lorsque la commande est introuvable ou qu'une erreur se produit.

+2

Je suis entièrement d'accord avec l'utilisation de 'command -v', je l'utilise tout le temps, pour vérifier la disponibilité de la commande. Par exemple, 'commande -v CMD>/dev/null || echo 'CMD not found'' Non stupide 'si' est requis !! – TechZilla

+2

@TechZilla: pourquoi les déclarations 'if' sont-elles stupides? – dokaspar

+0

'if' n'est pas stupide juste parce que c'est un' if', c'était stupide dans ce cas d'utilisation car il est étranger. Il n'y avait pas de regroupement, et donc pas de valeur sémantique supplémentaire, ce serait juste une réévaluation inutile. Peut-il être justifié de toute façon, absolument! Un zélote de n'importe quelle pratique peut justifier presque n'importe quoi, et dans ce cas la conséquence est insignifiante ... mais cela ne signifie pas qu'ils sont corrects, ou que toutes choses sont égales. Généralement, je fais la pratique comme ceci, une commande (test inclus) avec un seul code d'erreur, pas d'instruction if. Une fois que vous obtenez plus, alors «si» pourrait être plus que raisonnable. – TechZilla

0

Vous pouvez lire le fichier stdout/stderr de "which" dans une variable ou un tableau (en utilisant des guillemets) plutôt que de rechercher un code de sortie. Si le système n'a pas de commande "which" ou "where", vous pouvez également récupérer le contenu de la variable $ PATH, puis parcourir tous les répertoires et rechercher l'exécutable donné. C'est essentiellement ce qui fait (même si cela peut utiliser une mise en cache/optimisation des résultats $ PATH).

+0

Le problème est, que même sur les systèmes qui ont * qui *, je ne suis pas garanti il ​​y aura même * be * toute sortie ... Je suppose que je pourrais juste vérifier pour voir que ça ne marche pas "ressembler à un chemin" ... – singpolyma

+0

Ah, [-x "' qui aeiei' "] pourrait fonctionner ... encore, en supposant ce qui existe ... – singpolyma

2

Posix ne dit, « If a command is not found, the exit status shall be 127. » Vous pouvez faire

<command> 
if [ "${?}" = 127 ]; then 
    <handle not found> 
fi 

Lors de l'écriture des scripts shell, il est souvent permis d'exiger un shell bash (#!/bin/bash), parce que sans tableaux, il est à peu près impossible de traiter les arguments et/ou les noms de fichiers avec des espaces correctement. Dans ce cas, le bash intégré à type -p est équivalent à celui qui, et parce qu'il est intégré, est portable.

+2

Le type sans -p est POSIX, mais POSIX ne garantit pas qu'il interprète la commande qui n'existe pas comme une erreur. – singpolyma

+1

Bash est un extra sur de nombreux systèmes. Essayer de trouver si les choses sont supportées en utilisant un shell non standard n'est pas très bon. – dwc

+2

Sur Ubuntu, ils ont essayé de passer de bash à dash pour autant de scripts que possible (surtout au démarrage) car il est plus petit et plus rapide à lancer. Et les BSD ne sont pas livrés avec bash dans leur installation de base. La plupart des unix basés sur le système V ne le sont pas non plus. –

Questions connexes