web-dev-qa-db-ja.com

スクリプトの外部からbash実行トレース(set -x)を抑制します。

私はこの質問への答えを見つけようとしましたが、今のところ運がありません:

他のスクリプトを実行するスクリプトがあり、それらの他のスクリプトの多くには "set -x"が含まれているため、実行するすべてのコマンドが出力されます。私はそれを取り除きたいのですが、スクリプトのいずれかがエラーメッセージをstderrに送信した場合に情報を保持します。

だから私は単に./script 2>/dev/null

また、他のスクリプトを編集する権限がないため、手動で設定オプションを変更することはできません。

Stderrから別のファイルにすべてを記録し、トレースコマンドを除外することを考えていましたが、もっと簡単な方法があるのでしょうか。

17
human

bash 4.1以降では、次のことができます

_BASH_XTRACEFD=7 ./script.bash 7> /dev/null
_

bashshとして呼び出された場合にも機能します)。

基本的に、bashにデフォルトの2ではなくファイル記述子7のxtrace出力を出力し、そのファイル記述子を_/dev/null_にリダイレクトするように指示しています。 fd番号は任意です。スクリプトで使用されていない2を超えるfdを使用します。このコマンドを入力するシェルがbashまたはyashの場合、9より大きい数値を使用することもできます(シェルによって内部的にファイル記述子が使用されている場合は問題が発生する可能性があります)。

bashスクリプトを呼び出すシェルがzshの場合、次のようにすることもできます。

_(export BASH_XTRACEFD; ./script.bash {BASH_XTRACEFD}> /dev/null)
_

変数に9を超える最初の空きfdが自動的に割り当てられるようにします。

古いバージョンのbashでは、_set -x_(_#! /bin/bash -x_または_set -o xtrace_ではなく)でxtraceがオンになっている場合、別のオプションは、setを、次の場合に何もしないエクスポートされた関数として再定義します。渡された_-x_(ただし、スクリプト(またはスクリプトが呼び出す他のbashスクリプト)がsetを使用して位置パラメータを設定した場合、スクリプトが壊れます)。

お気に入り:

_set()
  case $1 in
    (-x) return 0;;
    (-[!-]|"") builtin set "$@";;
    (*) echo >&2 That was a bad idea, try something else; builtin set "$@";;
  esac

export -f set
./script.bash
_

別のオプションは、すべてのコマンドの前に_$BASH_ENV_を実行する_set +x_ファイルにデバッグトラップを追加することです。

_echo 'trap "{ set +x; } 2>/dev/null" DEBUG' > ~/.no-xtrace
BASH_ENV=~/.no-xtrace ./script.bash
_

ただし、サブシェルで_set -x_を実行すると機能しません。

@ilkkachuが言ったように、ファイルシステム上の任意のフォルダーへの書き込み権限がある場合、少なくともスクリプトのコピーを作成して編集できるはずです。

スクリプトのコピーを作成できる場所がない場合、または元のスクリプトが更新されるたびに新しいコピーを作成して編集することが不都合な場合でも、次のことができる場合があります。

_ bash <(sed 's/set -x/set +x/g' ./script.bash)
_

スクリプトが_$0_または_$BASH_SOURCE_のような特別な変数(スクリプト自体の場所に関連するファイルを検索するなど)を使用する場合、これ(およびコピーアプローチ)は正しく機能しない可能性があります。そのため、_$0_をスクリプトのパスに置き換えるなど、さらに編集が必要になる場合があります...

25

スクリプトなので、あなたはcouldそれらのコピーを作成し、それらを編集します。

それ以外では、出力のフィルタリングは単純に見えるかもしれませんが、明示的にPS4フィルタリングを簡単にするために、単一のプラスよりも変わったものに:

PS4="%%%%" bash script.sh 2>&1 | grep -ve '^%%%%'

(もちろん、これはstdoutとstdinを折りたたみますが、Bashでstderrだけをパイプすると少々煩わしいので、無視します)

5
ilkkachu