Linux之管道与重定向
一、重定向输出
可以通过操作符>将标准输出1和标准错误输出2重定向到某个文件,比如:
#ls -l > lsoutput.txt
上面命令将标准输出重定向到文件lsoutput.txt中。
当然,也可以将标准文件描述符以外的文件描述符进行重定向,不过这种情况很少见。
默认情况下,如果lsoutput.txt文件已经存在,则它的内容将被覆盖,如果想将输出内容附加到一个文件中,则可以使用>>操作符进行输出重定向,比如:
#ls -l >> lsoutput.txt
上面命令将输出附加到指定文件的尾部。
有时候会用重定向输出将命令产生的错误重定向输出到某个文件以屏蔽屏幕输出。
下面命令将标准输出和错误输出分别重定向到不同的文件中:
#kill -HUP 1234 > killout.txt 2>killerr.txt
如果想把两组输出都重定向到一个文件中,你可以使用>&操作符来结合两个输出,比如:
#kill -l 1234 >killouterr.txt 2>&1
这条命令将标准输出和标准错误输出都重定向到同一个文件中。请注意操作符出现的顺序,这条命令的含义是“将标准输出重定向到文件killouterr.txt,然后将标准错误输出重定向到与标准输出相同的地方。”如果顺序有误,重定向将不会按照预期执行。
还有一种将标准输出或标准错误输出丢弃的好办法,比如:
#kill -l 1234 >/dev/null 2>&1
回收站/dev/null就像黑洞一样,任何东西进入后都肉包子打狗有去无回。
二、重定向输入
我们还可以重定向标准输入,比如:
#more < killout.txt
不过上面的命令似乎意义不大,因为more本来也可以接受文件名为参数,我就是刷一下存在感而已。
三、管道
我们 可以用管道操作符|来连接进程。Linux与MS-DOS不同,在Linux下通过管道连接的进程可以同时运行,并且随着数据流在它们之间的传递可以自动地进行协调。
下面以使用sort命令对ps命令的输出进行排序来说明管道的意义,假设不用管道就必须要分几个步骤来实现:
#ps > psout.txt
#sort psout.txt > pssort.out
更精巧的一个解决方案是用管道来连接进程,比如:
#ps | sort > pssort.out
如果想在屏幕上分页显示输出结果,我们可以再连接第三个进程more,将它们都放在同一个命令行上,可以如此:
#ps | sort | more
允许连接的进程数目是没有限制的。假设我们想看看所有系统中运行的进程的名字,但不包括shell本身,可以如此:
#ps -xo comm | sort | uniq | grep -v sh | more
这个命令首先按字母顺序排序ps命令的输出,再用uniq命令去除重复的内容,然后用grep -v sh命令删除名为sh的进程,最终将结果分页显示在屏幕上。
如你所见,与使用一系列分离的命令并且每个命令都带有自己的临时文件相比,这是一个更精巧的解决方案。但这里有一点需要引起注意,如果你有一系列的命令需要执行,相应的输出文件是在这一组命令被创建的同时立刻被创建或写入的,所以绝不要在命令流中重复使用相同的文件名。如果尝试执行如下命令:
#cat mydata.txt | sort | uniq | > mydata.txt
你最终将得到一个空文件,因为你在读取文件mydata.txt之前就已经覆盖了这个文件的内容。