Linux管道与重定向
Shell里边的文件输入输出重定向什么的一直都是一知半解,只知道个>
代表覆盖重写而>>
代表对文件中追加,并不覆盖。
今天在用mplayer
播放提示音希望不显示输出,从网上看到这个命令瞬间泪奔
这到底什么个含义,决心花点时间来好好补补这一块的内容。
I/O 重定向
通常在Shell命令中最常见到三种输入输出类型,标准输入(stdin),标准输出(stdout)以及标准错误输出(stderr),感觉跟C/C++里边文件划分类似。
stdin
一般指command
接受的输入流,stdout
指command
正常输出情况,默认输出显示到终端,stderr
则是command
的错误输出,默认也是输出显示到终端。
而文件描述符则是与一个打开的文件或数据流相对应的一个整数,系统将0,1,2分别与标准输入,标准输出以及标准错误输出相对应。
输出重定向
重定向符号>
以及>>
意为输出重定向,包括标准输出以及标准错误输出,也是一般命令中比较常见的情况,与stdout
及stderr
两两组合就是四种情况
1>
表示标准输出重定向,覆盖1>>
表示标准输出重定向,追加2>
表示标准错误输出重定向,覆盖2>>
表示标准错误输出重定向,追加
其中默认缺省表示标准输出,即>
与>>
与前两个命令含义相同。
由于>
命令会将存在的文件进行覆盖,我们可以通过set -o noclobber
来进行相应的限制。设置成功后,如果再次进行重定向到已有的文件中就会报错,这时便
需要通过>|
来进行命令。
另外就是&
的使用,不过这里&
并不是指将命令在后台运行。&>
和&>>
可以将stdout
与stderr
重定义到同一文件中。这样就不用一个一个的指定了。
另一种方式这样2>&1
,表示将stderr
重定向到stdout
的位置,即stdout
输出到哪,stderr
也输出到哪。“IBM developerWorks”上有个很不错的例子,
这两个命令stderr
重定向的位置并不相同。第一个先将stderr
定向到stdout
,而此时stdout
的定向是默认的终端,所以stderr
被定向到终端,之后
stdout
被重定向到文件output
中。第二条命令先将stdout
定向到文件output
,然后将stderr
定向到stdout
上,因此stderr
最终被定向到文件中。
最后要提的是/dev/null
这个空设备,被称为bit bucket
或者黑洞,正如它名字所示,它会将一切写入到其中的数据流吞噬并丢弃,常用来将stdout
和stderr
内容丢弃掉。但/dev/null
是一个文件而不是目录,所以不能类似的将文件mv
其中来删除。
关于tee
命令,其实也有时候,我们希望输出不仅重定向到文件中,而且希望它能够在终端中显示出来,这样就不需要重定向后再继续打开文件来检查是否出问题。
这时候我们可以用到tee
命令。man tee
的解释是这样,从标准输入复制到每一个文件并复制到标准输出中。例如这样
而在一般的Linux tricks 有时候会利用tee
来帮忙解决vim时忘记加sudo
。可以这样子使用:w !sudo tee %
。其中:w
将更改后的文件作为标准输出传递给tee,
而%
代表当前文件名,然后利用sudo
权限把标准输出传到当前文件中去。
输入重定向
输入重定向自己平常到用的不多,可以用<
来接受文件内容来作为标准输入。
<<
则通常与一个单词来构成一个结束标识符来接受终端的输入。如
管道
相对与重定向,管道就没那么复杂了。一般来讲可以用|
来将上一个命令的stdout
作为当前命令的stdin
来使用。但需要注意的是,stderr
是不会被处理的。
关于xargs
。xargs
比较牛的地方是可以将标准输入来作为命令的参数传到命令中,而管道传给命令的只能是命令接受的stdin
。xargs
通常与find
连用来查找文件。
记忆中自己用到xargs
的地方是在Redis。由于Redis删除key的时候不支持通配符,而上万条的数据又不能一个一个手动删除,所以可以利用xargs
先用keys
命令找到数据库中所有匹配数据,然后通过xargs将输出作为del
的参数来进行删除。
参考资料:学习Linux,101:流,管道,重定向
27 Oct 2015
Post by: MetaCoder