Linux较少的行为和stderr


11

我正在查看带有的复杂命令的输出less,问题是stderr迷路了。stderr行通常stdout在内部的行之间列出less。我希望将它们打印到控制台上,并且当我退出时less,可以一起看到它们。

我读到,我意识到可能没有解决办法teemultitee但是到目前为止还没有运气。


2
您正在告诉我如何将stderr重定向到stdout,但这不是我想要的。我不希望stderr与stdout混在一起。我希望少走出口时,stderr能够进入候机楼。

如果stderr重定向到stdout,则所有的输出stderr 与上的正常输出混合stdout。用管道将输出less显示到两者。
一些程序员伙计

如果我忽略“退出较少时在终端中的stderr”,建议按Ctrl-L less重新绘制屏幕。
kamae 2011年

Answers:


10

也许

command 2> command.err | less; cat command.err; rm command.err

附录

以下是针对那些疏于仔细阅读问题并且没有阅读过OP的澄清意见的人们的说明。

haelix指出:

stderr行通常在更少的stdout行之间列出

在对早期答复者的评论中写道:

您正在告诉我如何将stderr重定向到stdout,但这不是我想要的。我不希望stderr与stdout混在一起。我希望少走出口时stderr在码头

问题可能是特定于平台的,这肯定是我在较旧的Unix SVR4平台上遇到的问题。

如果您在此类平台上执行

 find / ... | less

任何错误消息(例如,目录权限)都会在以下内容中显示为

 stdout line 1
 stdout line 2
 error message text
 stdout line 4

这样,输出行就会被错误消息遮盖。

如果刷新页面,则会正确显示输出行,但会丢失错误消息。当您退出时,除了命令提示符外,屏幕将被清除。

如果你做类似的事情

  find / ... 2>&1 | less

错误消息与标准输出混合在一起。同样,当您少退出时,屏幕为空。

如果要先仔细阅读较少的标准输出,然后再少退出,然后查看错误消息,则需要其他解决方案。

这就是我最初在两行回答中提出的建议。


这是垃圾 约阿希姆的答案应该是被接受的答案。
香草面对

2
@VanillaFace:我在回答中添加了一些澄清材料。
RedGrittyBrick

16

您必须重定向stderrstdout

$ ./somecommad 2>&1 | less

检查您的外壳手册(例如man bash。)


1
对这个旧问题的新读者发表评论(特别是对于Joachim而言)。这是每个人在初读该问题时的想法。但是问题更加微妙-dmckee回答
RedGrittyBrick

2>&1的简写是|&。因此,它可以简化为$ ./somecommad |& less
Melvin Abraham

1

只是告诉外壳将fd 2重定向到fd 1(stderr到stdout)

 make 2>&1 | less

1

到目前为止,所有答案中都缺少的一件事是原因,为什么会这样。这里的问题是在终端上向终端输出内容stderrless显示输出的过程之间存在某种竞争条件stdout。如果在将所有输出打印到终端less开始显示,则将保留该信息,退出后您将看到消息。OTOH如果已经开始显示内容,则错误消息会与的输出混合在一起,并且退出后不会保留任何内容(因为仅将终端保留为启动之前的状态,并且对之间的错误消息一无所知)。stderrlesslesslesslesslessless

您可以轻松看到,例如

grep foo -r /etc | less

所有“权限被拒绝”错误消息都与less输出混在一起,退出后将不存在任何内容。如果你这样做

grep foo -r /etc | (sleep 10; less)

在有less机会显示输出之前,所有(或至少大多数)错误消息已打印到终端,之后您将看到错误消息。

当然,您通常不希望在启动之前等待10秒钟less,但是对于Linux,您还可以提供等待时间的小数值,而对于快速运行的进程,通常只有很少sleep 0.1的数目可以避免竞争情况。(但是,当然,如果您希望或必须在真正安全的方面使用RedGrittyBrick的解决方案)。


0

您需要了解“文件描述符”的概念。通常,unix应用程序将以三个特殊的文件描述符开头:

  • 标准输入
  • 标准输出
  • 标准误差

|外壳中的“管道” stdout从一个过程连接到另一个过程stdin

错误是设计使然,stdin而不是下一个过程。它们通常对下一个应用程序没有意义,因此不应向用户隐藏。

如果要将错误混入stdout中,可以使用eg 2>&1,它实际上表示“将stderr附加到stdout”。例如

find /etc 2>&1 | less

还应包括无法访问的文件的错误输出。

find /etc 2>&1 >/dev/null | less

只会给你错误。


0

就您告诉我的默认行为,我对您的问题感到困惑。

当我使用

#include <stdio.h>

int main(int argc, char**argv){
  for (int j=0; j<10; ++j){
    fprintf( (j%2 ? stdout : stderr) , "%d\n" , j);
  }
  return 0;
}

为了进行简单的测试,

$ ./testredirection | less

确实满足您的要求。那是我明白的

1
3
5
7
9
(END) 

less

$ ./testredirection | less
0
2
4
6
8
$ 

当我辞职时 less


这很奇怪,但是事情并不总是这样。尝试使用脚本(echo info ; echo error 1>&2)并重复测试:两行都通过管道传递到更少的行。
cyrus

@cYrus:这也符合我的预期。“课程是我在Mac OS盒子上尝试过的。Bash 3.2.17,少了394。也许是Linux特有的。无论如何,RedGrittyBrick的方法都可以正常工作。
dmckee ---前版主小猫,

奇怪的!Debian Squeeze / Bash 4.1.5 /更少436
Cyrus 2011年

是的,我在工作时打开了一个Scientific Linux 5.3的外壳,并使用bash 3.0.15和更少的382获得了预期的行为。其中是否存在回归?
dmckee ---前版主小猫,

我不知道,我认为这只是缓冲问题。
cyrus

0

我最近在我的Debian 5.0中遇到了一个问题。例如,ls abc | 我发现错误消息的内容减少了,据我所知。

经过一些尝试,我发现这只是与屏幕缓冲区有关。stderr实际上并没有那么简单。您可以使用向上或向下箭头键(或j / k)进行演示。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.