bashの$ PS4 - GNUドキュメントに記載されている「間接レベル」の動作を再現する方法は?

bashの$ PS4 - GNUドキュメントに記載されている「間接レベル」の動作を再現する方法は?

私が読んでいるGNUドキュメント、私は次の文が正義の一部だと思いますPS4

拡張値の最初の文字は、複数レベルの間接参照を表すために必要なだけコピーされます。デフォルトは「+」です。

+私はこれを私のコードの各抽象化レベルのシンボルを見ることになるという意味に解釈します。私はこの動作を私のシェルで再現したかったので、次のコードを書きました。

#!/usr/bin/env bash

function baz() {
  echo "inside baz"
}

function foo() {
  echo "inside foo";
  baz;
}

function bar() {
  echo "inside bar";
  foo;
}

set -x;

bar;

bar私は呼び出しfoofoo呼び出しのために最大3つのレベルの間接参照を持つことを期待しているので、次のようなbaz(または同様の)出力が表示されると思います。

+ bar
+ echo 'inside bar'
inside bar
++ foo
++ echo 'inside foo'
inside foo
+++ baz
+++ echo 'inside baz'
inside baz

しかし、私が見たことはそうではありませんでした。代わりに私は次を見る:

+ bar
+ echo 'inside bar'
inside bar
+ foo
+ echo 'inside foo'
inside foo
+ baz
+ echo 'inside baz'
inside baz

この文脈で「間接レベル」が何を意味するのか誤解しているのでしょうか、それともそのレベルの間接レベルを正しく再現できないのでしょうか?

ベストアンサー1

現在承認されている回答が示すように、レベルは評価と調達を通じて増加したネストレベルに関連しています。コマンドの置き換えによって増やすこともできます。

PS4='+ '
echo hello > world
set -x
wc -l $(ls -tc | head -1)

与えられた

++ ls -tc
++ head -1
+ wc -l world
1 world

関数の深さに興味がある場合は、配列を使用できますFUNCNAME。例えば

PS4='+ ${_plus:0:${#FUNCNAME[@]}}${FUNCNAME[0]} '
_plus='================='
bar

仕組みは次のとおりです。${#FUNCNAME[@]} 配列の要素数に拡張されますFUNCNAME。現在呼び出されている各関数には配列の要素があるため、これは関数の深さです。その後、この値は最初のN文字を選択し$_plusて一連の記号に設定するために使用されます=。文字数は$_plus妥協です。関数のネストを表示するのに十分なコンテンツが必要ですが、ネストが深い場合(再帰関数がある可能性がある)、プロンプトがばかげて長くなることも避けたいと思います。現在の表示機能が追加されました${FUNCNAME[0]}$FUNCNAME配列の最上位要素だけを参照することも可能ですが、常に配列を配列に、スカラーをスカラーでアクセスするとより明確になります。

OPの定義によると、これは次のとおりですfoobarbaz

$ bar
+  bar
+ =bar echo 'inside bar'
inside bar
+ =bar foo
+ ==foo echo 'inside foo'
inside foo
+ ==foo baz
+ ===baz echo 'inside baz'
inside baz

したがって、+行の先頭はeval / source / command代替ネストレベルを表し、等号は関数ネストレベルを表し、次に現在属している関数名がわかります。

PS4プロンプトに追加することも考慮する必要がありますLINENOBASH_SOURCE

おすすめ記事