我正在使用
set -x
在 shell 脚本中实现调试标志 A.sh
:如果我调用 A.sh -d
,-d
标志将导致 set -x
被调用。
在 A.sh
中执行的每一行都将被打印到 stderr,带有 +
前缀。到目前为止一切顺利。
此时,我正在编写一个具有相同特征的脚本
B.sh
:B.sh -d
还将打印带有 +
前缀的每一行。
我想从
A.sh
内部调用 B.sh
,并传播 -d
标志。
这里我们遇到了问题:无法区分 A.sh
发出的命令和 B.sh
发出的命令,因为两者都以 +
开头。
一个可能的解决方案是从
A.sh
内部调用 B.sh
,如下所示:
propagate_options='-d'
A.sh $propagate_options 2> >(sed 's/^\+/++/')
但这有点难看,而且可能不太便携。 还有更好的主意吗?
在 chepner 的想法之后,我简单地实现了调试模式,如下所示:
PS4="+$(basename $0): "
propagate_options='-d'
set -x
这使得更容易理解什么的输出是什么......
set -x
使用 PS4
的当前值作为每行输出的标记。
PS4
当执行跟踪(set -x)正在执行时 交互式 shell,在执行跟踪中的每一行之前,该值 该变量应进行参数扩展并写入 到标准错误。默认值为“+”。本卷的 POSIX.1-2008 指定变量仅对系统的影响 支持用户可移植性实用程序选项。
最“自然”的方法是获取文件源。 shell 会识别这一点,并且由于您正在获取源代码,因此会传播调试。重点 - 每个源都会在开头自动添加一个“+”。这是
a.bash
:
#!/bin/bash
set -x
echo 1
echo 2
. b.bash
和
b.bash
:
#!/bin/bash
echo a
echo b
运行
a.bash
结果:
+ echo 1
1
+ echo 2
2
+ . b.bash
++ echo a
a
++ echo b
b
请注意
b
命令有两个 ++
。
PS4="+$(basename $0): "
我用的是我在某处找到的这个:
exec {BASH_XTRACEFD}>>"path/trace.dbg"
set -x
PS4='[$(basename ${BASH_SOURCE[0]:-inherited}):${LINENO}:${FUNCNAME[0]:-main}] '