Bagaimana Anda menemukan nomor baris di Bash di mana kesalahan terjadi?
Contoh
Saya membuat skrip sederhana berikut dengan nomor baris untuk menjelaskan apa yang kita butuhkan. Script akan menyalin file dari
cp $file1 $file2
cp $file3 $file4
Ketika salah satu cp
perintah gagal maka fungsi akan keluar dengan keluar 1 . Kami ingin menambahkan kemampuan ke fungsi untuk juga mencetak kesalahan dengan nomor baris (misalnya, 8 atau 12).
Apakah ini mungkin?
Contoh skrip
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
set -x
dan / atauset -v
untuk melacak apa yang telah dieksekusi. Tidak persis apa yang Anda minta, tetapi mungkin akan membantu juga.Jawaban:
Daripada menggunakan fungsi Anda, saya akan menggunakan metode ini sebagai gantinya:
Ini bekerja dengan menjebak ERR dan kemudian memanggil
failure()
fungsi dengan nomor baris + perintah bash saat ini yang dieksekusi.Contoh
Di sini saya sudah tidak diurus apapun untuk membuat file,
f1
,f2
,f3
, atauf4
. Ketika saya menjalankan skrip di atas:Gagal, melaporkan nomor baris plus perintah yang dieksekusi.
sumber
Selain
LINENO
berisi nomor baris saat ini, ada arrayBASH_LINENO
danFUNCNAME
(danBASH_SOURCE
) yang berisi nama fungsi dan nomor baris tempat mereka dipanggil.Jadi Anda bisa melakukan sesuatu seperti ini:
Menjalankan itu akan mencetak
Jika Anda menggunakan
set -e
, atautrap ... ERR
untuk secara otomatis mendeteksi kesalahan, perhatikan bahwa mereka memiliki beberapa peringatan. Ini juga lebih sulit untuk memasukkan deskripsi tentang apa yang dilakukan skrip pada saat itu (seperti yang Anda lakukan dalam contoh Anda), meskipun itu mungkin lebih bermanfaat bagi pengguna biasa daripada hanya nomor baris.Lihat misalnya ini untuk masalah dengan
set -e
dan lainnya:sumber
Bash memiliki variabel bawaan
$LINENO
yang digantikan oleh nomor baris saat ini ketika dalam sebuah pernyataan, jadi Anda bisa melakukannyaAnda juga dapat mencoba menggunakan
trap ... ERR
yang berjalan saat perintah gagal (jika hasilnya tidak diuji). Misalnya:Kemudian jika perintah seperti
cp $file1 $file2
gagal Anda akan mendapatkan pesan kesalahan dengan nomor baris dan keluar. Anda juga akan menemukan perintah dalam kesalahan dalam variabel$BASH_COMMAND
(meskipun tidak ada pengalihan, dll.).sumber