程序如何输出到STDOUT / STDERR以外的其他位置?如何避免呢?


15

显然,我不知道所有可供使用的输出目标。我知道stdout&1)和stderr&2)。但是,在重定向两个描述符之后,有时我的控制台中仍然会输出一些输出!

我能想到的最简单的例子是GNU Parallel。每次使用它,我都会看到一个引用通知。即使我这样做&2>1 > file,我仍然会看到通知。

这同样适用于emerge:当我运行emerge并且存在一些问题时,某些信息不会被打印到stdoutnor上stdin,因为我将它们重定向并且仍然可以通过。

我主要使用来解决这些问题script,但我仍然想知道是什么导致了此问题。


1
请提供完整的示例。
库沙兰丹


8
你不会得到他们所有。脚本始终可以写入/dev/tty
佐藤桂

1
至于GNU parallelmkdir ~/.parallel; touch ~/.parallel/will-cite将禁用烦人的消息。或者,四处寻找的其他实现parallel
桂聪(SatōKatsura)

2
@OleTange因为这不是问题,所以我想问为什么会发生什么,我parallel以它为例。
MatthewRock '16

Answers:


40

您使用的语法错误。

cmd &2>1 >file

将被分解为

cmd &
2>1 >file

这将:

  1. cmd作为后台作业运行,无重定向
  2. 在一个单独的过程中(没有命令!)将重定向stderr到一个字面叫的文件1并重定向stdoutfile

您想要的语法是:

cmd >file 2>&1

操作顺序很重要。这将:

  1. 重定向stdoutfile
  2. 重新导向 stderr&1-即与相同的文件句柄stdout

结果是 stderrstdout都将被重定向到file

在中bash,一种更简单的非标准(出于可移植性的原因,因此我不推荐这样做)的语法cmd &> file也具有相同的作用。


很好,谢谢。另一个问题可能是/dev/tty,但希望这不会发生得太频繁(如果有的话)。
MatthewRock '16

5
如果您的计算机上具有该at命令并有权使用它,则可以通过来运行该命令at now。有关详细信息,请参见手册页。这将通过批处理过程机制运行命令,并且该过程永远不会有tty写入。但是,总的来说,我不会担心这种情况。通常,仅使用需要交互并且故意需要向用户显示内容的过程,尽管需要重定向/dev/tty
史蒂芬·哈里斯

到那儿去了

10

有两个问题。

第一个是顺序很重要,第二个是/dev/tty

让我们将此脚本用作示例脚本,以捕获以下内容的输出:

test.sh

#!/bin/bash

echo dada
echo edada 1>&2
echo ttdada >/dev/tty

现在让我们看一下命令的输出:

./testmyscript.sh 2>&1 >/dev/null

edada
ttdada

因为评估的顺序是从左到右,所以我们首先得到“重定向stderrstdout输出的任何位置(因此,控制台输出)”。然后我们得到“重定向stdout/dev/null。我们最终遇到这样的情况:

stdout-> /dev/null stderr->控制台

因此,我们做对了:

./testmyscript.sh >/dev/null 2>&1

我们得到:

ttdada

现在,我们执行“重定向stdout/dev/null”,然后执行“将stderr重定向到stdout指向的位置”(所以,/dev/null)。欢呼!

但是,我们仍然有一个问题。程序打印到/dev/tty。现在,我不知道如何解决这种问题,因此您很可能需要这样做script,但是希望这种行为不会经常发生。

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.