GNU/Linux >> Znalost Linux >  >> Linux

Jak zjistím číslo řádku v Bash, když došlo k chybě?

Místo použití vaší funkce bych místo toho použil tuto metodu:

$ 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"

Funguje to tak, že se zachytí chyba ERR a pak se zavolá failure() funkce s aktuálním číslem řádku + příkaz bash, který byl proveden.

Příklad

Zde jsem se nestaral o vytváření souborů, f1 , f2 , f3 nebo f4 . Když spustím výše uvedený skript:

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

Selže a hlásí číslo řádku plus příkaz, který byl proveden.


Kromě LINENO obsahující aktuální číslo řádku, je zde BASH_LINENO a FUNCNAME (a BASH_SOURCE ) pole obsahující názvy funkcí a čísla řádků, ze kterých jsou volány.

Takže můžete udělat něco takového:

#!/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

Spuštění, které by tisklo

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

Pokud používáte set -e nebo trap ... ERR Chcete-li automaticky detekovat chyby, mějte na paměti, že mají určitá upozornění. Je také těžší zahrnout popis toho, co skript v té době dělal (jako vy ve vašem příkladu), i když to může být pro běžného uživatele užitečnější než jen číslo řádku.

Viz např. tyto pro problémy s set -e a další:

  • Proč sada -e nefunguje uvnitř podskořápek se závorkami () následovanými seznamem OR ||?
  • bash -e se ukončí, když se let nebo expr vyhodnotí jako 0
  • BashFAQ 105:Proč nastavení -e (nebo set -o errexit nebo past ERR) nedělá to, co jsem očekával?

Bash má vestavěnou proměnnou $LINENO které je v příkazu nahrazeno aktuálním číslem řádku, takže můžete udělat

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

Můžete také zkusit použít trap ... ERR který se spustí, když příkaz selže (pokud není testován výsledek). Např.:

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

Pak pokud příkaz jako cp $file1 $file2 selže, zobrazí se chybová zpráva s číslem řádku a ukončením. Příkaz také najdete chybně v proměnné $BASH_COMMAND (i když ne žádná přesměrování atd.).


Linux
  1. Hledání souborů v příkazovém řádku (jak na to)

  2. Jak zjistit počet vertikálních linek dostupných v terminálu?

  3. Jak mohu spočítat počet znaků v proměnné Bash

  1. Jak zjistím počet uživatelů online v Linuxu?

  2. Jak nastavit barvu příkazového řádku v Bash?

  3. Jak najít index slova v řetězci v bash?

  1. Jak najít soubory v CentOS 8 na příkazovém řádku

  2. Linux – Jak neustále zobrazovat číslo řádku při navigaci v Nano?

  3. Jak nastavit počet snímků, které má zfs-auto-snapshot zachovat?