「bash -x」がこのスクリプトをクラッシュさせるのはなぜですか?

「bash -x」がこのスクリプトをクラッシュさせるのはなぜですか?

特定のコマンドを実行するのにかかる時間を測定するスクリプトがあります。

time「実際の」コマンド、つまりバイナリが必要です/usr/bin/time(bash組み込みには対応するフラグがないためです-f)。

デバッグできる単純化されたスクリプトは次のとおりです。

#!/bin/bash

TIMESEC=$(echo blah | ( /usr/bin/time -f %e grep blah >/dev/null ) 2>&1 | awk -F. '{print $1}')

echo ABC--$TIMESEC--DEF

if [ "$TIMESEC" -eq 0 ] ; then
   echo "we are here!"
fi

「test.sh」として保存し、以下を実行します。

$ bash test.sh
ABC--0--DEF
we are here!

だから動作します。

それでは、bashコマンドラインに「-x」を追加してデバッグしてみましょう。

$ bash -x test.sh
++ echo blah
++ awk -F. '{print $1}'
+ TIMESEC='++ /usr/bin/time -f %e grep blah
0'
+ echo ABC--++ /usr/bin/time -f %e grep blah 0--DEF
ABC--++ /usr/bin/time -f %e grep blah 0--DEF
+ '[' '++ /usr/bin/time -f %e grep blah
0' -eq 0 ']'
test.sh: line 10: [: ++ /usr/bin/time -f %e grep blah
0: integer expression expected

「-x」を使用するとこのスクリプトが中断されますが、「-x」なしでうまく動作するのはなぜですか?

ベストアンサー1

問題は次のようになります。

TIMESEC=$(echo blah | ( /usr/bin/time -f %e grep blah >/dev/null ) 2>&1 | awk -F. '{print $1}')

標準出力に一致するように標準エラーをリダイレクトしています。 bash は標準エラーのトレース・メッセージを作成し (例えば) bash プロセス内の組み込み関数やその他のechoシェル構成を使用します。

次のように変更すると

TIMESEC=$(echo blah | sh -c "( /usr/bin/time -f %e grep blah >/dev/null )" 2>&1 | awk -F. '{print $1}')

これはこの問題を解決し、追跡と作業の間の許容可能な妥協点になる可能性があります。

++ awk -F. '{print $1}'
++ sh -c '( /usr/bin/time -f %e grep blah >/dev/null )'
++ echo blah
+ TIMESEC=0                 
+ echo ABC--0--DEF
ABC--0--DEF
+ '[' 0 -eq 0 ']'
+ echo 'we are here!'
we are here!

おすすめ記事