私が読んでいる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
私は呼び出しfoo
とfoo
呼び出しのために最大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の定義によると、これは次のとおりですfoo
。bar
baz
$ 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プロンプトに追加することも考慮する必要がありますLINENO
。BASH_SOURCE
答え2
間接アドレッシングは、観察された機能とは無関係で、eval
次の例に示すようにです。
#!/usr/bin/env bash
set -x
echo 1
eval "echo 2"
eval 'eval "echo 3"'
これは次のようなものを解放する必要があります
+ echo 1
1
+ eval 'echo 2'
++ echo 2
2
+ eval 'eval "echo 3"'
++ eval 'echo 3'
+++ echo 3
3
そしてmuruが指摘したように、ソースファイルも提供されます。
$ cat code
echo help
source code
$ bash -x code
control+がc準備されて準備ができていることを願っています...