我们可以在 Linux 中引用文件的**输出**有 4 种类型,这是真的吗?

我们可以在 Linux 中引用文件的**输出**有 4 种类型,这是真的吗?

是否可以得出 4 种类型的结论?流输出如果我们不希望它们在执行命令后出现在 CLI 中,我们可以引用 Linux 中的文件吗?

对文件的可能引用:

  1. 所有流输出
  2. 仅标准错误
  3. 仅标准输出(包括标准输出的最终结果)。
  4. stdout 和 stderr(不包括 stdout 的最终结果)。

笔记:

数字 4 的一个例子可能是find / -type f -name php.ini 2>/dev/null。据我了解,使用这个命令我们没有得到标准错误,也没有标准输出(除了标准输出的最终结果在本例中,这是我们搜索的文件(如果找到)。

答案1

有两个输出流连接到 Unix 系统上的每个进程:标准输出(标准输出,文件描述符 1)和标准误(stderr,文件描述符 2)。这些可以彼此独立地重定向。标准输入使用文件描述符 0。

  • 要将标准输出重定向到文件file,请使用>file或更明确的1>file。替换file/dev/null丢弃数据。
  • 要将标准错误重定向到文件file,请使用2>file.
  • 要将标准错误重定向到标准输出所在的位置,请使用2>&1.
  • 要将标准输出重定向到标准错误所在的位置,请使用1>&2.

不存在流或过程的“最终结果”概念。我想发送到标准输出的任何内容都可以被视为进程的“结果”,除非它也将数据输出到它自己打开的某个文件或具有其他副作用(例如从目录中取消文件链接,在这种情况下)的rm,或在 ) 的情况下处理多个网络连接sshd。进程还返回退出状态(零表示“成功”,非零表示“失败”),可以将其视为该进程的“结果”,但这不一定与进程的输出流相关。

流也可以重定向到附加模式,这意味着如果重定向到文件,则该文件最初不会被截断,并且流上的任何数据都将附加到文件末尾。通过使用>>file而不是来做到这一点>file

在问题的注释中,命令

find / -type f -name php.ini 2>/dev/null

给出。这会重定向(丢弃)仅有的标准误差。标准输出流根本不重定向,因此在控制台或终端中完整可见。如果它是管道的中间部分,则标准输出流将被输入到管道中下一个命令的标准输入中。

总而言之,我想说有(不是四个)输出流。这些可以以各种方式独立地重定向,其中包括丢弃它们的内容。

答案2

每一个过程按照惯例,可以使用三个标准文件描述符。这些文件描述符可作为流使用:stdinstdoutstderr

默认情况下,当您从 shell (CLI) 启动进程时,第一个进程连接到终端(或终端仿真器,如 xterm)的输入,另外两个连接到终端的输出。

您可以指示 shell 将它们重定向到其他地方,例如/dev/null(它们被吞噬的地方)。您可以独立为stdout和执行此操作stderr。那么对于这种情况,确实有四种可能:

command 
command > /dev/null
command 2> /dev/null
command > /dev/null 2> /dev/null

但没有什么可以阻止您将其中一个或两个重定向到其他地方:

command > /tmp/myout 2> /tmp/myerr

在这种情况下,您的终端也不会得到任何输出,但您可以稍后在文件/tmp/myout和中读取它/tmp/myerr

答案3

情况比你的问题所暗示的更简单,也更复杂。来解释一下什么善行难陀说在他的回答,有两个按惯例配置并用于输出的标准(常规)I/O 流(文件描述符):stdout(文件描述符 1)和 stderr(文件描述符 2)。我们的规范问题, shell 的控制和重定向运算符是什么?,讨论如何重定向它们。天真地,我们可以列举五种不同的组合:

╔══════════════════════════════╦═════════════════════════════════════════════╗
║                              ║                   stderr                    ║
║                              ╟─────────────────────┬───────────────────────╢
║                              ║       default       │                       ║
║                              ║ (same as the shell) │       redirected      ║
╠════════╤═════════════════════╬═════════════════════╦═══════════════════════╣
║        │       default       ║                     ║                       ║
║        │ (same as the shell) ║          1          ║           2           ║
║        ├─────────────────────╠═════════════════════╬═══════════════════════╣
║ stdout │                     ║                     ║ 4. redirected         ║
║        │                     ║                     ║    to the same file   ║
║        │      redirected     ║          3          ╟───────────────────────╢
║        │                     ║                     ║ 5. redirected         ║
║        │                     ║                     ║    to different files ║
╚════════╧═════════════════════╩═════════════════════╩═══════════════════════╝

但如果你算作/dev/null与文件不同,追加模式作为一种特殊情况,读写模式与只写模式不同,管道与文件不同,那么组合的数量就会呈指数级增长。然而,正如反复指出的,“stdout 的最终结果”不是标准的 Unix/Linux/bash 短语。

只有两个?

其他答案(也许是明智的)将自己限制为 stdout 和 stderr (文件描述符 1 和 2)。我(鲁莽地?)相信这个问题的完整答案应该解决其他文件描述符可用的事实 - 最多数百,数千,甚至超过一百万。例如,如果运行类似 的命令diff file1 file2diff程序将打开file1file2,内核可能会分配文件描述符 3 和 4。不同之处在于,只有文件描述符 0、1 和 2 是预先定义的。以下位置讨论了重定向大于 2 的文件描述符:

例如,请参阅以下高文件描述符示例:

$ 猫犬.c
#include <stdio.h>
#include <字符串.h>

主要的()
{
        int i,len;
        char msg[] = "你好,狗。\n";

        len = strlen(msg);
        我=写(17,味精,长度);
        如果 (i == len)
                printf("成功!i = %d = len\n", i);
        否则如果 (i == -1)
            {
                printf("错误!i = %d (len = %d)\n", i, len);
                错误(“”);
            }
        别的
                printf("意外结果:i = %d, len = %d\n", i, len);
}

$ 制作犬类
cc 犬.c -o 犬

$ ./犬类
错误!我 = -1 (len = 12)
错误的文件描述符

$ ./canine 17> 动物
成功!我 = 12 = 长度

$ ls -l
总计 70
-rw-r--r-- 1我的用户名 我的组名    2012年4月12日 13:36 动物
-rwxr-xr-x 1我的用户名 我的组名67067 4 月 12 日 13:36 犬
-rw-r--r-- 1我的用户名 我的组名   358 四月 12 13:36 犬.c

$ 猫 动物
你好,狗。

警告:我不确定上述内容是否适用于所有 shell 的所有版本。

标准程序不会写入高于 2 的文件描述符(除非它们通过打开文件、建立网络连接或类似操作从内核获取该文件描述符)。但是,如果您有一个执行此操作的(非标准)程序,则可以重定向这些文件描述符。

而且,如果您只有 100 个文件描述符,并且仅考虑每个文件描述符是否被重定向,那么您就有超过十亿 (1,000,000,000,000,000,000,000,000,000,000) 种可能的组合。

相关内容