Je programme un script shell Linux qui imprimera des bannières d'état pendant son exécution uniquement si l'outil approprié, par exemple figlet
, est installé (c'est-à-dire: accessible sur le chemin système ).
Exemple:
#!/usr/bin/env bash
echo "foo"
figlet "Starting"
echo "moo"
figlet "Working"
echo "foo moo"
figlet "Finished"
J'aimerais que mon script fonctionne sans erreur même lorsqu'il figlet
n'est pas installé .
Quelle pourrait être une méthode pratique ?
shell
scripting
executable
Sopalajo de Arrierez
la source
la source
figlet ... || true
.figlet || true
, mais dans votre cas, probablement une fonction shell qui peut être imprimée en clair Echos Si aucune bannière ne peut être imprimée est plus probablement ce que vous voulez.Réponses:
Mon interprétation utiliserait une fonction wrapper nommée de la même manière que l'outil; dans cette fonction, exécutez l'outil réel s'il existe:
Ensuite, vous pouvez avoir
figlet arg1 arg2...
inchangé dans votre script.@Olorin a proposé une méthode plus simple: définir une fonction wrapper uniquement si nous en avons besoin (si l'outil n'existe pas):
Si vous souhaitez que les arguments
figlet
soient imprimés même si la figlet n'est pas installée, ajustez la suggestion d'Olorin comme suit:la source
command
vient-il? Je ne l'ai pas dans mes installations (Red Hat 6.8 Enterprise et Cygwin64).command
est un shell intégré POSIX Bourne. Il exécute normalement la commande fournie, mais l'-v
indicateur le fait se comporter davantage commetype
un autre shell intégré.type -a command
vous le montrera.which
sera seulement montrer sur vos executables$PATH
, pas Encastrements, mots - clés, des fonctions ou des alias.which
ne trouve un alias applicable, car il aliaswhich
lui - même à courir/usr/bin/which
(!) et redirigez une liste des noms d' emprunt à regarder dans (Bien sûr du shell\which
supprime l'alias et utilise uniquement le programme, qui n'affiche pas les alias.)Vous pouvez tester pour voir s'il
figlet
existela source
Une façon courante de le faire est avec
test -x
aka[ -x
. Voici un exemple tiré d'/etc/init.d/ntp
un système Linux:Cette variante repose sur la connaissance du chemin complet de l'exécutable. Dans
/bin/lesspipe
j'ai trouvé un exemple qui contourne cela en combinant-x
et lawhich
commande:De cette façon, cela fonctionnera sans savoir à l'avance où se trouve
PATH
l'bunzip
exécutable.la source
which
. Et même si celawhich
fonctionne, l'utilisationtest -x
de sa sortie est idiote: si vous obtenez un cheminwhich
, il existe.test -x
fait plus que simplement vérifier si un fichier existe (c'est pour çatest -e
). Il vérifie également si le fichier a les autorisations d'exécution définies.which
.Au début de votre script, vérifiez s'il
figlet
existe, et si ce n'est pas le cas, définissez une fonction shell qui ne fait rien:type
vérifie s'ilfiglet
existe en tant que shell intégré, fonction, alias ou mot clé,>/dev/null 2>&1
supprime stdin et stdout pour que vous n'obteniez aucune sortie, et s'il n'existe pas,figlet() { :; }
définitfiglet
comme une fonction qui ne fait rien.De cette façon, vous n'avez pas à modifier chaque ligne de votre script qui utilise
figlet
ou à vérifier si elle existe à chaquefiglet
appel.Vous pouvez ajouter un message de diagnostic, si vous le souhaitez:
En prime, puisque vous n'avez pas mentionné le shell que vous utilisez, je pense que c'est compatible POSIX, donc cela devrait fonctionner sur la plupart des shell.
la source
type figlet >/dev/null 2>&1
parhash figlet 2>/dev/null
si vous utilisez bash. (L'OP a dit "si c'est dans mon CHEMIN".)Une autre alternative - un modèle que j'ai vu dans les scripts de configuration automatique de projet:
Dans votre cas spécifique, vous pourriez même le faire,
Si vous ne connaissez pas le chemin spécifique, vous pouvez essayer plusieurs
elif
(voir ci-dessus) pour essayer des emplacements connus, ou simplement utiliser lePATH
pour toujours résoudre la commande:En général, lors de l'écriture de scripts, je préfère appeler uniquement des commandes dans des emplacements spécifiques spécifiés par moi. Je n'aime pas l'incertitude / le risque de ce que l'utilisateur final pourrait avoir mis dans leur
PATH
, peut-être dans le leur~/bin
.Si, par exemple, j'écrivais un script compliqué pour d'autres qui pourrait supprimer des fichiers en fonction de la sortie d'une commande particulière que j'appelle, je ne voudrais pas accidentellement ramasser quelque chose dans leur
~/bin
qui pourrait ou non être la commande J'esperais.la source
figlet
c'était dans/usr/local/bin
ou/home/bob/stuff/programs/executable/figlet
?La
type
commande bash recherche une commande, une fonction, un alias, un mot-clé ou une fonction intégrée (voirhelp type
) et imprime l'emplacement ou la définition. Il renvoie également un code retour représentant le résultat de la recherche; true (0) si trouvé. Donc, ce que nous faisons ici est d'essayer de trouverfiglet
dans le chemin (-p
signifie seulement rechercher des fichiers, pas des fonctions intégrées ou, et supprime également les messages d'erreur), rejeter la sortie (c'est ce qui> /dev/null
fait), et si elle retourne true (&&
) , il s'exécuterafiglet
.Ceci est plus simple si se
figlet
trouve dans un emplacement fixe:Ici, nous utilisons la
test
commande (aka[
) pour voir si/usr/bin/figlet
est exécutable (-x
) et si oui (&&
) l'exécuter. Je pense que cette solution est plus portable que l'utilisation,type
ce qui est un bashisme je crois.Vous pouvez créer une fonction qui le fait pour vous:
(Les devis sont nécessaires en raison d'espaces potentiels)
Il vous suffirait alors de faire:
la source
o /, je dirais quelque chose comme
la source
Vous pouvez effectuer une exécution de test, supprimer toute sortie et tester le code de réussite / échec. Choisissez les arguments à figlet pour rendre ce test peu coûteux. -? ou --help ou --version sont des possibilités évidentes.
Ajouté en réponse au commentaire ci-dessous: si vous voulez vraiment tester que la figlet existe, pas qu'elle soit utilisable, alors vous feriez
la source
$?
est égal à 127 (sur mon système Linux). 127 est "commande introuvable". Mais ma pensée est que pour les commandes rationnelles, en cas d'command --help
échec, l'installation est suffisamment borkée pour qu'elle ne soit pas là!--help
disponibilité. Les utilitaires Posix ne l'ont pas, pour commencer, et les directives posix le déconseillent .at --help
échoue avecat: invalid option -- '-'
, par exemple, et un état de sortie de130
sur mon système.-?
--help
--version
... ou vous pouvez découvrir ce qui sefiglet -0 --illegal
termine avec, et le traiter comme votre indicateur de succès (tant qu'il n'est pas 127, que je classerais comme sabotage).