Cách hiển thị số dòng khi thực thi tập lệnh bash


89

Tôi có một tập lệnh thử nghiệm có rất nhiều lệnh và sẽ tạo ra nhiều đầu ra, tôi sử dụng set -xhoặc set -vset -e, vì vậy tập lệnh sẽ dừng khi xảy ra lỗi. Tuy nhiên, vẫn khá khó khăn đối với tôi để xác định dòng nào đã dừng thực thi để xác định vấn đề. Có phương pháp nào có thể xuất ra số dòng của tập lệnh trước khi mỗi dòng được thực thi không? Hoặc xuất số dòng trước khi triển lãm lệnh được tạo ra bởi set -x? Hoặc bất kỳ phương pháp nào có thể giải quyết vấn đề vị trí dòng tập lệnh của tôi sẽ là một trợ giúp tuyệt vời. Cảm ơn.

Câu trả lời:


161

Bạn đề cập rằng bạn đã sử dụng -x. Biến PS4biểu thị giá trị là lời nhắc được in trước khi dòng lệnh được lặp lại khi -xtùy chọn được đặt và mặc định :là dấu cách theo sau.

Bạn có thể thay đổi PS4để phát ra LINENO(Số dòng trong tập lệnh hoặc hàm shell hiện đang thực thi).

Ví dụ: nếu tập lệnh của bạn đọc:

$ cat script
foo=10
echo ${foo}
echo $((2 + 2))

Việc thực thi nó như vậy sẽ in ra các số dòng:

$ 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 cung cấp những thứ cuối cùng PS4sẽ xuất ra mọi thứ bạn có thể cần để theo dõi:

export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'

4
Tôi tự hỏi tại sao không ai đề cập đến điều này cho "Làm thế nào để gỡ lỗi tập lệnh shell?" . Đây là tốt hơn nhiều so chỉecho
Suvarna Pattayil

@VusP Đồng ý, echotốt nhất nên tránh những tuyên bố không cần thiết .
devnull

2
Tôi không thể không cảm thấy rằng -x nên in số dòng. Hoặc, có thể - nx nên bao gồm số dòng. Đối với tôi, đó là một trong những khoảnh khắc "WTF" ...
jww

1
Man, tôi ước gì tôi biết về điều đó PS4 bịa đặt sớm ... Nó sẽ có lưu tôi rất nhiều đau đầu
Niken

2
\033[0;33m+(${BASH_SOURCE}:${LINENO}):\033[0m ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'cho một số màu
Ulysse BN

34

Trong Bash, $LINENOchứa số dòng nơi tập lệnh hiện đang thực thi.

Nếu bạn cần biết số dòng nơi hàm được gọi, hãy thử $BASH_LINENO. Lưu ý rằng biến này là một mảng.

Ví dụ:

#!/bin/bash       

function log() {
    echo "LINENO: ${LINENO}"
    echo "BASH_LINENO: ${BASH_LINENO[*]}"
}

function foo() {
    log "$@"
}

foo "$@"

Xem tại đây để biết chi tiết về các biến Bash.


0

Giải pháp đơn giản (nhưng mạnh mẽ): Đặt echoxung quanh đoạn mã mà bạn cho là nguyên nhân gây ra sự cố và di chuyển echotừng dòng cho đến khi thông báo không xuất hiện nữa trên màn hình - vì tập lệnh đã dừng do lỗi trước đó.

Giải pháp mạnh mẽ hơn nữa: Cài đặt bashdbtrình gỡ lỗi bash và gỡ lỗi từng dòng tập lệnh


2
echoViệc nhập nội dung xung quanh có thể hữu ích trong nhiều trường hợp, nhưng sẽ không thành công khi bạn cố gắng áp dụng nó trong các hàm có đầu ra có ý nghĩa, có thể phân tích cú pháp.
Eliran Malka

1
@EliranMalka Điểm công bằng. Bạn có thể echo để thiết bị lỗi chuẩn trong trường hợp đó:echo "foo" >&2
hek2mgl

1
... người ta nên lặp lại tới stderr trong mọi trường hợp khi mục đích là các thông báo có tính chất chẩn đoán.
Charles Duffy

0

Giải pháp cho trình bao không có LINENO

Trong một kịch bản khá phức tạp, tôi không muốn thấy tất cả các số dòng; thay vì tôi muốn kiểm soát đầu ra.

Xác định một chức năng

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

Sử dụng nó với dấu ngoặc kép như

echo_line_no "this is a simple comment with a line number"

Đầu ra là

16   "this is a simple comment with a line number"

nếu số dòng này trong tệp nguồn là 16.

Điều này về cơ bản trả lời câu hỏi Làm thế nào để hiển thị số dòng khi thực thi tập lệnh bash cho người dùng tro hoặc các trình bao khác mà không có LINENO.

Bạn có muốn thêm gì không?

Chắc chắn rồi. Tại sao bạn cần cái này? Làm thế nào để bạn làm việc với điều này? Bạn có thể làm gì với điều này? Cách tiếp cận đơn giản này có thực sự đủ hoặc hữu ích không? Tại sao bạn lại muốn mày mò với cái này?

Bạn muốn biết thêm? Đọc phản ánh về gỡ lỗi

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.