回答:
同等の組み込みコマンドはないと思いますが、zsh / Parameterモジュールからのこれらの4つの変数のいくつかの組み合わせを使用できます。
funcfiletrace
この配列には、現在の関数、ソースファイル、または(
EVAL_LINENO
設定されている場合)eval
コマンドが呼び出されたポイントの絶対行番号と対応するファイル名 が含まれます。配列は同じ長さであるfuncsourcetrace
とfunctrace
、しかしと異なるfuncsourcetrace
では、ラインとファイルから呼び出し、定義ではない点、及び異なる点であることをfunctrace
すべての値は、絶対行番号がファイルにあることに対してではなく、中関数の開始(ある場合)。funcsourcetrace
この配列には、 現在実行されている関数、ソースファイル、および(
EVAL_LINENO
設定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
muruの答えに基づいて、私は両方で機能する次の関数を実装しました{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