我正在寻找bash
可以重定向的命令:
- 将命令的标准输出到文件
- stderr 到该文件和控制台。
我已经找到了将 stderr 附加到 stdout 之后文件末尾的方法,但我希望输出文件能够按时间顺序排列所有输出,就像我仅使用 一样command &> file
。
我努力了:
command 2>&1 1>logfile | tee -a logfile
command 2> >(tee -a logfile) 1>>logfile
我基本上希望输出文件与我简单执行的操作相同command &> logfile
,同时继续将 stderr 消息打印到控制台。
答案1
让我们创建一个测试函数,将一些输出发送到 stdout 和 stderr:
$ cmd() { echo 1 on stdout; echo 2 on stderr >&2; echo 3 on stdout; echo 4 on stderr >&2; }
运行它我们看到:
$ cmd
1 on stdout
2 on stderr
3 on stdout
4 on stderr
现在,我们想将 stdout 发送到文件,将 stderr 发送到文件和屏幕。为此,我们对 stdout 使用简单的重定向,对于 stderr,我们重定向到附加到文件并将输出发送回 stderr 的进程替换:
$ cmd > cmd.out 2> >( tee -a cmd.out >&2 )
2 on stderr
4 on stderr
$ cat cmd.out
1 on stdout
3 on stdout
2 on stderr
4 on stderr
我不知道如何保持混合的 stdout 和 stderr 消息的时间顺序。
答案2
如果将 stdout 附加到文件并将 stderr 重定向到tee
,则它会起作用,同时附加到文件:
$ bash -c "echo a;bahs;echo b;bhas" >>file 2> >( tee -a file >&2 )
bash: bahs: command not found
bash: bhas: command not found
$ cat file
a
bash: bahs: command not found
b
bash: bhas: command not found
这没有根据 Glenn Jackman 的回答进行测试,但我不明白为什么。
答案3
我认为你确实做不到这一点。
当您分别重定向stdout
和时stderr
,它们会变得不同步,并且无法再次修复它们。您要尝试执行的操作如下:
+------> terminal
|
cmd -(stderr)--> tee ----> file
| ^
+---(stdout)---------------+
这里,有两条从cmd
到 的平行路径file
,路径中有一个附加进程stderr
。根据调度情况,涉及 的路径可能会出现延迟tee
,这可能会导致stderr
消息延迟。
为了防止这种情况发生,系统需要tee
在收到输入时立即切换到 。通常,不能指望它这样做。在并行路径中添加另一个进程不会有帮助,因为结果将仅取决于两个中间进程之间的调度(而不是cmd
和tee
)。
答案4
你可以做这样的事情:
echo "asd" | xargs -I % sh -c 'echo % && echo % > asd'
第一个 echo 被传递给 xargs,xargs 将其作为参数并构建两个 echo 命令,第一个结果输出到终端,第二个结果作为文本输出到名为 asd 的文件中。
您可以在后面放置重定向以满足您的需求。