Bir hata oluştuğunda Bash'teki satır numarasını nasıl bulurum?


21

Bash'te bir hatanın oluştuğu yerdeki satır numarasını nasıl buluyorsunuz?

Misal

Neye ihtiyacımız olduğunu açıklamak için satır numaraları ile aşağıdaki basit komut dosyasını oluşturuyorum. Komut dosyası dosyaları

cp $file1 $file2
cp $file3 $file4

cpKomutlardan biri başarısız olduğunda, işlev çıkış 1 ile birlikte çıkar . Hatayı satır numarasıyla da yazdırma işlevini eklemek istiyoruz (örneğin, 8 veya 12).

Mümkün mü?

Örnek komut dosyası

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


Yürütülenleri izlemek için set -xve / veya kullanabilirsiniz set -v. Tam olarak ne istedi değil ama muhtemelen de yararlı olacaktır.
Rolf

Yanıtlar:


29

İşlevinizi kullanmak yerine, bu yöntemi kullanmak istiyorum:

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

Bu, ERR'ye bindirip failure()işlevi geçerli satır numarası + yürütülen bash komutuyla çağırarak çalışır .

Misal

İşte dosyaları oluşturmak için herhangi halledilir değil ettik f1, f2, f3, veya f4. Yukarıdaki komut dosyasını çalıştırdığımda:

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

Satır numarası artı yürütülen komutu rapor ederek başarısız olur.


14

LINENOGeçerli satır numarasını içermenin yanı sıra , çağrıldıkları işlev adlarını ve satır numaralarını içeren BASH_LINENOve FUNCNAME(ve BASH_SOURCE) dizileri de vardır.

Böylece böyle bir şey yapabilirsiniz:

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

Yazdırılacak koşu

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

Kullanıyorsanız set -eveya trap ... ERRhataları otomatik olarak algılamak için bazı uyarılar olduğunu unutmayın. Ayrıca, komut dosyasının o sırada ne yaptığının (örneğin örneğinde olduğu gibi) bir açıklamasını eklemek daha zordur, ancak bu normal bir kullanıcı için yalnızca satır numarasından daha yararlı olabilir.

Örneğin, set -eve diğer sorunlar için bunlara bakın :


13

Bash, bir deyimdeyken $LINENOgeçerli satır numarasıyla değiştirilen yerleşik bir değişkene sahiptir, böylece

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

Ayrıca trap ... ERR, bir komut başarısız olduğunda (sonuç test edilmezse) hangisinin çalıştığını da deneyebilirsiniz . Örneğin:

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

Sonra böyle bir komut cp $file1 $file2başarısız olursa, satır numarası ve bir çıkış ile hata mesajı alırsınız. Komutu değişkente de hatalı bulacaksınız $BASH_COMMAND(ancak yeniden yönlendirme vb. Olmasa da).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.