单独重定向和重新组合 stderr/stdout,而不会丢失顺序

2024-10-17 08:46:00
admin
原创
304
摘要:问题描述:我想要执行一个命令并希望重定向 stderr 和 stdout,如下所示:stderr 和 stdout -> 应仅写入 logs.log 文件,同时保持顺序stderr -> 应该打印到 SCREEN 并写入 errors.log到目前为止,我可以将它们重定向到屏幕和文件 log.tx...

问题描述:

我想要执行一个命令并希望重定向 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

因为我们正在关闭输出文件名(stdoutstderr),所以这些名称需要保持不变才能使上述代码正常工作——可以使用任何所需的临时目录。


显然,您实际上不应该做任何这些。更新您的程序以支持其原生语言中可用的任何日志记录基础结构(Java 中的 Log4j、Python 日志记录模块等),以便明确配置其日志记录。

解决方案 2:

这将帮助你达到大部分目标:

your_command 2> >(tee -a logs.log errors.log) 1>>logs.log

但我不认为您能够准确地保留 logs.log 文件中输出的顺序。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用