一些终端程序如何忽略重定向和管道?

一些终端程序如何忽略重定向和管道?

今晚我一直在摆弄我的网卡,当我运行时我注意到了一些ip link help不同的东西。以下是我注意到不同之处的两种情况:

ip link help | grep set

ip link help > ip_link_help.txt

第一个命令没有效果,即,不是将 的输出ip link help从 重定向stdoutgrep,而是简单地忽略管道并将 的输出ip link help发送到stdout

第二种情况有点不同。虽然ip link help忽略了重定向符号>并只打印到stdout,但文件file.txt还是被创建了(但它是空的)。

答案1

ip link help打印到标准错误(stderr,文件描述符2);其标准输出(stdout,文件描述符1)不获取任何数据。通常,这两个流都发送到终端,因此乍一看您无法真正区分它们。|>影响标准输出。使用它之后,您就会知道任何被重定向的数据都必须发送到 stdout;其他所有数据 – 发送到其他地方:通常是 stderr,尽管有些程序会直接将一些数据打印到终端(ip不是其中之一)。

在第一种情况下,您可以将 stderr 重定向到 stdout 的文件描述符,然后构建管道:

ip link help 2>&1 | grep set

where2>&1告诉 shell 将文件描述符重定向2到文件描述符1指向的任何位置。使用此语法,如果命令将某些内容打印到 stdoutstderr,一切都会到达grep

ip在第二种情况下,shell 在运行之前创建(如果需要)并截断文件。您可以通过调用

a_command_that_doesnt_even_exist > foo.txt

foo.txt尽管存在明显的错误,仍会创建。这是因为它是在 shell 尝试运行命令之前首先创建的。

要将 stderr 捕获到文件中,请使用2>仅重定向 stderr:

ip link help 2> ip_link_help.txt

同样,1>仅重定向 stdout。>您使用的 Short 严格相当于1>


一个以三种不同方式打印到终端的命令的人工示例是

echo "standard output"; echo "standard error" >&2; echo "terminal" >/dev/tty

输出为:

standard output
standard error
terminal

您可以轻松地重定向前两行。试试这个:

(echo "standard output"; echo "standard error" >&2; echo "terminal" >/dev/tty) >stdout.txt 2>stderr.txt

但这仍会打印最后一行。

相关内容