個々のコマンドにbashフラグを設定する方法はありますか?

個々のコマンドにbashフラグを設定する方法はありますか?

これを行うより良い方法はありますか?

set -x; ls; set +x
# rest of the script

答え1

表示される状況には次のものがあります。

( set -x; ls )

このset操作はサブシェル内のローカル環境を変更しますが、サブシェルの外側の環境は変更しません。

サブシェルは、変数値などの親環境のどれも変更できません。

また、コードはxtrace最後に無条件にシェルオプションを設定解除します(つまり、呼び出しスクリプトでもそのオプションをオフにします)、サブシェルを使用すると(上記のように)アクティブかどうかにかかわらず、最初からbash -x元の設定を維持します。set -x

関連:

答え2

バージョン4.4以降、最初のオプションセットのオプション(setオプションなしで//に設定されているオプションとは逆のオプションセット)をローカルオプションset -oとしてそのまま使用できます(現在有効なオプションセットを記録する特殊引数)。関数として) したがって、次の関数を定義できます。shopt -oshopt-olocal -$-

xtrace() {
  local -
  set -o xtrace
  "$@"
}

そして電話:

xtrace ls

xtraceこの関数のコンテキスト内でコマンドが呼び出されるため、期待どおりに機能しませんxtrace returnxtrace typeset varxtrace shift

PS4関数でローカルに定義することもできます。

xtrace() {
  local - PS4='xtrace: running '
  set -o xtrace
  "$@"
}
bash-5.2$ xtrace echo "hello world"
xtrace: running echo 'hello world'
hello world

に対応する構文はzsh次のとおりです。

xtrace() {
  set -o localoptions -o xtrace
  local PS4='...'
  "$@"
}

答え3

主に「の意味によって異なります。より良いものたとえば、サブシェルを使用できます。

( set -x; ls )

答え4

( ... )フラグを追加する代わりに、コマンドを使用して-x新しいシェルを呼び出すこともできます。

bash -x -c 'ls'

これは、現在の環境とは異なるシェルを使用したい場合に便利です。

関連情報