将终端输出重定向到文件

将终端输出重定向到文件

我正在寻找bash可以重定向的命令:

  1. 将命令的标准输出到文件
  2. 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在收到输入时立即切换到 。通常,不能指望它这样做。在并行路径中添加另一个进程不会有帮助,因为结果将仅取决于两个中间进程之间的调度(而不是cmdtee)。

答案4

你可以做这样的事情:

echo "asd" | xargs -I % sh -c 'echo % && echo % > asd'

第一个 echo 被传递给 xargs,xargs 将其作为参数并构建两个 echo 命令,第一个结果输出到终端,第二个结果作为文本输出到名为 asd 的文件中。

您可以在后面放置重定向以满足您的需求。

相关内容