将echo的标准输出重定向到标准错误,仍然在终端产生输出?

时间:2014-12-24 01:03:22

标签: bash redirectstandardoutput

我有点困惑为什么当我将echo命令的标准输出重定向到标准错误时,为什么我仍然在终端中打印参数?

这是我跑的路线

echo "potato" >&2

有人可以向我解释一下吗?如果输出被重定向到其他地方,该命令如何输出任何内容?

谢谢:)

5 个答案:

答案 0 :(得分:1)

我认为你想要的是:

bash-3.2$ echo "potato" &>2
bash-3.2$ 

来自bash的man页面:

Redirecting Standard Output and Standard Error
       Bash  allows  both  the  standard  output (file descriptor 1) and 
       the standard error output (file descriptor 2) to be redirected to the file 
       whose name is the expansion of word with this construct.

       There are two formats for redirecting standard output and standard error:

              &>word
       and
              >&word

       Of the two forms, the first is preferred.  This is semantically equivalent to

              >word 2>&1

答案 1 :(得分:1)

首先,当您的终端和shell启动时,STDOUT和STDERR都指向终端输出。您的命令echo "potato" >&2要求将STDOUT重定向到STDERR指向的内容。因此这个命令根本没有效果。

以下是一些参考资料:

  • 文件描述符0(FD0)名为STDIN
  • 文件描述符1(FD1)名为STDOUT
  • 文件描述符2(FD2)名为STDERR
  • 文件描述符3(FD3)以及更多没有特殊名称。
  • 任何unix程序最初都默认打开所有这3个文件描述符。
  • STDIN默认指向输入设备(打开程序的终端),通常最终指向键盘
  • STDOUT,STDERR默认指向控制台(终端)输出
  • > somefile1> somefile将文件描述符1重定向到名为'somefile'的文件,即将STDOUT指向'somefile'
  • n> somefile将文件描述符n重定向到名为'somefile'的文件,其中n = 1,2,3,... n默认为1,{{1}省略。
  • n将文件描述符n重定向到文件描述符m。
  • 当我们说文件描述符n被重定向到文件描述符m时,我们实际上意味着文件描述符n被强制指向指向的文件描述符m,例如终端输出设备/控制台。
  • n>&m关闭文件描述符n,其中n = 1,2,3,...
  • 重定向的顺序很重要。它们从左到右应用。见下面的例子:

n>&-

  • 在重定向和管道之间进行排序(首先是管道,然后是重定向)。因此,此命令:# FD1 (file descriptor1, i.e. STDOUT) is redirected (pointing) to the file named 'file.log` # Then FD2 is pointing to what FD1 points to, i.e. 'file.log'. Thus the following command # redirection both "potato" and the error output of 'ls xx' to file.log: $ (echo "potato"; ls xx) > file.log 2>&1 $ cat file.log potato ls: cannot access xx: No such file or directory # FD2 is redirected (pointing) to what FD1 points to, i.e. the terminal output. (This has no effect, since FD2 was pointed to the terminal anyway. # FD1 is then redirected to file.log # Thus the following command only redirects "potato" to file.log, and left the error message # displayed on the terminal. $ (echo "potato"; ls xx) 2>&1 > file.log ls: cannot access xx: No such file or directory $ cat file.log potato 首先在command1和command2之间创建管道,即将命令1的STDOUT链接到command2的STDIN。然后,command1的STDOUT被重定向到/ dev / null。这基本上取消了管道(脱离管道)。因此command2将看到STDIN输入的结束,即command2的STDIN被关闭。

因此,它解释了为什么以下命令交换STDIN和STDOUT:

command1 > /dev/null | comamnd2
  • 步骤1:创建管道,FD1(左侧)指向管道输出。 $ (echo xx; ls xx) 3>&1 1>&2 2>&3 3>&- | wc -l ls: cannot access xx: No such file or directory 1 的FD0指向管道输入
  • 步骤2:创建FD3,复制FD1,即指向管道输出
  • 步骤3:FD1现在变为指向的FD2,即终端输出。
  • 步骤4:现在将FD2更改为指向的FD3,即管道输出。
  • 步骤5:关闭FD3。

净效应是:         FD1现在指向终端输出。         FD2现在指向管道输出,管道输出到wc命令。

希望这有帮助。

答案 2 :(得分:0)

嗯,默认情况下,您的终端同时显示STDOUT和STDERR。

所以,你看到的是STDERR。

如果你想隐藏STDERR:echo "potato" 2>/dev/null >&2

/dev/null是一个黑洞,您可以在其中重定向您不希望看到的内容:)

答案 3 :(得分:0)

因为标准错误也默认显示在终端中。因此,您将标准输出重定向到标准错误,而标准错误又会重定向到控制台。结果不会改变。

答案 4 :(得分:0)

输出只是告诉它去的地方

默认情况下,文件描述符1和2指向同一位置(注意>&2相当于1>&2

> $ ls -l /proc/$$/fd/
total 0
lrwx------ 1 foo foo 64 Dec 23 18:42 0 -> /dev/pts/3
lrwx------ 1 foo foo 64 Dec 23 18:42 1 -> /dev/pts/3
lrwx------ 1 foo foo 64 Dec 23 18:42 2 -> /dev/pts/3

现在让我们说我们将其中一个文件描述符重定向到其他地方

> exec 1>foo
> ls -l /proc/$$/fd/
> exec 1>&2
> cat foo
total 0
lrwx------ 1 foo foo 64 Dec 23 18:42 0 -> /dev/pts/3
lrwx------ 1 foo foo 64 Dec 23 18:42 1 -> /home/foo/foo
lrwx------ 1 foo foo 64 Dec 23 18:42 2 -> /dev/pts/3    

请注意ls -l /proc/$$/fd/的输出转到我们工作目录中的文件foo,而不是打印到stdout。