現在実行中のbashスクリプトがデバッグのために-xで呼び出されたかどうかを確認するにはどうすればよいですか?


11

launch.sh正しい所有者でファイルを作成するために、別のユーザーとして自分自身を実行するスクリプトがあります。最初にスクリプトに渡された場合、この呼び出しに-xを渡したい

if [ `whoami` == "deployuser" ]; then
  ... bunch of commands that need files to be created as deployuser
else
  echo "Respawning myself as the deployment user... #Inception"
  echo "Called with: <$BASH_ARGV>, <$BASH_EXECUTION_STRING>, <$->"
  sudo -u deployuser -H bash $0 "$@"  # How to pass -x here if it was passed to the script initially?
fi

bashデバッグページを読みましたが、元のスクリプトがで起動されたかどうかを示す明確なオプションがないよう-xです。

回答:


15

bashコマンドラインで渡すことができるフラグの多くはsetフラグです。set実行時にこれらのフラグを切り替えることができる組み込みシェルです。たとえば、スクリプトをそのまま呼び出すことbash -x foo.shは、基本的にスクリプトset -xの上部で行うことと同じです。

これsetがシェルの組み込みであることを知っていると、どこを見ればよいかがわかります。これでhelp set、次のことができます。

$ help set
set: set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]
...
      -x  Print commands and their arguments as they are executed.
...
    Using + rather than - causes these flags to be turned off.  The
    flags can also be used upon invocation of the shell.  The current
    set of flags may be found in $-.  The remaining n ARGs are positional
    parameters and are assigned, in order, to $1, $2, .. $n.  If no
    ARGs are given, all shell variables are printed.
...

だから、このことから、私たちはそれが見$-フラグが有効になっているものを教えなければなりません。

$ bash -c 'echo $-'
hBc

$ bash -x -c 'echo $-'
+ echo hxBc
hxBc

だから基本的にはあなたがする必要があるだけです:

if [[ "$-" = *"x"* ]]; then
  echo '`-x` is set'
else
  echo '`-x` is not set'
fi

おまけとして、すべてのフラグをコピーしたい場合は、

bash -$- /other/script.sh

1
[[ $- == *x* ]]パターンマッチングに使用する必要があります。
グレン・ジャックマン、2014

1
または、標準を使用できますcase $- in *x*) ... ;; *) ... ;; esaccase移植可能であることを意図したスクリプトのこの使用法を知っておくと便利です。今ではそれを知っているので、「bash固有の場合は[[、そうでない場合」を覚えるよりも、覚えているだけの方が簡単ですcase
hvd 2014

OK、この一連のコメント全体を削除できます。
l0b0 14

$-出力hB。何ん-h-Bフラグ/引数がですか?その後、bashのmanページを参照しないでください
Dan Dascalescu 2014

3

set -oが使用されているxtrace on場合-xは出力され、そうでない場合は出力されますxtrace off


2

@Patrickの答えは「正しい」ものですが、トレースをオンにするなど、何をすべきかを指示するパラメータまたはエクスポートされた変数を子スクリプトに渡すこともできます。

これには、入力しようとしているスクリプトの各レベルに再エクスポートする必要がある(私はそう思います)と言う欠点があります。

これには、出力/変更された動作が必要なスクリプトのみを選択的にトレース(またはその他の方法で影響)できるという利点があります-無関係な出力などを削減するために。たとえば、呼び出しスクリプトのトレースをオフにして呼び出されたスクリプトでまだオンになっています。それはオール・オア・ナッシングの命題ではありません。

あなたの質問の一部ではありませんが、関連しています:

私は時々次のような変数を定義します

E=""
E="echo "

または

E=""
E=": "

そしてそれを(複数のステートメントで)のように使用します

"${E}" rsync ...

または、第2のバリエーションだけのために、

"${E}" echo "this is a debugging message"

次に、コマンドを実行するときに、2番目の定義をコメント化します。代わりに、この手法をパラメーターまたはエクスポートされた変数で使用することもできます。

これらのいずれかを使用する場合、メソッドは複合リストの最初のステートメントでのみ動作することが保証されているため、複合ステートメントに注意する必要があります。


1

プロセスのPIDを取得し、psを使用してプロセステーブルを調べて、引数が何であるかを確認できます。


次の方法でプロセスのPIDを取得できます:$$
Paul Calabro

2
これが-xスクリプト内で設定された場合、ps出力に表示されないため、これは一般的に良い考えではないと思います。そして、このソリューションはとにかく非効率的です。
vinc17 2014

それは公正な議論です。$-変数については実際には知りませんでした。これはこれを解決するためのより良いアプローチのようです。
ポールカラブロ2014

1
set -o私が提案した解決策もあります。のような関連するフラグがないオプションでも機能するはず-xです。
vinc17 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.