Bashでは、次のように書くことができます。
caller 0
そして受け取った訪問者状況別:
- 電話番号
- 機能
- スクリプト名
これはデバッグに非常に便利です。一方:
yelp () { caller 0; }
yelp
その後、どのコード行に到達したかを確認するために書くことができます。
caller 0
次のように実装できますbash
。
echo "${BASH_LINENO[0]} ${FUNCNAME[1]} ${BASH_SOURCE[1]"
caller 0
で同じ出力をどのように取得できますかzsh
?
答え1
内臓はないようです。注文する同じですが、これら4つの変数のいくつかの組み合わせzsh/パラメータモジュール以下を使用できます。
funcfiletrace
EVAL_LINENO
この配列には、現在の関数、ソースファイル、または(設定されている場合)コマンドが呼び出された場所の絶対行番号とそのファイル名が含まれますeval
。この配列は長funcsourcetrace
さと長さは同じですfunctrace
がfuncsourcetrace
、行とファイルが定義点ではなく呼び出し点である点が異なり、functrace
すべての値が関数の開始に相対的なものではなく、ファイルの絶対行番号である点が異なります。funcsourcetrace
この配列には、現在実行中の関数、ソースファイル、および(設定されている場合)コマンドを定義するポイントのファイル名と行番号が含まれています
EVAL_LINENO
。行番号は、""または""で始まる行です。自動ロードされた関数の場合、行番号は0として報告されます。各要素の形式は次のとおりです。eval
function name
name ()
filename:lineno
デフォルトのzsh形式(ファイルに関数の本文のみが表示されます)のファイルから自動的にロードされる関数または組み込み関数、または「」によって
source
実行されたファイルの場合、トレース情報が表示されます。定義されています。関数をロードすると、ソースファイル名は絶対パスで解決され、それ以外の場合はそのパスが解決されます。.
filename:0
ほとんどのユーザーは配列の情報に興味があります
funcfiletrace
。funcstack
配列には、関数名、ソースファイル、および(
EVAL_LINENO
設定されている場合)eval
コマンドが含まれます。現在実行中です。最初の要素は、このパラメーターを使用する関数の名前です。標準シェル配列を
zsh_eval_context
使用して、各深度で実行されるシェル構成のタイプを決定できます。ただし、順序が反対であるため、最後の項目は最新のものであり、より詳細な項目です(たとえば、最上位の項目を含む)。メインシェルコードを対話的に実行するか、スクリプトで実行する場合$funcstack
。functrace
この配列には、現在実行中の関数に対応する呼び出し元の名前と行番号が含まれています。各要素の形式はです
name:lineno
。また、ソースファイルの呼び出し元は、source
'' コマンドが実行されるポイントです。.
比較する:
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
答え2
に基づいてムルの答え、両方で機能する次の機能を実装しました{ba,z}sh
。
$ cat yelp
#!/bin/zsh
# Say the file, line number and optional message for debugging
# Inspired by bash's `caller` builtin
# Thanks to https://unix.stackexchange.com/a/453153/143394
function yelp () {
# shellcheck disable=SC2154 # undeclared zsh variables in bash
if [[ $BASH_VERSION ]]; then
local file=${BASH_SOURCE[1]} func=${FUNCNAME[1]} line=${BASH_LINENO[0]}
else # zsh
emulate -L zsh # because we may be sourced by zsh `emulate bash -c`
# $funcfiletrace has format: file:line
local file=${funcfiletrace[1]%:*} line=${funcfiletrace[1]##*:}
local func=${funcstack[2]}
[[ $func =~ / ]] && func=source # $func may be filename. Use bash behaviour
fi
echo "${file##*/}:$func:$line $*" > /dev/tty
}
foo () { yelp; }
yelp
foo
出力は次のとおりです
$ ./yelp
yelp::20
yelp:foo:19