可以模板/覆盖 STDOUT 吗?

可以模板/覆盖 STDOUT 吗?

我正在调试调用堆栈并简单地echo从各个文件输出语句。平面日志变得有点难以理解,所以我很好奇嵌套输出的最佳方法是什么。

我认为如果我可以重载 STDOUT 流,则将环境变量设置为制表符数量或作为前缀空格/制表符字符串可能是最简单的选择。基本上,如果我可以做一些类似STDOUT="$TABS$STDOUT"在输出流开头保留堆叠制表符的事情,那就太好了。

但我不确定是否可以覆盖流?例如,如果我想在每一行前面加上连字符+空格,这可能吗?

这样:

echo foo
echo bar
echo foobar

生产:

- foo
- bar
- foobar

  1. 可以模板化 STDOUT 吗?
  2. 嵌套输出的建议方法是什么,而无需修改可能调用的许多不同脚本中的所有echo/语句?printf

答案1

如果您不介意合并 stdout 和 stderr,可能最简单的事情是使用标志运行,-x该标志使 bash 打印每个命令,因为它使用前缀(例如+++来自嵌套级别的字符数)执行。然后,您可以对输出进行后处理,记住前缀但抑制该行,并将其应用到任何后续的无前缀行,这将是您的 echo 或 printf。

例如,采用一个小的阶乘脚本myprog

#!/bin/bash
f(){
        local i=$1
        if [[ "$i" > 1 ]]
        then        echo $((i*$(f $((i-1)))))
        else        echo $i
        fi
        echo "my debug info $i" >&2
}
echo "factorial ${1?} is $(f $1)"

运行它

 bash -x myprog 4  |&
 awk '/^+/{ indent=$1; next }
          { print indent " " $0 }'

给你

+++++ my debug info 1
++++ my debug info 2
+++ my debug info 3
++ my debug info 4
+ factorial 4 is 24

当然,只需PS4使用-x.例如

PS4='+ ${BASH_SOURCE}:${LINENO}: ${FUNCNAME[0]} - [${SHLVL},${BASH_SUBSHELL}, $?]     ' 

给你:

++ myprog:10: main - [2,1, 0]     f 4
++ myprog:3: f - [2,1, 0]     local i=4
++ myprog:4: f - [2,1, 0]     [[ 4 > 1 ]]
+++ myprog:5: f - [2,2, 0]     f 3
+++ myprog:3: f - [2,2, 0]     local i=3
+++ myprog:4: f - [2,2, 0]     [[ 3 > 1 ]]
++++ myprog:5: f - [2,3, 0]     f 2
++++ myprog:3: f - [2,3, 0]     local i=2
++++ myprog:4: f - [2,3, 0]     [[ 2 > 1 ]]
...

相关内容