如何判断当前正在执行的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

Answers:


15

可以bash在命令行上传递的许多标志是set标志。set是内置的shell,可以在运行时切换这些标志。例如,调用脚本bash -x foo.sh的方式与set -x在脚本顶部进行的操作基本相同。

知道set是负责此操作的内置Shell使我们知道在哪里看。现在我们可以做得到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* ]]用于模式匹配。
glenn jackman 2014年

1
或者您可以使用标准case $- in *x*) ... ;; *) ... ;; esac。知道这种case对可移植脚本的使用很有用,现在我知道了,我发现记住这一点比记住“如果是bash特定的,则为[[else case” 要容易得多。
hvd

好的,那么整个注释系列都可以删除。
l0b0

$-输出hB。什么的-h-B标志/参数呢?在bash手册页中看不到。
Dan Dascalescu 2014年

3

set -oxtrace on如果-x使用,将输出,否则xtrace off


2

尽管@Patrick的答案是“正确的”答案,但是您也可以只将参数或导出的变量传递到子脚本中,告诉其操作-就像打开跟踪一样。

这样做的缺点是(我相信)您必须将其重新导出到要输入的每个脚本级别。

它的优点是能够选择性地跟踪(或影响)您需要从中进行输出/修改的行为的脚本,以减少多余的输出等。例如,对于调用脚本和仍然在被调用的脚本中打开。这不是一个全有或全无的主张。

不属于您的问题,但与以下内容有关:

我有时会定义一个像

E=""
E="echo "

要么

E=""
E=": "

并在多个语句中使用它,例如

"${E}" rsync ...

或者,仅针对第二种变化,

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

然后,当我想运行命令时,我只是将第二个定义注释掉。您也可以将此技术与参数或导出变量一起使用。

无论使用哪种方法,都必须当心复合语句,因为只能保证该方法对复合列表中的第一个语句起作用。


1

您可以获取进程的PID,然后使用ps检查进程表以查看其参数。


您可以通过以下方式获取流程的PID:$$
Paul Calabro 2014年

2
我一般认为这不是一个好主意,因为如果-x在脚本中设置了,则不会在ps输出中显示它。而且该解决方案仍然是低效的。
vinc17

这是一个公平的论点。我实际上不知道$-变量。这似乎是解决此问题的更好方法。
Paul Calabro 2014年

1
还有set -o我提出的解决方案。它也适用于没有相关标志(如)的选项-x
vinc17
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.