Linux上的stdin,stdout和stderr是什么?

Linux计算机上的终端窗口Fatmawati Achmad Zaenuri / Shutterstock.com

标准输入标准输出,和 标准错误 是启动Linux命令时创建的三个数据流。您可以使用它们来判断脚本是通过管道传输还是重定向。我们告诉你怎样。

Streams加入两点

一旦你开始学习Linux和类Unix操作系统,你就会遇到这些术语 标准输入标准输出,和 stederr。这些是在执行Linux命令时建立的三个标准流。在计算中,流是可以传输数据的东西。在这些流的情况下,该数据是文本。

数据流,如水流,有两个目的。他们有来源和外流。无论您使用哪种Linux命令,都会提供每个流的一端。另一端由启动命令的shell确定。根据启动命令的命令行,该端将连接到终端窗口,连接到管道,或重定向到文件或其他命令。

Linux标准流

在Linux中, 标准输入 是标准输入流。这接受文本作为其输入。从命令到shell的文本输出是通过 标准输出 (标准输出)流。来自命令的错误消息通过发送 标准错误 (标准错误)流。

所以你可以看到有两个输出流, 标准输出标准错误和一个输入流, 标准输入。因为错误消息和正常输出都有自己的管道来将它们传送到终端窗口,所以它们可以彼此独立地处理。

流处理文件

Linux中几乎所有其他内容的流都被视为文件。您可以从文件中读取文本,也可以将文本写入文件。这两个动作都涉及数据流。因此,将数据流作为文件处理的概念并不是那么容易。

与进程关联的每个文件都会分配一个唯一的编号来标识它。这称为文件描述符。每当需要对文件执行操作时,文件描述符用于标识文件。

始终使用这些值 标准输入标准输出,标准错误

  • 0:stdin

  • 1:标准输出

  • 2:stderr

对管道和重定向做出反应

为了简化某人对某个主题的介绍,一种常见的技术是教授该主题的简化版本。例如,通过语法,我们被告知规则是“我在E之前,除了在C之后”。但实际上,这个规则有更多的例外,而不是遵守它的情况。

在谈论时也是如此 标准输入标准输出,和 标准错误 可以方便地推出一个公认的过程,即一个过程既不知道也不关心其三个标准流的终止位置。进程是否应该关心其输出是转到终端还是重定向到文件中?它甚至可以判断它的输入是来自键盘还是从另一个进程输入?

实际上,如果软件作者决定添加该功能,那么一个进程确实知道 – 或者至少它可以找到它,如果它选择检查 – 它可以相应地改变它的行为。

我们可以很容易地看到这种行为的变化。试试这两个命令:

LS

在终端窗口

ls |猫

ls在终端窗口中输出

LS 如果输出的命令行为不同(标准输出正在被管道输入另一个命令。它是 LS 切换到单列输出,它不是由执行的转换 。和 LS 如果重定向其输出,则执行相同的操作:

ls> capture.txt

ls>终端窗口中的capture.txt

cat capture.txt

cat capture.txt在终端窗口中

重定向stdout和stderr

通过专用流传递错误消息是有利的。这意味着我们可以重定向命令的输出(标准输出)到一个文件,仍然看到任何错误消息(标准错误)在终端窗口。如果需要,您可以对错误做出反应。它还会阻止错误消息污染文件 标准输出 已被重定向到。

在编辑器中键入以下文本并将其保存到名为error.sh的文件中。

#!/斌/庆典

echo“关于尝试访问不存在的文件”
cat bad-filename.txt

使用此命令使脚本可执行:

chmod + x error.sh

脚本的第一行通过文本将文本回显到终端窗口 标准输出 流。第二行尝试访问不存在的文件。这将生成通过传递的错误消息 标准错误

使用以下命令运行脚本:

./error.sh

./error.sh在终端窗口中

我们可以看到两个输出流, 标准输出标准错误,已经显示在终端窗口中。

在终端窗口中输出error.sh脚本

让我们尝试将输出重定向到文件:

./error.sh> capture.txt

./error.sh>终端窗口中的capture.txt

通过提供的错误消息 标准错误 仍然被发送到终端窗口。我们可以查看文件的内容,看看是否可以 标准输出 输出转到文件。

cat capture.txt

cat capture.txt在终端窗口中

输出来自 标准输入 被按预期重定向到文件。

终端窗口中capture.txt的内容

> 重定向符号适用 标准输出 默认情况下。您可以使用其中一个数字文件描述符来指示要重定向的标准输出流。

要明确重定向 标准输出,使用此重定向指令:

1>

要明确重定向 标准错误,使用此重定向指令:

2>

让我们再次尝试我们的测试,这次我们将使用 2>

./error.sh 2> capture.txt

./error.sh 2>终端窗口中的capture.txt

错误消息被重定向并且 标准输出 回声 消息被发送到终端窗口:

在终端窗口中输出./error.sh 2> capture.txt

让我们看看capture.txt文件中的内容。

cat capture.txt

cat capture.txt在终端窗口中

标准错误 消息在capture.txt中按预期方式。

终端窗口中capture.txt文件的内容

重定向stdout和stderr

当然,如果我们可以重定向 标准输出 要么 标准错误 对于一个彼此独立的文件,我们应该能够同时将它们重定向到两个不同的文件?

我们可以。这个命令将指向 标准输出 到一个名为capture.txt和。的文件 标准错误 到一个名为error.txt的文件。

./error.sh 1> capture.txt 2> error.txt

终端窗口中的./error.sh 1> capture.txt 2> error.txt

由于输出标准输出和标准错误的两个流都被重定向到文件,因此终端窗口中没有可见的输出。我们返回到命令行提示符,好像什么都没发生一样。

./error.sh在终端窗口中输出

让我们检查每个文件的内容:

cat capture.txt
cat error.txt

终端窗口中的capture.txt和error.txt的内容

将stdout和stderr重定向到同一文件

这很简洁,我们已经将每个标准输出流转到它自己的专用文件。我们唯一能做的其他组合就是发送两者 标准输出标准错误 到同一个文件。

我们可以使用以下命令实现此目的:

./error.sh> capture.txt 2&> 1

让我们打破它。

  • ./error.sh:启动error.sh脚本文件。

  • > capture.txt:重定向 标准输出 流到capture.txt文件。 > 是简写 1>

  • 2>&1:这使用&>重定向指令。此指令允许您告诉shell使一个流与另一个流到达同一目的地。在这种情况下,我们说“重定向流2, 标准错误,到与流1相同的目的地, 标准输出,正被重定向到。“

./error.sh>终端窗口中的capture.txt 2&> 1

没有可见的输出。这令人鼓舞。

终端窗口中输出./error.sh

让我们检查一下capture.txt文件,看看里面有什么。

cat capture.txt

终端窗口中capture.txt的内容

这俩 标准输出标准错误 流已被重定向到单个目标文件。

要将流的输出重定向并静默丢弃,请将输出定向到 的/ dev / null的

检测脚本中的重定向

我们讨论了命令怎样检测是否有任何流被重定向,并可以选择相应地改变其行为。我们可以用自己的脚本完成这个吗?我们可以。这是一种非常容易理解和使用的技术。

在编辑器中键入以下文本并将其另存为input.sh。

#!/斌/庆典

if(-t 0);然后

  来自键盘的echo stdin
 
其他

  echo stdin来自管道或文件
 
科幻

使用以下命令使其可执行:

chmod + x input.sh

聪明的部分是方括号内的测试。该 -t 如果与文件描述符关联的文件在终端窗口中终止,则(terminal)选项返回true(0)。我们使用文件描述符0作为测试的参数,代表 标准输入

如果 标准输入 连接到终端窗口,测试将证明是真的。如果 标准输入 连接到文件或管道,测试将失败。

我们可以使用任何方便的文本文件来生成脚本的输入。这里我们使用一个名为dummy.txt的文件。

./input.sh <dummy.txt

<img class =“alignnone size-full wp-image-436383”data-pagespeed-lazy-src =“https://www.howtogeek.com/wp-content/uploads/2019/08/x26.png.pagespeed。 gp + jp + jw + pj + ws + js + rj + rp + rw + ri + cp + md.ic.KS7TuufRTP.png“alt =”./ input.sh < dummy.txt in a terminal window" width="646" height="57" src="/pagespeed_static/1.JiBnMqyl6S.gif" onload="pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);" onerror="this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);">

输出显示脚本识别出输入不是来自键盘,而是来自文件。如果您选择,则可以相应地改变脚本的行为。

从终端窗口中的脚本输出

那是文件重定向,让我们用管道来试试。

cat dummy.txt | ./input.sh

cat dummy.txt | ./input.sh在终端窗口中

该脚本识别出其输入正在通过管道输入。或者更准确地说,它再一次认识到了 标准输入 流未连接到终端窗口。

终端窗口中的脚本输出

让我们运行脚本既不管道也不重定向。

./input.sh

./input.sh在终端窗口中

标准输入 流连接到终端窗口,脚本相应地报告。

要使用输出流检查相同的内容,我们需要一个新脚本。在编辑器中键入以下内容并将其另存为output.sh。

#!/斌/庆典

if(-t 1);然后

echo stdout将进入终端窗口
 
其他

echo stdout正在被重定向或管道传输
 
科幻

使用以下命令使其可执行:

chmod + x input.sh

对此脚本的唯一重大更改是在方括号中的测试中。我们使用数字1来表示文件描述符 标准输出

我们来试试吧。我们将输出通过

./output |猫

./output |猫在终端窗口

该脚本识别出其输出不会直接进入终端窗口。

脚本输出在终端窗口中

我们还可以通过将输出重定向到文件来测试脚本。

./output.sh> capture.txt

./output.sh>终端窗口中的capture.txt

终端窗口没有输出,我们默默地返回到命令提示符。正如我们所期望的那样。

脚本输出在终端窗口中

我们可以查看capture.txt文件以查看捕获的内容。使用以下命令执行此操作。

猫capture.sh

cat capture.sh在终端窗口中

再一次,我们脚本中的简单测试检测到了 标准输出 流不会直接发送到终端窗口。

如果我们在没有任何管道或重定向的情况下运行脚本,它应该检测到它 标准输出 正在直接送到终端窗口。

./output.sh

./output.sh在终端窗口中

而这正是我们所看到的。

脚本输出在终端窗口中

意识流

知道怎样判断脚本是否已连接到终端窗口,管道或正在重定向,您可以相应地调整其行为。

记录和诊断输出可以或多或少地详细,具体取决于它是进入屏幕还是文件。错误消息可以记录到与正常程序输出不同的文件中。

通常情况下,更多知识带来更多选择。

body #primary .entry-content ul#nextuplist list-style-type:none; margin-left:0px; padding-left:0px;
body #primary .entry-content ul#nextuplist li a text-decoration:none; color:#1d55a9;

请阅读下一步

  • >怎样流式传输UFC 241 Cormier与Miocic Live Online
  • >怎样使用Chrome的隐藏“发送标签到自我”功能
  • >微软将通过Windows 10的商店更新记事本
  • > Windows 10将在任务管理器中显示GPU温度
  • >您可以在Windows PC或Android手机上使用AirDrop吗?
本文机器自动生成,不保证语句完整通顺和表达准确,亦不对内容真实有效性负责,请读者知悉。