111 votes

Comment afficher le numéro de ligne lors de l'exécution de bash script

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.

195voto

devnull Points 45016

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]}(): }'

44voto

Deqing Points 2178

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.

4voto

Luc Points 41

PS4 avec valeur $LINENO est ce dont vous avez besoin,

Par exemple, en suivant script (myScript.sh) :

       #!/bin/bash -xv
       PS4='${LINENO}: '
       echo "Hello"
       echo "World"

La sortie serait :

  ./myScript.sh
  +echo Hello
  3 : Hello
  +echo World
  4 : World

3voto

kklepper Points 437

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

0voto

hek2mgl Points 38787

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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X