J'ai un test script qui a beaucoup de commandes et va générer beaucoup de sorties, j'utilise set -x
o set -v
y set -e
pour que le script s'arrête en cas d'erreur. Cependant, il m'est toujours assez difficile de localiser à quelle ligne l'exécution s'est arrêtée afin de localiser le problème. Existe-t-il une méthode permettant de sortir le numéro de ligne du script avant l'exécution de chaque ligne ? Ou bien sortir le numéro de ligne avant l'exposition de la commande générée par set -x
? Ou toute méthode qui peut traiter mon problème d'emplacement de ligne script serait d'une grande aide. Merci.
Réponses
Trop de publicités?Vous mentionnez que vous utilisez déjà -x
. La variable PS4
indique que la valeur est l'invite imprimée avant que la ligne de commande ne soit envoyée en écho lorsque la commande -x
est définie et a pour valeur par défaut :
suivi d'un espace.
Vous pouvez modifier PS4
pour émettre le LINENO
(Le numéro de ligne dans le script ou la fonction shell en cours d'exécution).
Par exemple, si votre script se lit :
$ cat script
foo=10
echo ${foo}
echo $((2 + 2))
L'exécuter ainsi imprimerait les numéros de ligne :
$ PS4='Line ${LINENO}: ' bash -x script
Line 1: foo=10
Line 2: echo 10
10
Line 3: echo 4
4
http://wiki.bash-hackers.org/scripting/debuggingtips donne l'ultime PS4
qui sortirait tout ce dont vous avez besoin pour le traçage :
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
Dans Bash, $LINENO
contient le numéro de ligne où le script s'exécute actuellement.
Si vous avez besoin de connaître le numéro de ligne où la fonction a été appelée, essayez $BASH_LINENO
. Notez que cette variable est un tableau.
Par exemple :
#!/bin/bash
function log() {
echo "LINENO: ${LINENO}"
echo "BASH_LINENO: ${BASH_LINENO[*]}"
}
function foo() {
log "$@"
}
foo "$@"
Voir aquí pour les détails des variables Bash.
Solution de contournement pour les shells sans LINENO
Dans un script assez sophistiqué, je ne voudrais pas voir tous les numéros de ligne ; je voudrais plutôt avoir le contrôle de la sortie.
Définir une fonction
echo_line_no () {
grep -n "$1" $0 | sed "s/echo_line_no//"
# grep the line(s) containing input $1 with line numbers
# replace the function name with nothing
} # echo_line_no
Utilisez-le avec des citations comme
echo_line_no "this is a simple comment with a line number"
La sortie est
16 "this is a simple comment with a line number"
si le numéro de cette ligne dans le fichier source est 16.
Cela répond essentiellement à la question Comment afficher le numéro de ligne lors de l'exécution de bash script pour les utilisateurs de ash ou d'autres shells sans LINENO
.
Rien d'autre à ajouter ?
Bien sûr. Pourquoi en avez-vous besoin ? Comment travaillez-vous avec ça ? Que pouvez-vous faire avec ceci ? Cette approche simple est-elle vraiment suffisante ou utile ? Pourquoi voulez-vous bricoler avec ça ?
Vous voulez en savoir plus ? Lire les réflexions sur le débogage
Une solution simple (mais puissante) : Placez echo
autour du code que vous pensez être à l'origine du problème et déplacez le echo
ligne par ligne jusqu'à ce que les messages n'apparaissent plus à l'écran - car le script s'est arrêté à cause d'une erreur auparavant.
Une solution encore plus puissante : Installez bashdb
le débogueur bash et déboguer le script ligne par ligne.