bash - 将 stdout 和 stderr 重定向到文件,将 stderr 重定向到屏幕,同时保留输出顺序
问题描述
我想将 stdout 和 stderr 重定向到一个文件,同时保留输出顺序,但同时也将 stderr 显示到屏幕上。我看到很多问题都在讨论它:
- https://unix.stackexchange.com/questions/9646/show-only-stderr-on-screen-but-write-both-stdout-and-stderr-to-file
- https://unix.stackexchange.com/questions/333198/bash-redirect-stderr-to-file-and-stdout-stderr-to-screen
- https://unix.stackexchange.com/questions/364166/redirect-bash-stdoutstderr-to-one-file-and-stderr-to-another-file
- 将 STDOUT 和 STDERR 写入日志文件,同时将 STDERR 写入屏幕
但他们似乎都没有做我想做的事或保持秩序。
我的测试脚本:
#!/bin/bash
echo "1: good" >&1
echo "2: error" >&2
echo "3: error" >&2
echo "4: good" >&1
echo "5: error" >&2
echo "6: good" >&1
echo "7: error" >&2
echo "8: good" >&1
echo "9: error" >&2
到目前为止我所拥有的:
$ ./test.sh 2>&1 > output.log
解决方案
标准 UNIX 语义不允许这样做;仅使用内置在 bash 中或在 POSIX 中指定的工具无法可靠地完成它。
只有当它们发生在同一个目的地时,写入才具有相互关联的保证顺序。一旦您将 stdout 和 stderr 重定向到不同的目的地,操作系统就不再提供对它们执行的写入顺序的保证;当这些写入是针对一个单独的进程(例如tee
)时,该进程必须读取内容并执行其自己的进一步写入,受操作系统级调度的影响。
可以使用操作系统提供(或可用于)您的操作系统提供的系统调用级跟踪工具来生成系统调用的绝对顺序,从而生成明确排序的输出;在不丢失排序的情况下单独重定向和重新组合 stderr/stdout的答案中给出了一个示例。
但是,使用 bash 本身,您只能控制连接子进程的文件描述符的位置,而不是如何缓冲和刷新写入这些描述符的内容,因此根本没有足够的控制来使您要求的内容成为可能写入可能会重新排序。
推荐阅读
- elasticsearch - Kafka Connect Elasticsearch sink 没有文档被索引
- reactjs - Graphql:Typescript + Jest + Relay + Jest 似乎无法集成在一起
- php - 如何在php中格式化打印输出
- c# - 将位置设置为底部时不显示 TabbedPage 图标
- google-colaboratory - 在 Google Colaboratory 中长时间运行会话结束后,如何用剩余的 epoch 训练模型。?
- java - Hibernate EntityManager#getResultList 挂起,没有任何错误
- html - HTML文件的图像未在ios应用程序中加载
- javascript - window.parent.postMessage 不适用于 iframe 中的 scr="'data:text/html;charset=utf-8"
- angular - 如何在 Ionic Ecommerce App 中应用产品搜索
- dns - 如何强制用户从特定的办公地点到特定的 ADFS 服务器