「set -x」のトレース出力を理解するには?

「set -x」のトレース出力を理解するには?

バッシュマニュアルから

set -x

コマンド、大文字と小文字、選択、および算術コマンドと、その引数または関連する単語のリストを含む単純なコマンドのトレースを印刷します。拡張後実行前。 PS4変数の値が拡張され、結果の値がコマンドおよび拡張引数の前に印刷されます。

  • しかし、印刷された痕跡は正確に拡張後の結果ではなく、実行前の結果であることがわかりました。特に、トレースは引用符が削除された後に行われますが、出力には引用符やバックスラッシュが追加されています。これは、元のコマンドを実行したのと同じ結果を得るために、シェルからコマンドで出力を実行できるように見えます。なぜそんなことですか?

  • それでは、拡張後の実行前の実際の中間解析結果をトレース出力からどのように推論できますか?

たとえば、unset のvar場合

$ echo '$var'   
+ echo '$var'
$var
$ echo "$var"  
+ echo ''

$ echo \$var   
+ echo '$var'
$var
$ echo \'$var\'    # why is the trace print out not: echo \'\'
+ echo ''\'''\'''
''
$ echo \'
+ echo \'
'
$ echo "'"        # why is the trace print out not: echo "'"
+ echo \'
'
$ echo "''"       # why is the trace print out not: echo "''"
+ echo ''\'''\'''
''
$ echo \'\'        # why is the trace print out not: echo \'\'
+ echo ''\'''\'''
''
$ echo \\          # why is the trace print out not: echo \\
+ echo '\'
\

ベストアンサー1

マニュアル引用:

拡張後実行前

あなたは次のように主張します。

しかし、印刷された痕跡は正確に拡張後の結果ではなく、実行前の結果であることがわかりました。

しかし、彼らはそうです。拡張結果は単語リスト。 Bashは引用符を使用して単語のリストを明確に表現します。 bashが印刷することは、引用符を削除しなかった拡張の中間結果ではありません。それ印刷された表現文字列のリストです。

たとえば、トレースが次のような場合

+ cp foo bar qux

それでは、コマンドがcp3つの引数foobarandを取ったのか、qux2つの引数andfoo barを取っquxたのか(たとえば元のコマンドだったからcp "foo bar" qux)、2つの引数fooandを取ったのかbar qux、実際に名前のついたコマンドなのかcp foo bar quxなどがわかる方法ありません。トレースを明確にするために、bashは引用符を使用します。フォローする引用を選択してください。考えられる方法Bashスクリプトでこのコマンドを実行します。

たとえば、トレースは、コマンドが+ echo '$var'1echoつの引数(4文字の文字列)で実行されたことを示します$var。このコマンドを実行する方法はいくつかあります。たとえば、次のようになります。

echo '$var'
echo \$var
echo \$\v\a\r
echo "\$v"\a''''r
echo "$a"               # after running a='$var'

おすすめ記事