shell中的输出重定向

时间:2021-12-03 06:08:52

shell中默认有三个标准设备:标准输入(STDIN)、标准输出(STDOUT)、标准错误(STDERR)。

在Linux系统中,一切(或几乎一切)都是文件。因此,标准输入的文件描述符是0,标准输出的文件描述符是1,标准错误的文件描述符是2。

shell命令的输出默认显示在终端显示器上,示例如下:

$ echo hello world
hello world

可以使用输出重定向符号把标准输出重定向到一个文件,示例如下:

$ echo hello world > log.txt
$ cat log.txt
hello world

标准输出的文件描述符为1,该值为输出重定向符号的默认值,可以省略。因此,上面的示例等效为:

$ echo hello world 1> log.txt  (这里的 1 与 > 符号之间不能有空格)
$ cat log.txt
hello world

当然我们也可以使用输出重定向符号对标准错误进行重定向,但必须在 > 符号前明确指定标准错误的文件描述符,即使用 2> 对标准错误进行重定向。

既然提到了输出重定向,就必须说明输出重定向符号有两种:> 符号 和 >> 符号。区别如下:

  • > file:打开file文件时会先清空文件,然后添加输出信息。
  • >> file:打开file文件时不清空文件,直接在file文件结尾处添加输出信息。

示例如下:

$ cat log.txt
hello world
$ >> log.txt
$ cat log.txt
hello world
$ > log.txt
$ cat log.txt
$

如果愿意,可以将STDOUT和STDERR输出重定向到同一个输出文件。为此,bash shell提供了一个特殊的重定向符号,即 &> 符号。

使用 &> 符号,命令生成的所有输出都发送到同一位置,包括数据和错误。而且bash shell自动使错误信息的优先级高于标准输出,这样你就可以一起查看错误信息,而不用在整个输出文件中查找。貌似对cat命令的输出不起作用。

重定向到某个文件描述符

重定向到某个文件描述符时,必须在文件描述符前面添加 & 符号。必须这样的原因:因为我们知道类似1,2这样的文件描述符也是标准的Linux文件名称,添加 & 符号以做区分。

这样一来,我们经常在脚本中见到的 2>&1 命令是不是很好理解了?是的,就是把标准错误重定向到标准输出。这不是废话嘛,标准错误默认就跟标准输出在同一个位置━━终端显示器。对的,使用终端显示器作为输出设备时是这样的,如果我们要把输出重定向一个文件中时,我们就要使用 2>&1 命令了。说到这里,问题来了,如下:

command > file 2> file 与 command > file 2>&1 效果一样吗?

效果貌似一样:因为不管是command产生的标准输出信息还是标准错误信息都重定向到了file文件里。确实如此,但也有让人意料之外的地方:

command > file 2> file 命令把STDOUT和STDERR都直接送到file文件中,file文件会被打开两次,这样STDOUT和STDERR会相互覆盖。该命令执行时相当于两个进程同时向同一个文件中写数据,你写你的,我写我的,也不进行同步,写完拉倒。打开文件一看,数据重叠,乱七八糟。示例如下:

$ cat badfile log.txt > log 2> log
$ cat log
hello world
: No such file or directory
$

command > file 2>&1 命令把STDOUT直接送往file文件,而STDERR经由STDOUT的通道把数据信息送到file文件中。此时,file文件只被打开了一次,因此标准输出数据和标准错误数据不会相互覆盖,而是井然有序。示例如下:

$ cat badfile log.txt > log 2>&1
$ cat log
cat: badfile: No such file or directory
hello world
$

从I/O效率上来说,command > file 2> file 相比于 command > file 2>&1 要低,而且会出现数据相互覆盖的情况。因此,我们一般会使用后面这条命令。

在同一个命令中多次进行输出重定向

如果我们在同一个命令中进行了多次输出重定向操作,会出现什么情况呢?最终命令的输出会重定向到最后一次重定向的位置。读起来很拗口,但实际操作一下就明白了。

$ ls (空目录)
$ tty (查看终端显示器名称)
/dev/pts/7
$ echo hello world > log.txt 1>/dev/pts/7 2>&1
hello world
$ ls
log.txt
$ cat log.txt
$

echo hello world > log.txt 1>/dev/pts/7 2>&1 命令首先把标准输出重定向到log.txt文件,由于当前目录下并不存在该文件,因此会创建该文件,并把文件清空;接着命令又把标准输出重定向到了终端显示器;最后又把标准错误重定向到了标准输出。因此命令的输出还是被发送到了终端显示器上,命令结束,文件关闭,结果log.txt文件里什么数据都没有写入,只是创建了一个空白的文件。

最后说明

最后要说明的是,使用 > 符号进行重定向时,shell并不总是轻松潇洒地清空重定向文件,比如/proc目录下的文件,shell一般会检查要写入的数据,如果要写入的数据或者写入的方式有问题,shell可能会提醒你,也可能不提醒你。

有提示的示例如下:

root@lj:~# cat /proc/sys/net/ipv6/route/max_size
4096
root@lj:~# echo hello > /proc/sys/net/ipv6/route/max_size
-bash: echo: write error: Invalid argument
root@lj:~# cat /proc/sys/net/ipv6/route/max_size
4096
root@lj:~#

没有提示的示例如下:

# cat /proc/sys/net/netfilter/nf_conntrack_udp_timeout
180
# echo hello > /proc/sys/net/netfilter/nf_conntrack_udp_timeout
# cat /proc/sys/net/netfilter/nf_conntrack_udp_timeout
180
#

因此,即便有时候某条命令执行完成后没有任何提示信息,貌似成功了,我们还是应该检查一下相关数据或文件,看看是否真的执行成功了。

shell中的输出重定向的更多相关文章

  1. 学习笔记之Shell脚本的输出重定向

    shell http://baike.baidu.com/link?url=qN3THt5ZJhQtwRJJkakWdz5-vZp4V9H3OmNP97XNhaoL-dqU-6rrFrYfHXmYv6 ...

  2. shell 中的>文件重定向符 和 标准输入、输出、错误以及 2&1 的含义*

    http://www.cnblogs.com/chenmh/p/5382044.html 问:其中 的2>&1是怎么回事? . test.sh > test.log 2>&a ...

  3. shell编程-输入/输出重定向(十一)

    linux中文件描述符 linux跟踪打开文件,而分配的一个数字,通过这个数字可以实现对文件的读写操作 用户可以自定义文件描述符范围是:3-max,max跟用户的ulimit –n 定义数字有关系,不 ...

  4. Linux中的输出重定向

    标准输入输出: 键盘        /dev/stdin        0       标准输入 显示器    /dev/stdout      1       标准输出 显示器    /dev/st ...

  5. Linux Shell 下的输出重定向

    linux 环境中支持输入输出重定向,用符号<和>来表示. 0.1和2分别表示标准输入.标准输出和标准错误信息输出, 可以用来指定需要重定向的标准输入或输出,比如 2>a.txt 表 ...

  6. shell中echo输出换行的方法

    [~]#echo "Hello world.\nHello sea" Hello world.\nHello sea [~]#echo -e "Hello world.\ ...

  7. shell中&gt&semi;&sol;dev&sol;null 2&gt&semi;&amp&semi;1

    本文转自http://www.kissyu.org/ 背景 我们经常能在shell脚本中发现>/dev/null 2>&1这样的语句.以前的我并没有去深入地理解这段命令的作用,照搬 ...

  8. linux下详解shell中&gt&semi;&sol;dev&sol;null 2&gt&semi;&amp&semi;1

    前言 相信大家经常能在shell脚本中发现>/dev/null 2>&1这样的语句.以前的我并没有去深入地理解这段命令的作用,照搬照用,直到上周我将这段命令不小心写成了2>& ...

  9. &lbrack;转帖&rsqb;shell 中的&gt&semi;&sol;dev&sol;null 2&gt&semi;&amp&semi;1 是什么鬼?

    shell 中的>/dev/null 2>&1 是什么鬼? http://blog.jobbole.com/109355/ 背景 我们经常能在shell脚本中发现>/dev/ ...

随机推荐

  1. EF6 CodeFirst&plus;Repository&plus;Ninject&plus;MVC4&plus;EasyUI实践&lpar;完&rpar;

    前言 这一篇是本系列的最后一篇,虽然示例讲到这里就停止呢,但对于这些技术的学习远不能停止.虽然本示例讲的比较基础,但是正如我第一篇说到的,这个系列的目的不是说一些高端的架构设计,而是作为一个入门级,对 ...

  2. Autolayout-VFL语言添加约束-备

    一.VFL语言简介 VFL(Visual format language)语言是苹果为了简化手写Autolayout代码所创建的专门负责编写约束的代码.为我们简化了许多代码量. 二.使用步骤 使用步骤 ...

  3. java单元测试(Junit)

    JUnit是由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression testing framework),供Java开发人员编写单元测试之用. 对不同性质的被 ...

  4. 【Android开发日记】第一个任务Android Service!Service靴&plus;重力感应器&plus;弹出窗口&plus;保持执行

    前言: 近期在写一个小程序,需求是手机摇一摇就弹窗出来.第一次使用了Service,学习了两天,实现了Service弹窗,开机启动,Service启动和销毁,Service保持一直执行. 满足了自己的 ...

  5. 微信小程序天坑--图片汉字命名

    图片用汉字命名的,在开发者工具中是显示的,但是,在真机的微信中,是不会显示的. 大写的尴尬,微信小程序开发者工具对于做微信的UI来说,就是一个天坑,在电脑上漂漂亮亮的,到手机上各种意想不到的情况.

  6. &lbrack;转&rsqb;简单科普私钥、地址、助记词、Keystore的区别

    本文转自:https://www.jianshu.com/p/d0a4a44685d3 很多人保管不好自己的虚拟财产,发生丢币的情况,很多都是因为不清楚私钥的概念. 私钥(Private Key) 比 ...

  7. 排查 Maxwell can not find database 并且使用 MySQL binlog 解决相关问题

    目前我们在使用 Maxwell 在读线上机器的 binlog 同步我们的离线数据库. 这次错误定位上,首先线要确定问题是发生在生产者 还是队列 还是消费者.经过查看各机器上任务的运行日志,定位到了问题 ...

  8. SharePoint 2013 批量导入、删除帐号

    删除一个group里所有的帐号: cls ########################### # "Enter the site URL here" $SITEURL = &q ...

  9. (转载)设计模式之-策略模式(Strategy)

    原文:http://blog.sina.com.cn/s/blog_48df74430100t2m7.html 前言 部门组织培训,<Effective Java>,每人每天给大家讲解一节 ...

  10. Maven的pom&period;xml文件结构之基本配置parent和继承结构&lbrack;转&rsqb;

    1.Maven项目的继承 Maven项目之间不仅存在多模块的聚合关系,而且Maven项目之间还可以存在相互继承的关系. Maven项目之间的继承关系通过<parent>表示,在子Maven ...