当前位置: 首页 > news >正文

一文搞懂Linux的标准输出/错误重定向

前言

 今天在写一个脚本时,需要将shell命令和可执行程序的输出重定向在某一个log文件中,但是遇到了点小问题,索性就研究下输出重定向到底怎么回事。

 Linux系统,有一个非常重要概念,就是一切皆文件。在使用shell脚本时,系统为了能够进行接收外部输入,同时向外部输出,将三个文件始终保持在打开的状态,并使用三个文件描述符0,1,2来分别指向这三个文件,以此来完成标准输入,标准输出,标准错误输出。

  • 标准输入:由键盘输入

  • 标准输出:输出到屏幕

  • 标准错误:输出到屏幕

 在正常情况下,我们执行shell命令时,其输出总是标准输出或者标准错误,因此总是会将输出的信息,不论是正常信息还是报错信息,都会打印在屏幕上,但有时我们不希望这些输出打印在屏幕上,而是希望这了信息能被保存到指定的文件中,这就是输出重定向。

 那么,究竟什么是标准输入/标准输出/标准错误呢?下面为大家一一介绍。

1.标准输出

 在终端输入

echo hello
hello

 终端会打印hello,但是我们echo出来的hello,到底去了什么地方?

 每个基于 Unix 的操作系统都有一个“输出的默认位置”的概念。由于这个短语比较啰嗦,所以大家都称它为“标准输出”或“stdout”,读作standard out。 shell(可能是 bash 或 zsh)一直在监视默认输出位置。当 shell 在标准输出那里看到新的输出时,它会将其打印在屏幕上,以便我们可以看到它。否则,shell不去监视标准输出位置,echo hello会将“hello”发送到那个默认位置,但我们却看不到。

2.标准输入

 标准输入(stdin)是命令监听信息的默认位置,尝试在终端输入cat,不添加任何参数

cat 
hello
hello
1234
1234

 不论输入什么,shell会将你的输入再次打印,shell怎么读取到你的输入呢,和标准输出类似,shell会一直监视默认输入位置,一有新的输入进来,shell便会把数据读进来,然后输出到stdout

3.标准错误

 标准错误(stderr)和stdin/stdout很像,区别就是stderr是错误信息存储的地方,例如, cat一个不存在的文件

cat ttt
cat: ttt: No such file or directory

 似乎和stdout没什么两样,但是我们借助管道来验证一下,在linux中,管道是将一个命令的stdout连接到另一个命令的stdin,可以使用管道符号|来完成这个操作,例如

echo "hello there"
hello there
echo "hello there" | sed "s/hello/hi/"
hi there

 这里的sed是将hello替换为hi,上面命令中,echo将hello there传输到标准输出,然后通过管道将hello there将其作为标准输入传递给sed,sed对其进行操作后,再输出到标准输出。

 那cat打印出的信息,到底是stdout呢还是stderr呢?看这个命令

cat ttt | sed "s/No such/hello world/"
cat: ttt: No such file or directory

  如果 cat ttt打印出来的信息是stdout的话,那No such会被替换成hello world,但似乎并没有被替换到,是的,cat ttt打印出的信息,是stderr而不是stdout。管道只会接收stdout,而不会接收stderr

4. 重定向

 这里我们终于可以知道什么是重定向了,默认情况下,我们shell执行的命令的输出一定会到stdout或者stderr,如果我们不想让信息输出到stdout或者stderr,那就要用到重定向了,我们可以使用>将输出进行重定向。

$ echo "hello world" > file
$ cat file
hello world

 这行命令做了两件事

  • file不存在,则创建
  • file存在,则用hello world覆盖其内容

 如果只是想追加内容而不是覆盖原有内容,则可以使用>>

$ echo "hello world" > file
$ cat file
hello world
$ echo "go go go" >>file
$ cat file
hello world
go go go

 其中,如果>或者>>前不添加文件描述符,则默认是将标准输出重定向到file,如果想重定向stderr,则需要表示为1 > file或者2 > file

5.文件描述符

 文件描述符(File descriptor)是表示输入/输出源的正整数,例如stdin是0,stdout是1,stderr是2,这些数字是由POSIX标准定义的,MacOS和Linux都实现了这个标准的一部分。

如果想将输出重定向到某一文件描述符,则需要借助>&运算符并跟上文件描述符来完成

# Redirect stdout to stdout (FD 1)
echo "hello there" >&1
hello there
# Redirect stdout to stderr (FD 2)
echo "hello there" >&2
hello there

 这和上面的输出重定向到某一文件基本一样,只不过重定向的最终目标变成了stdoutstderr,让我们继续通过管道看看这两个输出有什么区别

echo "no changes" >&1 | sed "s/no/some/"
some changes
# Redirect to stderr, so it does not come through
echo "no changes" >&2 | sed "s/no/some/"
no changes

 原理还是和上面一样,第一行将输出重定向到了标准输出,所以管道会将其传递给sed,第二行经echo的输出重定向到了标准错误,管道无法传递。

6.将stderr重定向到stdout

 如果一个脚本,将输入的参数的三个参数分别重定向到了stdout stderr stdout,那么一个命令就出现了两种不同的输出,使用管道时,就无法传递全部的输出作为下个命令的输入,我们编写一个这样的command

#!/bin/bashfor f in $@; doif [[ $f == "file2" ]]; thenecho "stderr file2" >& 2elseecho "stdout $f"fi
done
$ bash command file1 file2 file3
stdout file1
stderr file2
stdout file3

 用管道来处理,则只会处理部分,file2是stderr,无法被管道抓取。

$ bash command file1 file2 file3 | sed "s/^/Robot says: /"
stderr file2
Robot says: stdout file1
Robot says: stdout file3

 我们可以通过2>&1将标准错误重定向给标准输出,例如

cat ttt 2>&1 | sed "s/No such/hello world/"
cat: ttt: hello world file or directory

 由于stderr重定向到了stdout,管道就将输出的信息传递给了sed,sed做了处理并输出到stdout

同样的,对于command也可以这样做

dexu_tian@VM-4-10-ubuntu:~/Tmp/outputRedirect$ bash ./command file1 file2 file3 2>&1 | sed "s/std/Robot says: std/"
Robot says: stdout file1
Robot says: stderr file2
Robot says: stdout file3

7. 常用用法

 比较常见的用法是将一个命令的stdoutstderr都重定向到某一个文件中,那么它的写法就应该是这样的

cmd > logfile 2>&1

 cmd的stdout将会被重定向到logfile,stderr将会被重定向到stdout,由此实现了stderrstdout被重定向到了logfile.

 像2>&1一样,如果想重定向文件描述符,则需要表示为N >&M,其中N和M是文件描述符,其为1和2时,就是在重定向stdout和stdin了。如果M不是文件描述符,则使用文件名N>filename

8.输出静音

 我们可以通过这种重定向的语法,将所有的输出重定向到/dev/null, 它会吞下所有接收到的内容并且不做任何操作。

echo "hello there" >/dev/null

以上就是本文所要分享的内容,希望大家每天坚持进步~

相关文章:

一文搞懂Linux的标准输出/错误重定向

前言 今天在写一个脚本时,需要将shell命令和可执行程序的输出重定向在某一个log文件中,但是遇到了点小问题,索性就研究下输出重定向到底怎么回事。 Linux系统,有一个非常重要概念,就是一切皆文件。在使用shell脚本时&a…...

【OJ】计数的梦

📚Description: Bessie 处于半梦半醒的状态。过了一会儿,她意识到她好像在数羊,不能入睡。Bessie的大脑反应灵敏,仿佛真实地看到了她数过的一个又一个数。她开始注意每一个数码:每一个数码在计数的过程中出现过多少次…...

【项目实战】MySQL使用CONCAT字符串拼接函数实现与特殊字符的拼接

一、需求说明 因为有新功能需要上生产环境,总有一些乱七八糟的兼容历史数据的活要去做,比如以下。 需要批量的更新数据库中某个字段(如id列中原来是ABCDEFG,需要改成[“ABCDEFG”]), 没错,就是…...

OpenCV实战(11)——形态学变换详解

OpenCV实战(11)——形态学变换详解0. 前言1. 腐蚀和膨胀运算1.1 腐蚀和膨胀基础1.2 使用形态学滤波器执行图像腐蚀和膨胀运算2. 开运算和闭运算2.1 使用形态学滤波器执行图像开运算和闭运算3. 形态学变换应用3.1 使用形态学滤波器检测边缘3.2 使用形态学…...

SPI协议详解(Standard SPI、Dual SPI和Queued SPI)

1、标准SPI 1.1、SPI接口的引脚 (1)SCLK:时钟线; (2)MOSI(master output slave input):主设备输出,从设备输入,单向传输; (3)MISO(master input slave output):主设备输入,从设备输…...

【代码随想录二刷】Day15-二叉树-C++

代码随想录二刷Day15 今日任务 层序遍历 226.翻转二叉树 101.对称二叉树 语言&#xff1a;C 层序遍历 102.二叉树的层序遍历 class Solution { public:vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>> res;if(root NULL) …...

C++为什么能重夺年度语言?

目录一、爷青回1、年初依旧很多大新闻&#xff0c;其中一条就是TIOBE把年度编程语言颁给了C。2、这是什么概念&#xff1f;那一年Java的流行指数是14%。二、C为什么衰落三、C为什么重新流行1、C为什么重新流行起来了呢&#xff1f;2、C究竟做对了什么呢&#xff1f;3、根本原因…...

视频监控实时接入——以海康威视为例(2023.2.16)

海康威视实时视频监控接入学习 2023.2.16引言1、视频协议简介1.1 RTSP——Real Time Streaming Protocol&#xff08;实时流传输协议&#xff09;1.2 RTMP——Real Time Messaging Protocol&#xff08;实时消息传输协议&#xff09;1.3 HLS——HTTP Live Streaming&#xff08…...

推荐系统[一]:超详细知识介绍,一份完整的入门指南,解答推荐系统是什么。

1. 推荐算法的初步理解 如果说互联网的目标就是连接一切,那么推荐系统的作用就是建立更加有效率的连接,推荐系统可以更有效率的连接用户与内容和服务,节约了大量的时间和成本。 1.1 推荐系统主要解决问题 任务一:挖掘长尾:帮助用户找到想要的物品(音乐、商品、新闻),…...

新手小白入门必看!如何批量注册Twitter账号?

Twitter是目前海外比较流行的社媒营销平台&#xff0c;所以很多从事跨境电商行业的朋友都需要利用多个Twitter账号来推广营销&#xff0c;但是注册和管理多个Twitter账号其实并不是简单的事情。龙哥将会在这里详细讲讲该如何批量注册并且让这些账号不会因为关联被封号&#xff…...

虚拟环境的创建以及labelme的使用教程

本来打算是将这两部分分开的&#xff0c;但写完虚拟环境的创建似乎字数太少了&#xff0c;不过二者有关联&#xff0c;所以就放一起了。简单介绍一下&#xff0c;虚拟环境的创建有win11系统已经Ubuntu系统&#xff0c;labelme教程包括了下载及其使用的全部流程&#xff0c;以及…...

CSS中的BFC详细讲解(易懂)

带你用最简单的方式理解最全面的BFC~~~1.先了解最常见定位方案普通流元素按照其在 HTML 中的先后位置至上而下布局行内元素水平排列&#xff0c;直到当行被占满然后换行&#xff0c;块级元素则会被渲染为完整的一个新行所有元素默认都是普通流定位浮动元素首先按照普通流的位置…...

华为3面,官网显示面试通过了...开始泡池子,进入漫长等待期

背景&#xff1a; 现在双非本科&#xff0c;非计算机科班&#xff0c;有算法方面的奖&#xff0c;有嵌入式开发经历&#xff0c;官网显示面试通过&#xff0c;短信说录用情况在十个工作日内告知&#xff0c;看别人的说法应该是泡池子了。 全程视频面试&#xff0c;一天面完三…...

【新2023】华为OD机试 - 构成的正方形数量(Python)

构成的正方形数量 题目 输入 N 个互不相同的二维整数坐标, 求这 N 个坐标可以构成的正方形数量。(内积为零的两个向量垂直) 输入 第一行输入为 N,N 代表坐标数量,N为正整数。N <= 100 之后的 K 行输入为坐标 x y以空格分隔,x, y 为整数, -10 <= x, y <= 10 输…...

ElasticSearch之RestClient操作索引库和文档

前言&#xff1a;上文介绍了使用DSL语言操作索引库和文档&#xff0c;本篇文章将介绍使用Java中的RestClient来对索引库和文档进行操作。 希望能够加深自己的印象以及帮助到其他的小伙伴儿们&#x1f609;&#x1f609;。 如果文章有什么需要改进的地方还请大佬不吝赐教&#x…...

Lp正则化

一、L1 和 L2范数&#xff08;norm&#xff09;A norm is a mathematical thing that is applied to a vector. The norm of a vector maps vector values to values in [0,∞). In machine learning, norms are useful because they are used to express distances: this vect…...

云原生 -- Docker进阶(Docker-compose,Docker网络简单介绍)

Dockerfile的构建过程 每条保留字段必须为大写字母。Dockerfile每行只支持一条指令&#xff0c;但是每条指令可以带多个参数&#xff0c;并且每条保留字指令后面至少要带有一个参数。从上到下依次执行。每条指令都会创建一个新的镜像层&#xff0c;并提交新的镜像。 大致流程…...

taskset命令:让进程运行在指定CPU上

1. 操作场景 taskset命令&#xff0c;可用于进程的CPU调优&#xff0c;可以把云服务器上运行的某个进程&#xff0c;指定在某个CPU上工作。 本节操作指导用户使用taskset命令让进程运行在指定CPU上。 2. 操作步骤 2.1. 执行如下命令&#xff0c;查看云服务器CPU核数。 cat …...

Pod基本概念与Pod应用生命周期

Pod是一个逻辑抽象概念&#xff0c;kubernetes创建和管理的最小单元&#xff0c;一个Pod由一个容器或多个容器组成。特点&#xff1a;一个Pod可以理解为是一个应用实例&#xff0c;提供服务Pod中容器始终部署在一个Node上Pod中容器共享网络、存储资源Pod主要用法&#xff1a;运…...

DDL 数据定义语言

DDL 数据定义语言 目录概述一、库的管理1、库的创建2、库的修改【一般不修改&#xff0c;容易出现错误】3、库的删除二、表的管理【重要】1、表的创建2、表的修改3、表的删除4、表的复制 【可以跨库复制】练习题概述 数据定义语言 库和表的管理 一、库的管理 创建、修改、删除…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...