J'ai fait le script suivant:
# !/bin/bash
# OUTPUT-COLORING
red='\e[0;31m'
green='\e[0;32m'
NC='\e[0m' # No Color
# FUNCTIONS
# directoryExists - Does the directory exist?
function directoryExists {
cd $1
if [ $? = 0 ]
then
echo -e "${green}$1${NC}"
else
echo -e "${red}$1${NC}"
fi
}
# EXE
directoryExists "~/foobar"
directoryExists "/www/html/drupal"
Le script fonctionne, mais à côté de mes échos, il y a aussi la sortie quand
cd $1
échoue à l'exécution.
testscripts//test_labo3: line 11: cd: ~/foobar: No such file or directory
Est-il possible d'attraper cela?
bash
shell
shell-script
error-handling
Thomas De Wilde
la source
la source
test -d /path/to/directory
(ou[[ -d /path/to/directory ]]
en bash) vous dira si une cible donnée est un répertoire ou non, et il le fera tranquillement.cd
.directoryExists
.Réponses:
Votre script change de répertoire au fur et à mesure de son exécution, ce qui signifie qu'il ne fonctionnera pas avec une série de chemins d'accès relatifs. Vous avez ensuite commenté plus tard que vous vouliez seulement vérifier l'existence du répertoire, pas la capacité à utiliser
cd
, donc les réponses n'ont pas du tout besoin d'être utiliséescd
. Modifié. Utilisationtput
et couleurs deman terminfo
:(Modifié pour utiliser le plus invulnérable
printf
au lieu de la problématiqueecho
qui pourrait agir sur les séquences d'échappement dans le texte.)la source
Utilisez
set -e
pour définir le mode exit-on-error: si une simple commande renvoie un état différent de zéro (indiquant un échec), le shell se ferme.Attention, ce
set -e
n'est pas toujours le cas. Les commandes dans les positions de test peuvent échouer (par exempleif failing_command
,failing_command || fallback
). Les commandes dans le sous-shell conduisent uniquement à quitter le sous-shell, pas le parent:set -e; (false); echo foo
s'affichefoo
.Alternativement, ou en plus, dans bash (et ksh et zsh, mais pas plain sh), vous pouvez spécifier une commande qui est exécutée au cas où une commande retourne un état différent de zéro, avec le
ERR
piège, par exempletrap 'err=$?; echo >&2 "Exiting on error $err"; exit $err' ERR
. Notez que dans des cas comme(false); …
, le trap ERR est exécuté dans le sous-shell, il ne peut donc pas provoquer la sortie du parent.la source
||
comportement, ce qui permet de gérer facilement les erreurs sans utiliser de pièges. Voir ma réponse . Que pensez-vous de cette méthode?ERR
pseudo-signal est pris en charge dans tous les shells principaux. Merci pour la revue! =)Pour développer la réponse de @Gilles :
En effet,
set -e
ne fonctionne pas à l'intérieur des commandes si vous utilisez l'||
opérateur après elles, même si vous les exécutez dans un sous-shell; par exemple, cela ne fonctionnerait pas:Mais l'
||
opérateur est nécessaire pour empêcher le retour de la fonction externe avant le nettoyage.Il existe une petite astuce qui peut être utilisée pour résoudre ce problème: exécutez la commande interne en arrière-plan, puis attendez-la immédiatement. La fonction
wait
intégrée renverra le code de sortie de la commande interne, et maintenant vous utilisez||
aprèswait
, pas la fonction interne, doncset -e
fonctionne correctement à l'intérieur de cette dernière:Voici la fonction générique qui s'appuie sur cette idée. Cela devrait fonctionner dans tous les shells compatibles POSIX si vous supprimez des
local
mots clés, c'est-à-dire remplacez toutlocal x=y
par justex=y
:Exemple d'utilisation:
Exécuter l'exemple:
La seule chose dont vous devez être conscient lorsque vous utilisez cette méthode est que toutes les modifications des variables Shell effectuées à partir de la commande à laquelle vous passez
run
ne se propageront pas à la fonction appelante, car la commande s'exécute dans un sous-shell.la source
Vous ne dites pas exactement ce que vous entendez par
catch
--- signalez et continuez; abandonner le traitement ultérieur?Depuis
cd
retourne un état non nul en cas d'échec, vous pouvez faire:Vous pouvez simplement quitter en cas d'échec:
Ou, faites écho à votre propre message et quittez:
Et / ou supprimer l'erreur fournie par
cd
en cas d'échec:Selon les normes, les commandes doivent placer des messages d'erreur sur STDERR (descripteur de fichier 2). Ainsi
2>/dev/null
dit rediriger STDERR vers le "bit-bucket" connu par/dev/null
.(n'oubliez pas de citer vos variables et de marquer la fin des options pour
cd
).la source
En fait, pour votre cas, je dirais que la logique peut être améliorée.
Au lieu de cd puis vérifiez s'il existe, vérifiez s'il existe puis allez dans le répertoire.
Mais si votre but est de faire taire les erreurs possibles
cd -- "$1" 2>/dev/null
, cela vous rendra plus difficile le débogage à l'avenir. Vous pouvez vérifier les drapeaux if testing sur: Bash if documentation :la source
$1
variable et échouera si cette variable contient des blancs ou d'autres métacaractères shell. Il ne parvient pas non plus à vérifier si l'utilisateur y est autorisécd
.