单独重定向和重新组合 stderr/stdout,而不会丢失顺序
- 2024-10-17 08:46:00
- admin 原创
- 61
问题描述:
我想要执行一个命令并希望重定向 stderr 和 stdout,如下所示:
stderr 和 stdout -> 应仅写入 logs.log 文件,同时保持顺序
stderr -> 应该打印到 SCREEN 并写入 errors.log
到目前为止,我可以将它们重定向到屏幕和文件 log.txt,如下所示:
command 2>&1 | tee logs.log
但以上并不是我需要的。
再次更清楚地说明需要什么结果。
执行命令后,我需要在屏幕上仅看到 stderr 的结果,我需要有一个名为 errors.log 的文件,其中包含 stderr,并且我需要有另一个名为 logs.log 的文件,其中包含 stdout 和 stderr 的结果,按照它们创建的原始顺序。
解决方案 1:
在没有一些丑陋的黑客手段的情况下,在执行单独的重定向时保持完美的顺序甚至在理论上都是不可能的。只有在直接写入同一文件(在 O_APPEND 模式下)时,顺序才会保留;只要您将类似的东西放在tee
一个进程中,而不放在另一个进程中,顺序保证就会消失,如果不保留有关以何种顺序调用哪些系统调用的信息,就无法检索到顺序保证。
那么,这种黑客行为会是什么样子的呢?它可能看起来像这样:
# eat our initialization time *before* we start the background process
sudo sysdig-probe-loader
# now, start monitoring syscalls made by children of this shell that write to fd 1 or 2
# ...funnel content into our logs.log file
sudo sysdig -s 32768 -b -p '%evt.buffer' \n "proc.apid=$$ and evt.type=write and (fd.num=1 or fd.num=2)" \n > >(base64 -i -d >logs.log) \n & sysdig_pid=$!
# Run your-program, with stderr going both to console and to errors.log
./your-program >/dev/null 2> >(tee errors.log)
话虽如此,这仍然是丑陋的黑客行为:它只捕获直接写入 FD 1 和 2 的写入,并且不跟踪可能发生的任何进一步重定向。(这可以通过执行对 FIFO 的写入并使用 sysdig 跟踪对这些 FIFO 的写入来改进;这样fdup()
,类似的操作就会按预期工作;但以上内容足以证明这一概念)。
明确分开处理
在这里我们演示了如何使用它来仅为 stderr 着色,并且保持 stdout 不变 - 通过告诉sysdig
生成 JSON 流作为输出,然后对其进行迭代:
exec {colorizer_fd}> >(
jq --unbuffered --arg startColor "$(tput setaf 1)" --arg endColor "$(tput sgr0)" -r '
if .["fd.filename"] == "stdout" then
("STDOUT: " + .["evt.buffer"])
else
("STDERR: " + $startColor + .["evt.buffer"] + $endColor)
end
'
)
sudo sysdig -s 32768 -j -p '%fd.filename %evt.buffer' \n "proc.apid=$$ and evt.type=write and proc.name != jq and (fd.num=1 or fd.num=2)" \n >&$colorizer_fd \n & sysdig_pid=$!
# Run your-program, with stdout and stderr going to two separately-named destinations
./your-program >stdout 2>stderr
因为我们正在关闭输出文件名(stdout
和stderr
),所以这些名称需要保持不变才能使上述代码正常工作——可以使用任何所需的临时目录。
显然,您实际上不应该做任何这些。更新您的程序以支持其原生语言中可用的任何日志记录基础结构(Java 中的 Log4j、Python 日志记录模块等),以便明确配置其日志记录。
解决方案 2:
这将帮助你达到大部分目标:
your_command 2> >(tee -a logs.log errors.log) 1>>logs.log
但我不认为您能够准确地保留 logs.log 文件中输出的顺序。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件