bash: "-x" エコーから別の行をエスケープします。

bash: "-x" エコーから別の行をエスケープします。

Bashで-xこのオプションを使用すると、単一コマンドのエコーを省略できますか?

出力をできるだけきれいに保ちようとしているので、スクリプトの一部をサブシェルで実行しますset +x。ただし、行set +x自体はまだエコーされ、出力に重要な情報を追加しません。

以前は.batランタイムを使用したecho onとき@。 Bashにも同様のことがありますか?

#!/bin/bash -x

function i_know_what_this_does() {
  (
    set +x
    echo do stuff
  )
}

echo the next-next line still echoes 'set +x', is that avoidable?
i_know_what_this_does
echo and we are back and echoing is back on

上記のコマンドを実行すると、出力は次のようになります。

+ echo the next-next line still echoes 'set +x,' is that 'avoidable?'
the next-next line still echoes set +x, is that avoidable?
+ i_know_what_this_does
+ set +x
do stuff
+ echo and we are back and echoing is back on
and we are back and echoing is back on

答え1

xtrace出力はstderrに移動するため、次にstderrリダイレクトできます/dev/null

i_know_what_this_does() {
  echo do stuff
} 2> /dev/null

関数内で実行されているコマンドのエラーを確認するには、次の手順を実行します。

i_know_what_this_does() (
  { set +x; } 2> /dev/null # silently disable xtrace
  echo do stuff
)

(...)代わりに使用すると、{...}サブシェルを介して関数にローカルスコープが提供されます。bashバージョン4.4では、Almquistシェル(Almquistシェルに似ています)のように、関数のローカルオプションとしてオプション設定をサポートするようになりましたlocal -set -o localoptionszsh

i_know_what_this_does() {
  { local -; set +x; } 2> /dev/null # silently disable xtrace
  echo do stuff
}

4.0から4.3への代替案は、変数をbash使用し、$BASH_XTRACEFD専用ファイル記述子を開くことです。/dev/null

exec 9> /dev/null
set -x
i_know_what_this_does() {
  { local BASH_XTRACEFD=9; } 2> /dev/null # silently disable xtrace
  echo do stuff
}

bashfdを表示する能力が不足しているため実行時に閉じるフラグですが、これはfdを他のコマンドに流す副作用があります。

これも見てくださいlocvar.sh実装されるいくつかの機能が含まれています。地元のPOSIXスクリプトの変数と関数の範囲、およびそれらを生成するためのtrace_fn関数も提供されています。untrace_fnディーデンかどうか。

答え2

set +x印刷する理由は、set -x「実行したいコマンドを印刷して展開して走る前に。したがって、シェルは、何かを印刷しないように指示する行を印刷するまで、ユーザーが何かを印刷したくないことを知っていません。私が知る限り、これが起こるのを防ぐ方法はありません。

答え3

あなたが探していた解決策は次のとおりです。

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.
    : "$@"
    set +x
  ) 2>&1 | perl -ne 's/^[+] :/+/ and print' 1>&2
  # Execute the original line unmolested
  "$@"
}

元のコマンドは、ID変換時に同じシェルで実行されます。実行する前に、パラメータの非再帰的なxtraceを取得してください。これにより、すべての "echo" コマンドのコピーを stederr にスパムとして送信することなく、関心のあるコマンドを xtrace できます。

# Example
echo "About to do something complicated ..."
xtrace do_something_complicated

関連情報