2013-06-28 9 views
6

私はいくつかの値をループし、各値に長いコマンドラインを実行するシェルスクリプトを書いています。これらのコマンドを途中で印刷したいのですが、makeと同じようにメークファイルを実行します。私はそれらを実行する前にすべてのコマンドを単に "エコー"することができることを知っていますが、それは気持ちが悪いと感じます。だから私が代わりにset -xと同様のメカニズムで探しています:シェルスクリプトでxtraceをサイレントに無効にする方法はありますか?

#!/bin/sh 

for value in a long list of values 
do 
    set -v 
    touch $value # imagine a complicated invocation here 
    set +v 
done 

私の問題は、次のとおりです。各繰り返しで、プリントアウトinterrestingラインがあるが、また、set +xラインだけでなくだけでなく。それをどうにかして防ぐことはできますか?そうでない場合は、どのような回避策をお勧めしますか?

PS:上のMWEはshを使用していますが、役立つ場合はbashzshもインストールされています。

+1

FYI [それが印刷されることなくバッシュセット+ X](http://stackoverflow.com/questions/13195655/bash-set-x-without-it-being-printed) – Beetle

答えて

6

サンドボックスに:もちろん

(set -x; do_thing_you_want_traced) 

、変数またはそのサブシェルで行われた環境への変更が失われます。

本当に気にしているのであれば、を使用してそれを関数に継承させるためのDEBUGトラップを使用して、set -x相当の機能を実装することもできます。例えば

は、bashを使用する場合:

trap_fn() { 
    [[ $DEBUG && $BASH_COMMAND != "unset DEBUG" ]] && \ 
    printf "[%s:%s] %s\n" "$BASH_SOURCE" "$LINENO" "$BASH_COMMAND" 
    return 0 # do not block execution in extdebug mode 
} 
trap trap_fn DEBUG 

DEBUG=1 
# ...do something you want traced... 
unset DEBUG 

BASH_COMMANDは(DEBUGトラップとして行うことができる)set -xの完全に等価ではない発光、前記;たとえば、展開後の値は表示されません。

+0

お返事ありがとうございました!私はコマンドの変数で遊んでいるわけではありません(実際はちょっと長めの呼び出しです)ので、私はサブシェルのアプローチに行きました。私のニーズに完全に合っています。 – Gyom

+0

wooo、クールなアイデア! :-) –

1

私は

set -x >/dev/null 2>1; echo 1; echo 2; set +x >/dev/null 2>&1 

考えるが、私は、これらの結果によって驚い

+ echo 1 
1 
+ echo 2 
2 
+ 1> /dev/null 2>& 1 

を得ました。 ....しかし、

set -x ; echo 1; echo 2; set +x 
+ echo 1 
1 
+ echo 2 
2 

あなたの要件を満たすようです。私はその唯一の行に各ステートメントを入れたときに、私は同様の結果を見て

IHTH(セット+ Xを除きます)。サブシェルで

+0

の可能性の重複 - BASH_XTRACEFDで上書きされない限り、 'set -x'出力はstderrのみになります。 –

+0

...ところで、走行距離は異なります;私はここでbash 4.2.45(1)で報告された動作を再現できません。 –

+0

@charlesDuffy:私はkshを使っていますが、私はいつもbash(ここ)について読んでいます。詳細をありがとう!皆さんお元気で。 – shellter

1

あなたはシングルラインXTRACEを使用して試してみたい:

function xtrace() { 
    # Print the line as if xtrace was turned on, using perl to filter out 
    # the extra colon character and the following "set +x" line. 
    (
    set -x 
    # Colon is a no-op in bash, so nothing will execute. 
    : "[email protected]" 
    set +x 
) 2>&1 | perl -ne 's/^[+] :/+/ and print' 1>&2 
    # Execute the original line unmolested 
    "[email protected]" 
} 

元のコマンドには、恒等変換の下で同じシェルで実行されます。実行する直前に、引数の非再帰的なxtraceが得られます。これにより、すべての "echo"コマンドの重複コピーでstederrをスパムすることなく、気になるコマンドをxトレースすることができます。

# Example 
for value in $long_list; do 
    computed_value=$(echo "$value" | sed 's/.../...') 
    xtrace some_command -x -y -z $value $computed_value ... 
done 
関連する問題