GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo encuentro el número de línea en Bash cuando ocurre un error?

En lugar de usar su función, usaría este método:

$ cat yael.bash
#!/bin/bash

set -eE -o functrace

file1=f1
file2=f2
file3=f3
file4=f4

failure() {
  local lineno=$1
  local msg=$2
  echo "Failed at $lineno: $msg"
}
trap 'failure ${LINENO} "$BASH_COMMAND"' ERR

cp -- "$file1" "$file2"
cp -- "$file3" "$file4"

Esto funciona capturando ERR y luego llamando al failure() función con el número de línea actual + comando bash que se ejecutó.

Ejemplo

Aquí no me he preocupado por crear los archivos, f1 , f2 , f3 , o f4 . Cuando ejecuto el script anterior:

$ ./yael.bash
cp: cannot stat ‘f1’: No such file or directory
Failed at 17: cp -- "$file1" "$file2"

Falla, informando el número de línea más el comando que se ejecutó.


Además de LINENO que contiene el número de línea actual, están los BASH_LINENO y FUNCNAME (y BASH_SOURCE ) matrices que contienen los nombres de las funciones y los números de línea desde los que se llaman.

Así que podrías hacer algo como esto:

#!/bin/bash

error() {
        printf "'%s' failed with exit code %d in function '%s' at line %d.\n" "${1-something}" "$?" "${FUNCNAME[1]}" "${BASH_LINENO[0]}"
}

foo() {
        ( exit   0 ) || error "this thing"
        ( exit 123 ) || error "that thing"
}

foo

Ejecutar eso imprimiría

'that thing' failed with exit code 123 in function 'foo' at line 9.

Si usa set -e o trap ... ERR para detectar errores automáticamente, tenga en cuenta que tienen algunas advertencias. También es más difícil incluir una descripción de lo que estaba haciendo la secuencia de comandos en ese momento (como hizo en su ejemplo), aunque eso podría ser más útil para un usuario normal que solo el número de línea.

Véase, por ejemplo. estos para los problemas con set -e y otros:

  • ¿Por qué set -e no funciona dentro de subcapas con paréntesis () seguido de una lista OR ||?
  • bash -e sale cuando let o expr se evalúa como 0
  • BashFAQ 105:¿Por qué set -e (o set -o errexit, o trap ERR) no hace lo que esperaba?

Bash tiene una variable incorporada $LINENO que se reemplaza por el número de línea actual cuando está en una declaración, por lo que puede hacer

in_case_fail $? "at $LINENO: cp $file1 $file2"

También puedes intentar usar trap ... ERR que se ejecuta cuando falla un comando (si el resultado no se prueba). Por ejemplo:

trap 'rc=$?; echo "error code $rc at $LINENO"; exit $rc' ERR

Entonces, si un comando como cp $file1 $file2 falla obtendrá el mensaje de error con el número de línea y una salida. También encontrará el comando erróneo en la variable $BASH_COMMAND (aunque no redirecciones, etc.).


Linux
  1. Cómo encontrar archivos en CentOS 8 en la línea de comandos

  2. Cómo encontrar el número de núcleos en Ubuntu

  3. Cómo agregar un ícono al indicador de bash

  4. ¿Cómo puedo contar la cantidad de caracteres en una variable Bash?

  5. ¿Cómo puedo encontrar el número de usuarios en línea en Linux?

Cómo comentar en Bash

Cómo leer un archivo línea por línea en Bash

Cómo encontrar el número de puerto de un servicio en Linux

Cómo encontrar quién reinició el sistema Linux y cuándo

Cómo encontrar archivos en la línea de comandos de Ubuntu

¿Cómo borrar el número de línea en Vim al copiar?