zsh 中函式的呼叫上下文:相當於 bash caller
在 bash 中,我可以寫:
caller 0
並接收呼叫者上下文的:
- 電話號碼
- 功能
- 腳本名稱
這對於調試非常有用。鑑於:
yelp () { caller 0; }
然後我可以寫信
yelp
看看正在到達哪些程式碼行。我可以實現
caller 0
為bash
:echo "${BASH_LINENO[0]} ${FUNCNAME[1]} ${BASH_SOURCE[1]"
如何獲得與中相同的
caller 0
輸出zsh
?
我認為沒有等效的內置命令,但是可以使用zsh/Parameter 模組中這四個變數的某種組合:
funcfiletrace
此數組包含呼叫目前函式、源文件或(如果
EVAL_LINENO
已設置)eval
命令的點的絕對行號和相應的文件名。該數組的長度與funcsourcetrace
and相同functrace
,但不同之處在於funcsourcetrace
行和文件是呼叫點,而不是定義點,不同之處functrace
在於所有值都是文件中的絕對行號,而不是相對於函式的開始,如果有的話。funcsourcetrace
該數組包含定義目前正在執行的函式、源文件和(如果
EVAL_LINENO
已設置)命令的點的文件名和行號。eval
行號是 ’function name
’ 或 ’name ()
’ 開始的行。在自動載入函式的情況下,行號報告為零。每個元素的格式是filename:lineno
.對於從原生 zsh 格式的文件中自動載入的函式,其中只有函式的主體出現在文件中,或者對於已由
source
或 ’.
’ 內置函式執行的文件,跟踪資訊顯示為filename:0
,因為整個文件是定義。載入函式時,源文件名被解析為絕對路徑,否則解析到它的路徑。大多數使用者會對
funcfiletrace
數組中的資訊感興趣。funcstack
該數組包含函式、源文件和(如果
EVAL_LINENO
已設置)eval
命令的名稱。目前正在執行。第一個元素是使用參數的函式的名稱。標準 shell 數組
zsh_eval_context
可用於確定在每個深度執行的 shell 構造的類型:但是請注意,這是相反的順序,最近的項目在最後,並且更詳細,例如包括一個條目頂層,以互動方式或從腳本執行的主 shell 程式碼,它不存在於$funcstack
.functrace
該數組包含與目前正在執行的函式相對應的呼叫者的名稱和行號。每個元素的格式是
name:lineno
. 還顯示了源文件的呼叫者;呼叫者是執行source
or ’.
’ 命令的點。比較:
foo.bash
:#! /bin/bash yelp() { caller 0 } foo () { yelp } foo
foo.zsh
:#! /bin/zsh yelp() { print -l -- $funcfiletrace - $funcsourcetrace - $funcstack - $functrace } foo () { yelp } foo
結果:
$ bash foo.bash 7 foo foo.bash $ zsh foo.zsh foo.zsh:7 foo.zsh:10 - foo.zsh:2 foo.zsh:6 - yelp foo - foo:1 foo.zsh:10
因此,對應的值在
${funcfiletrace[1]}
和中${funcstack[-1]}
。修改yelp
為:yelp() { print -- $funcfiletrace[1] $funcstack[-1] }
輸出是:
foo.zsh:7 foo
這與 bash 非常接近
7 foo foo.bash