Comment trouvez-vous le numéro de ligne dans Bash où une erreur s'est produite?
Exemple
Je crée le script simple suivant avec des numéros de ligne pour expliquer ce dont nous avons besoin. Le script copiera les fichiers de
cp $file1 $file2
cp $file3 $file4
Lorsque l'une des cp
commandes échoue, la fonction se termine avec la sortie 1 . Nous voulons ajouter la possibilité à la fonction d'imprimer également l'erreur avec le numéro de ligne (par exemple, 8 ou 12).
Est-ce possible?
Exemple de script
1 #!/bin/bash
2
3
4 function in_case_fail {
5 [[ $1 -ne 0 ]] && echo "fail on $2" && exit 1
6 }
7
8 cp $file1 $file2
9 in_case_fail $? "cp $file1 $file2"
10
11
12 cp $file3 $file4
13 in_case_fail $? "cp $file3 $file4"
14
set -x
et / ouset -v
pour retracer ce qui a été exécuté. Pas exactement ce que vous avez demandé, mais ce sera probablement utile aussi.Réponses:
Plutôt que d'utiliser votre fonction, j'utiliserais plutôt cette méthode:
Cela fonctionne en interceptant ERR puis en appelant la
failure()
fonction avec la commande numéro de ligne + bash actuelle qui a été exécutée.Exemple
Ici , je l' ai pas pris de soin de créer les fichiers,
f1
,f2
,f3
ouf4
. Lorsque j'exécute le script ci-dessus:Il échoue, signalant le numéro de ligne plus la commande qui a été exécutée.
la source
En plus de
LINENO
contenir le numéro de ligne actuel, il existe les tableauxBASH_LINENO
andFUNCNAME
(etBASH_SOURCE
) qui contiennent les noms de fonction et les numéros de ligne à partir desquels ils sont appelés.Vous pouvez donc faire quelque chose comme ceci:
Courir qui imprimerait
Si vous utilisez
set -e
, outrap ... ERR
pour détecter automatiquement des erreurs, notez qu'elles comportent des mises en garde. Il est également plus difficile d'inclure une description de ce que le script faisait à l'époque (comme vous l'avez fait dans votre exemple), bien que cela puisse être plus utile pour un utilisateur régulier que le simple numéro de ligne.Voir par exemple ceux-ci pour les problèmes avec
set -e
et d'autres:la source
Bash a une variable intégrée
$LINENO
qui est remplacée par le numéro de ligne actuel dans une instruction, vous pouvez donc faireVous pouvez également essayer d'utiliser les
trap ... ERR
exécutions lorsqu'une commande échoue (si le résultat n'est pas testé). Par exemple:Ensuite, si une commande comme
cp $file1 $file2
échoue, vous obtiendrez le message d'erreur avec le numéro de ligne et une sortie. Vous trouverez également la commande en erreur dans la variable$BASH_COMMAND
(mais pas de redirection, etc.).la source