Linux Shell编程 | 重定向看这篇就够了 /dev/null 2>&1

本文深入讲解Linux中的重定向概念,包括标准输入、标准输出及错误输出的重定向方法。通过实例展示如何使用重定向控制输出信息,实现命令执行结果的灵活处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

重定向

目录/home/case1下只有一个文件test1.log,无test2.log ,我们执行命令cat test1.log test2.log,结果如下图

上图中我们提取三个信息:标准输入(键盘输入)、标准输出(屏幕显示的正确信息)、错误输出(屏幕显示的错误信息)

我们从专业角度介绍下相关概念:

文件描述符(file description,fd)

相信每个人在学Linux时,都看过这样一句话:Linux 下,一切皆文件。

既然在Linux操作系统中,一切都被抽象成了文件,那么对于一个打开的文件,应用程序就通过文件描述符来对应上。当应用程序请求内核打开/新建一个文件时,内核会返回一个文件描述符用于对应这个打开/新建的文件,读写文件也是需要使用这个文件描述符来指定待读写的文件。

在Linux系统中,就分别使用描述符0、1、2来表示,这3个描述符默认的目标文件(设备)分别是/dev/stdin、/dev/stdout、/dev/stderr,它们分别是各个终端字符设备的软链接。

文件描述符类型默认情况对应设备位置
0标准输入(standard input)键盘输入/dev/stdin
1标准输出(standard output)输出到屏幕/dev/stdout
2错误输出(error output)输出到屏幕/dev/stderr

我们也可以cd /dev 看到具体的文件描述符

我们再看下文章开头那张图,执行shell命令是从键盘获得输入cat test1.log test2.log,并且将正确结果和错误结果均输出到屏幕。

那么,这里我们就可以通过更改文件描述符的指向,实现输入、输出的重定向,从而控制输出信息在屏幕的回显和写入到指定文件。

具体操作格式如下:

标准输出重定向

> 把标准输出重定向到新文件中

cat test1.log test2.log 1 >info.log    #将1(标准输出)指向文件log.txt,那么标准的输出就会输出到log.txt中 

>> 把标准输出追加到文件中

cat test1.log test2.log 1 >>info.log    #将1(标准输出)指向文件log.txt,那么标准的输出就会追加到log.txt中

注: 1也可省略不写,默认就是标准输出,

           cat test1.log test2.log 1 >ok.log  = cat test1.log test2.log >ok.log 

           cat test1.log test2.log 1 >>ok.log  = cat test1.log test2.log >>ok.log

实例1:

实例2:

错误输出重定向

> 把错误输出重定向到新文件中

cat test1.log test2.log 2 >err.log    #我们将2(错误输出)指向文件err.log,那么错误的输出就会输出到err.log中

>> 把错误输出追加到文件中

cat test1.log test2.log 2 >>err.log    #我们将2(错误输出)指向文件err.log,那么错误的输出就会追加到err.log中

实例3:

实例4:

在上述实例1、实例2中,我们将标准输出重定向到了ok.log文件中,所以屏幕(控制台)只剩下了错误提示。

在例3、实例4中我们将错误输出重定向到了err.log文件中,所以屏幕(控制台)只剩下了正确提示。

我们也可以把操作放在一个命令执行,将标准输出重定向到ok.log文件中,同时将错误输出重定向到err.log

实例5:

Tips:>和>>区别

当使用>时,会判断右边的文件log.txt是否存在,如果存在就删除掉,再重新创建一个log.txt;如果不存在,则直接创建log.txt。

当使用>>进行时,会判断右边的文件log.txt是否存在,如果存在也不会删除,而是在log.txt结尾继续追加新的内容,如果不存在,则直接创建log.txt。

有时候我们不喜欢屏幕回显任何信息,也不需要把这些信息写到文件中去,我们就可以用到/dev/null来处理。

何为/dev/null?

/dev/null:表示的是一个黑洞,也就是空设备文件,通常用于丢弃不需要的数据输出, 或者用于输入流的空文件,可想象为回收站,把不要的数据统统扔进去

cat test1.log test2.log 1>/dev/null  #把标准输出扔掉,屏幕仅显示错误输出信息,且不会保存到任何文件

cat test1.log test2.log 2>/dev/null  #把错误输出扔掉,屏幕仅显示标准输出信息,且不会保存到任何文件

cat test1.log test2.log >/dev/null 2>&1 #把标准输出、错误输出均扔掉,屏幕不显示任何信息,且不会保存到任何文件

上面>/dev/null  2>&1是什么意思呢,也就是1> /dev/null 2>&1,详细解释下:

重定向绑定2>&1

使用&将两个标准输出和错误输出绑定到一起,使其输出到同一个文件描述符

实例6:

执行过程:这条语句是从左到右依次执行的,开始错误输出会输出到标准输出,此时标准输出的内容会包含错误输出,最后/dev/null仅被标准输出打开。

所以执行结果是:屏幕不会回显任何信息,也不会有把任何信息输出到文件中。

注意!!!

为什么 >/dev/null 2>&1不等同于 2>&1 >/dev/null

上文已经说过这条语句执行顺序是从左往右,2>&1写在/dev/null前面,错误输出指向标准输出,还是会回显在屏幕上,而只会把标准输出扔到/dev/null

说到这里,有的人就仍不住抛出疑问了,这么写花里胡哨,还容易出错,何不像下面这样去写简单粗暴:

为什么>/dev/null 2>&1不要写为1>/dev/null 2>/dev/null

实例7:

实例8:

原因:这种写法,其实标准输出和错误输出会抢占输出同一个文件的管道,都打开同一个文件/dev/null,有相互复覆盖的影响,

从实例7、实例8可以看到,随时有覆盖、回显错误输出等情况发生。所以我们只能不用这种写法,嘿嘿。

exec绑定重定向

我们发现,上面讲的输入输出重定向,都是只对当前执行的那条指令有效。那如何使得接下来所有命令有效呢?

我们可以扩展自己新的描述符,对文件进行读写操作。我们可以通过exec命令绑定来处理这种情况。

实例9:

绑定文件描述符

exec 8>&1  #将标准输出与文件描述符8绑定

查看文件描述符

ls /proc/self/fd/    #可以查看到文件描述符8

将标准输出绑定到文件

exec 1>log  #将接下来所有命令的标准输出,都输出到log文件中

实例10:

那如何解绑呢?

实例11:

解绑恢复标准输出

exec 1>&8  #恢复标准输出

关闭文件描述符

exec 8>&- #关闭文件描述符8

&>/dev/null

不管是什么文件描述符,都可以重定向到/dev/null

输入重定向

介绍了输出重定向,输入重定向也很好理解了,你看就符号(<)和输出重定向(>)是反的

<  input 以input文件作为标准输入

unzip test1.zip test2.zip 0 <log.txt    #将log.txt文件内容作为标准输入

注: 0也可省略不写,默认就是标准输入,

 unzip test1.zip test2.zip 0 <log.txt  = unzip test1.zip test.zip  <log.txt  

实例12:

让cat读取input.txt的内容,并写到log文件中。

<< delimiter 从标准输入中读入,直到遇到delimiter分隔符

delimiter分隔符可以是任意字符,如over

unzip test1.zip test2.zip  <<over    #从标准输入中读入,直到遇到over分隔符,当遇到over分隔符

实例11:

我们看下cat >info的例子,cat 的作用就是将标准输入(键盘)回显到标准输出(屏幕)上,cat >info就是讲内容写入到info文件中。

过程中,我们只能使用ctrl+c才能结束输入。

实例13:

实例14:

我们在实例11的基础上加上<<over,变为cat >info<<over,通过下面例子演示我们看下这里的分割符(over)的作用

过程中,我们可以不使用ctrl+c结束输入,可以通过键盘输入over结束输入

使用场景

1、nohup结合

2、打印屏幕信息打印留做日志分析

3、防止后台执行程序打印信息干扰工作

4、过滤错误信息

5、将csv格式的数据文件自动转换为sql insert语句

6、等等

(待最近补充)

一张图总结

讲了这么多,文章最后用一张图总结一下:

(待最近补充)

very nice !ery nice !

shell脚本中发现>/dev/null 2>&1这样的语句,在工作中用到最多的就是nohup command >/dev/null 2>&1 &命令,希望大家能够好好掌握。

nohup /usr/local/kafka_2.11-2.3.0/bin/kafka-server-start.sh /usr/local/kafka_2.11-2.3.0/config/server.properties 1>/dev/null 2>&1&

tar -zxvf mysql-5.7.31-el7-x86_64.tar.gz >/dev/null 2>&1

yum -y install gcc >/dev/null 2>&1

port=6379
    npid=$(netstat -nlp | grep :$port | awk '{print $7}' | awk -F"/" '{ print $1 }');
    if [  -z  "$npid"  ] && [ "$npid" -gt 0 ] 2>/dev/null;  then
        echo "kill  -9  $npid"
        kill  -9  $npid;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我自人间漫浪

你的鼓励将是我创作的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值