Linux stdin、stdout和stderr详解

一、标准流介绍

在计算机编程中,标准流是计算机程序开始执行时与其环境之间预连接的输入和输出通信通道。这三种输入/输出(I/O)连接称为标准输入(stdin)、标准输出(stdout)和标准错误(stderr)。最初I/O是通过物理连接的系统控制台(通过键盘输入,通过监视器输出)发生的,但是标准流抽象了这一点。当通过交互式shell执行命令时,流通常连接到shell运行的文本终端,但可以通过重定向或管道进行更改。更一般地说,子进程继承其父进程的标准流。

标准输入(Standard input (stdin))

标准输入是程序从中读取其输入数据的流。程序通过读取操作请求数据传输。并非所有程序都需要流输入。例如,dir和ls程序(它们显示目录中包含的文件名)可能接受命令行参数,但在没有任何流数据输入的情况下执行它们的操作。

除非重定向,否则标准输入从父进程继承。在交互式shell的情况下,它通常与终端(或伪终端)的输入设备相关联,终端最终连接到用户的键盘。

标准输出(Standard output (stdout))

标准输出是程序向其写入输出数据的流。程序通过写操作请求数据传输。并不是所有的程序都产生输出。例如,文件重命名命令(有mv、move或ren等不同的名称)在执行成功后将静默。

除非重定向,否则标准输出从父进程继承。在交互式shell的情况下,它通常是启动程序的文本终端。

标准错误(Standard error (stderr))

标准错误是程序通常用于输出错误消息或诊断的另一个输出流。它是一个独立于标准输出的流,可以单独重定向。

通常的目的地是文本终端,它启动程序以提供最好的机会被看到,即使标准输出被重定向(因此不容易被观察到)。例如,管道中程序的输出被重定向到下一个程序或文本文件的输入,但每个程序的错误仍然直接进入文本终端,以便用户可以实时查看。

将标准输出和标准错误直接输出到相同的目的地(如文本终端)是可以接受的,也是正常的。消息的出现顺序与程序写入它们的顺序相同,除非涉及到缓冲。例如,在通常情况下,标准错误流是未缓冲的,但标准输出流是行缓冲的;在这种情况下,如果标准输出流缓冲区还没有满,那么稍后写入标准错误的文本可能会更早出现在终端上。

二、标准流文件描述符

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

  • 0:代表标准输入
  • 1:代表标准输出
  • 2:代表标准错误

在Linux中,不需要找到这个文件或为它们执行任何操作;它们已经是Linux系统的一部分,并且连接到终端设备(例如,"/dev/tty")。

二、重定向操作符

重定向分为输入重定向和输出重定向

  • 输入重定向

输入重定向是把命令的标准输入重定向到指定的文件,可以来自键盘或者文件。

操作符为:<0<

示例:

shell 复制代码
cat < test.txt
cat 0< test.txt

两者等同
  • 输出重定向

输出重定向是指把命令(或可执行程序)的标准输出或标准错误输出重新定向到指定文件中。这样,该命令的输出就不显示在屏幕上,而是写入到指定文件中。

  1. [command] > [文件名]:把标准输出重定向到文件中,会覆盖源文件内容,> 实为 1>的略写,不写文件描述符,则默认为1

示例:

shell 复制代码
ls > a.txt
ls 1> a.txt

两者等同
  1. [command] >> [文件名]:把标准输出重定向到文件中,不覆盖源文件内容,把结果追加到文件结尾。

示例:

shell 复制代码
ls >> a.txt
ls 1>> a.txt
  1. [command] 2> [文件名]:把标准错误重定向到文件中,会覆盖源文件内容。

示例:

shell 复制代码
ls 2> a.txt
  1. [command] 2>> [文件名]:把标准错误重定向到文件中,不覆盖文件内容,把结果追加到文件结尾。

示例:

shell 复制代码
ls 2>> a.txt
  1. [command] > [文件名] 2>&1[command] &> [文件名]:把标准错误重定向到标准输出

示例:

shell 复制代码
ls > a.txt 2>&1

ls &> a.txt

两者等同
  1. [command] > /dev/null:把标准输出重定向到空设备,即丢弃输出信息,空设备相当于 windows 的垃圾桶。

示例:

shell 复制代码
ls > /dev/null
ls 1> /dev/null

两者等同
  1. [command] 2> /dev/null:把标准错误重定向到空设备。

示例:

shell 复制代码
ls 2> /dev/null
  1. [command] > /dev/null 2>&1:把标准输出和标准错误都重定向到空设备。

示例:

shell 复制代码
ls > /dev/null 2>&1 
  1. [command] > abc.txt 2> def.txt:把标准输出和标准错误分别重定向到不同的文件。

示例:

shell 复制代码
ls > abc.txt 2> def.txt
  1. [command] > common.txt 2>&1:把标准输出和标准错误重定向到同一个文件。

示例:

shell 复制代码
ls > common.txt 2>&1

三、其他常用操作

  • 同时指定 <>
shell 复制代码
cat < a.txt > b.txt

从a.txt中读取再写到b.txt中,可当做复制功能使用
  • 结合通道使用
shell 复制代码
ls | grep abc | cat > a.txt

解释:ls列出文件,通过 |(通道) 把标准输出传给grep的标准输入,再把grep的标准输出传给cat的标准输入,cat最后把标准输出写到文件。
  • 通过文件描述符路径的方式指定
shell 复制代码
ls > /dev/fd/1
重定向到标准输出

ls > /dev/fd/2
重定向到标准错误
  • 标准输出重定向到标准错误
shell 复制代码
ls 1>&2
  • 标准错误重定向到标准输出
shell 复制代码
ls 2>&1
相关推荐
梅见十柒23 分钟前
wsl2中kali linux下的docker使用教程(教程总结)
linux·经验分享·docker·云原生
Koi慢热26 分钟前
路由基础(全)
linux·网络·网络协议·安全
传而习乎36 分钟前
Linux:CentOS 7 解压 7zip 压缩的文件
linux·运维·centos
我们的五年1 小时前
【Linux课程学习】:进程程序替换,execl,execv,execlp,execvp,execve,execle,execvpe函数
linux·c++·学习
IT果果日记1 小时前
ubuntu 安装 conda
linux·ubuntu·conda
Python私教1 小时前
ubuntu搭建k8s环境详细教程
linux·ubuntu·kubernetes
羑悻的小杀马特1 小时前
环境变量简介
linux
小陈phd2 小时前
Vscode LinuxC++环境配置
linux·c++·vscode
是阿建吖!2 小时前
【Linux】进程状态
linux·运维
明明跟你说过2 小时前
Linux中的【tcpdump】:深入介绍与实战使用
linux·运维·测试工具·tcpdump