2012-06-18 30 views
9

Tôi đang cố gắng tìm một cách để tìm ra tệp và số dòng mà hàm được gọi từ đó. Hàm này nằm trong tệp thư viện đang được tập lệnh của tôi cung cấp.Bash: Tìm số dòng của cuộc gọi hàm từ tìm nguồn cung ứng tập tin

file1:

$source file2 
$warn_me "Error: You didn't do something" 

file2:

$function warn_me() { 
$ message=???? 
$ echo ${message} 
$} 

Output mong muốn:$: file1: Dòng 2: Lỗi: Bạn không làm điều gì đó

Dấu chấm câu cuộc gọi ion đã xảy ra nhiều lần trong nhiều tệp nên tôi đang cố gắng tìm cách để làm điều này mà không thay đổi điều đó.

Trước đây chức năng warn_me được định nghĩa trong mỗi tập tin mà sử dụng nó và điều này đã được đưa về chăm sóc như vậy:

$local message="$BASH_SOURCE:(""${BASH_LINENO}): ""$*" 

Trả lời

10

Bạn đang tìm kiếm caller vẻ bề ngoài.

$ cat h.sh 
#! /bin/bash 
function warn_me() { 
    echo "[email protected]" 
    caller 
} 
$ cat g.sh 
#!/bin/bash 
source h.sh 
warn_me "Error: You didn't do something" 
$ . g.sh 
Error: You didn't do something 
3 g.sh 
+1

Cảm ơn, tôi đã thay thế dòng bằng: $ local message = "$ BASH_SOURCE [1] :(" "$ {BASH_LINENO}):" "$ *" – spizzak

6

Lấy cảm hứng từ @nosid và @Wrikken Tôi đã viết một chức năng nhỏ để đặt stack trace hiện tại vào một biến gọi là $ STACK. Nó có thể hữu ích để đầu ra cho người dùng vị trí một số lỗi đã xảy ra. Bash quá xấu không có printStackTrace tích hợp ... Hy vọng ai đó có thể thấy nó tiện dụng trong các dự án của họ.

function get_stack() { 
    STACK="" 
    local i message="${1:-""}" 
    local stack_size=${#FUNCNAME[@]} 
    # to avoid noise we start with 1 to skip the get_stack function 
    for ((i=1; i<$stack_size; i++)); do 
     local func="${FUNCNAME[$i]}" 
     [ x$func = x ] && func=MAIN 
     local linen="${BASH_LINENO[$((i - 1))]}" 
     local src="${BASH_SOURCE[$i]}" 
     [ x"$src" = x ] && src=non_file_source 

     STACK+=$'\n'" at: "$func" "$src" "$linen 
    done 
    STACK="${message}${STACK}" 
} 

Cập nhật: Tôi sửa lỗi đánh máy và thêm thông số lỗi. Vì vậy, tham số đầu tiên của hàm là một thông báo lỗi được thêm vào dấu vết ngăn xếp. btw nếu kịch bản của bạn được cung cấp trên stdin của bash (một ý tưởng tồi trong hầu hết các trường hợp), thì vị trí đầu tiên sẽ bị mất. Nếu cần, sau đó nhập vào vòng lặp for, đổi thành i<$stack_size + 1. Nhưng như tôi đã nói, bạn không nên đưa tập lệnh của mình vào bash`s stdin, here's why.

Cập nhật 2: Tôi thấy mình có một số older answer về việc này. Bạn nên giữ phiên bản cập nhật của mã ở một nơi. Vì vậy, quyết định thực hiện một gist. Vui lòng đề xuất cải tiến cho ý chính. Tôi sẽ cố gắng cập nhật câu trả lời này nếu có bất kỳ thay đổi nào xảy ra nhưng tôi không thể đảm bảo.

Các vấn đề liên quan