17

関数が呼び出されたファイルと行番号を見つける方法を見つけようとしています。関数は、私のスクリプトによって供給されているライブラリ ファイルにあります。

ファイル1:

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

ファイル2:

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

目的の出力: $: file1:Line 2: エラー: 何かをしていません

関数呼び出しはすでに多くのファイルで何度も発生しているため、それを変更せずにこれを行う方法を見つけようとしています。

以前は、 warn_me 関数はそれを使用するすべてのファイルで定義されていましたが、これは次のように処理されていました。

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

3 に答える 3

16

あなたはそれを探してcallerいるようです。

$ cat h.sh 
#! /bin/bash
function warn_me() {
  echo "$@"
  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
于 2012-06-18T21:19:20.727 に答える
11

@nosid と @Wrikken に触発されて、現在のスタック トレースを $STACK という変数に入れる小さな関数を書きました。エラーが発生した場所をユーザーに出力すると便利な場合があります。残念なことに、bash には組み込みの printStackTrace がありません。

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}"
}

更新: タイプミスを修正し、エラー メッセージ パラメーターを追加しました。したがって、関数の最初のパラメーターは、スタック トレースに追加されるエラー メッセージです。ところで、スクリプトがbashの stdin を指定した場合 (ほとんどの場合、悪い考えです)、最初の位置が失われます。必要に応じて、forループ内で に変更しi<$stack_size + 1ます。しかし、私が言ったように、スクリプトを bash の stdin にフィードするのは得策ではありません。その理由は次のとおりです。

更新 2: これに関する古い回答があることがわかりました。更新されたバージョンのコードを 1 か所に保管することをお勧めします。そこで要点を作ることにしました。要旨の改善を遠慮なく提案してください。変更が発生した場合は、この回答を最新の状態に保つように努めますが、保証はできません。

于 2013-07-18T21:20:10.857 に答える
9

この目的で使用できる配列変数は3つあります。

  • FUNCNAME
  • BASH_SOURCE
  • BASH_LINENO

詳細については、次の回答を参照してください。

于 2012-06-18T21:18:10.490 に答える