我想执行一个命令,并想重定向stderr和stdout,如下所示:
stderr和stdout->仅应在保持顺序的同时写入logs.log文件
stderr->应该打印到SCREEN并也写入errors.log
到目前为止,我可以将它们重定向到屏幕和文件log.txt,如下所示:
command 2>&1 | tee logs.log
但是以上不是我所需要的。
为了更清楚地说明结果是什么。
执行命令后,我只需要在屏幕上看到stderr的结果,我需要在stderr中有一个名为errors.log的文件,而在目录中需要有stdout和stderr两者都在其中的结果的另一个名为logs.log的文件。创建它们的原始顺序。
从理论上讲,如果没有一些丑陋的黑客手段,则在执行单独的重定向时保持完美的顺序是不可能的。
仅在直接写入同一文件(在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' \
"proc.apid=$$ and evt.type=write and (fd.num=1 or fd.num=2)" \
> >(base64 -i -d >logs.log) \
& 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和FD
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' \
"proc.apid=$$ and evt.type=write and proc.name != jq and (fd.num=1 or fd.num=2)" \
>&$colorizer_fd \
& 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日志记录模块等)可用的任何日志记录基础结构,以允许对其日志记录进行显式配置。
问题内容: 我在cyberciti.biz的评论中看到了这个有趣的问题。 我发现我什至找不到在sh的单行命令中执行此操作的灵活方法。 到目前为止,我对解决方案的想法是: 但是您会看到,这不是同步的,而且致命的是,它是如此丑陋。 欢迎与您分享这个想法。:) 问题答案: 你要 这里的顺序很重要。假设stdin(fd 0),stdout(fd 1)和stderr(fd 2)最初都连接到tty,因此 首先
我想将stdout和stderr重定向到一个文件,同时保留输出顺序,然后还将stderr显示到屏幕上。我看到很多问题讨论它: https://unix.stackexchange.com/questions/9646/show-only-stderr-on-screen-but-write-both-stdout-and-stderr-to-file https://unix.stackexcha
问题内容: 我想将子进程的stderr输出重定向到stdout。常量应该这样做,不是吗? 然而, 确实 输出了一些东西。为什么会这样,如何在stdout上得到错误消息? 问题答案: 仔细阅读源代码即可得出答案。特别是,该文档在显示以下内容时会产生误导: 表示(…)的特殊值表示标准错误应与标准输出进入同一 句柄 。 由于在求值时stdout设置为“默认”(技术上来说),因此stderr也设置为“默认
很好的一天。我有一系列的命令,我想通过一个函数来执行,这样我就可以得到退出代码并相应地执行控制台输出。话虽如此,我这里有两个问题: 1) 我似乎无法将stderr指向/dev/null。 2) 在执行$1之前,不会显示第一条回显行。直到我运行需要一段时间才能处理的命令,比如在硬盘上搜索文件,我才真正注意到这一点。此外,情况显然是这样,因为输出如下所示: 换句话说,stderr显示在“尝试…$2”之
在 Linux 中,一切都只是文件。这意味着,对于控制台程序: 键盘表示为一个文件,Bash 从中读取你的输入。 显示器表示为一个文件,Bash向输出写入它。 让我们假设,你有一个程序可以计算文件中的行。你可以通过键入wc -l来调用它。现在尝试一下 没有发生什么事吧?它只是卡在那里。错了,它正在等待你的输入。这是它的工作原理: line_counter = 0 while end of file
问题内容: 如何解决在PHP中重定向后丢失会话的问题? 最近,我遇到了一个非常常见的问题,即在重定向后丢失会话。在搜索该网站后,我仍然找不到任何解决方案(尽管这是最接近的解决方案)。 更新资料 我找到了答案,我想将它发布在这里,以帮助遇到同样问题的任何人。 问题答案: 首先,执行以下常规检查: 确保在任何会话被调用之前被调用。因此,一个安全的选择就是将其放在页面的开头,紧接着在开始声明之后,再放在