Shell

zsh 中函式的呼叫上下文:相當於 bash caller

  • July 3, 2018

在 bash 中,我可以寫:

caller 0

並接收呼叫者上下文的:

  • 電話號碼
  • 功能
  • 腳本名稱

這對於調試非常有用。鑑於:

yelp () { caller 0; }

然後我可以寫信yelp看看正在到達哪些程式碼行。

我可以實現caller 0bash

echo "${BASH_LINENO[0]} ${FUNCNAME[1]} ${BASH_SOURCE[1]"

如何獲得與中相同的caller 0輸出zsh

我認為沒有等效的內置命令,但是可以使用zsh/Parameter 模組中這四個變數的某種組合:

funcfiletrace

此數組包含呼叫目前函式、源文件或(如果 EVAL_LINENO已設置)eval命令的點的絕對行號和相應的文件名。該數組的長度與funcsourcetraceand相同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. 還顯示了源文件的呼叫者;呼叫者是執行sourceor ’ .’ 命令的點。

比較:

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

引用自:https://unix.stackexchange.com/questions/453144