![可以模板/覆盖 STDOUT 吗?](https://linux22.com/image/97192/%E5%8F%AF%E4%BB%A5%E6%A8%A1%E6%9D%BF%2F%E8%A6%86%E7%9B%96%20STDOUT%20%E5%90%97%EF%BC%9F.png)
我正在调试调用堆栈并简单地echo
从各个文件输出语句。平面日志变得有点难以理解,所以我很好奇嵌套输出的最佳方法是什么。
我认为如果我可以重载 STDOUT 流,则将环境变量设置为制表符数量或作为前缀空格/制表符字符串可能是最简单的选择。基本上,如果我可以做一些类似STDOUT="$TABS$STDOUT"
在输出流开头保留堆叠制表符的事情,那就太好了。
但我不确定是否可以覆盖流?例如,如果我想在每一行前面加上连字符+空格,这可能吗?
这样:
echo foo
echo bar
echo foobar
生产:
- foo
- bar
- foobar
- 可以模板化 STDOUT 吗?
- 嵌套输出的建议方法是什么,而无需修改可能调用的许多不同脚本中的所有
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 ]]
...