下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

详解Linux shell中的管道命令:head

作者:课课家教育     来源: http://www.kokojia.com点击数:1752发布时间: 2016-02-18 18:29:31

标签: Linux管道Linux系统Linux

  Linux shell中的管道“|”是非常方便的功能,可以将一个程序的输出作为另外一个程序的输入,这样我们可以将多个命令“拼”在一起,省去了临时文件的繁琐。Windows中也有类似的用法,比如dir |more,曾几何时,还学过dos命令的朋友们应该都还会记得。

详解Linux shell中的管道命令:head_Linux管道_Linux系统_Linux_课课家

  既然是管道,那么就有一个入口和一个出口,各自对应一个应用程序,正常的情况下,入口应用程序的输出应当被出口应用程序全部接受,但在一些特殊情况,出口应用程序会提前关闭管道,比如在查询svn的更新日志,只取前己行的时候:

  $ svn log |head

  ------------------------------------------------------------------------

  r137 | Fwolf | 2007-05-28 13:38:47 +0800 (Mon, 28 May 2007) | 4 lines

  更新记录。。。

  svn: Write error: Broken pipe

  先来看一下head的定义与用法:

  定义: head –display first lines of a file — 显示文件中的前几行

  用法: head[-n count | -c bytes] [file …]

  由于head只需要用到输入的前10行(默认行数,也可由用户指定),再接收剩下的输出也是多余,便提前关闭了管道,管道入口的应用程序svn发现之后,便报错退出了。在这个例子中,错误信息非常清楚,但不是所有应用程序都这样的,比如下面这个:

  $ find . -name "*rc" |xargs -i cat {}|head -1

  [Desktop]

  xargs: cat: terminated by signal 13

  错误信息似乎并不太好理解,实际上它的意思是:xargs发现它的子进程cat由于信号13被中止了。由于xargs本身属于循环操作,发现错误之后就停止了循环,这是其一;信号13是在cat试图向一个已关闭的pipe管道中写数据的时候,系统产生的,cat收到之后就停止了。类似于在cat输出的过程中,用户按下ctrl+c的效果。

  如何避免这种问题呢?很简单,管道后面使用不会提前关闭管道的程序即可,尤其是结合xargs使用的时候,它发现出错就不继续了。比如要用到head可以这样:

  $ cat file |head -1

  虽然cat仍然会被signal 13关闭,但bash是不会报错的,所以也只能针对一个文件进行操作,即使是使用了通配符也只能head到第一个文件。如果要加上对文件的遍历,可以用到for:

  $for file in .*rc;do cat $file |head -1;done

  cat依然会被关闭,但是for不会理会它,继续循环。head也可以直接指定文件名,这样我们就可以抛开cat了:

  $find . -name "*rc" |xargs -i head -n1 {}

  个人认为这是一种最完美的解决方式,即可以用到find强大的搜索指令,还不会涉及到管道的问题。不过如果文件名没有什么特殊要求,还有一种更简单的方式:

  $head -n1 .*rc

  在head的参数中直接用通配符指定文件,呵呵。

赞(26)
踩(2)
分享到:
华为认证网络工程师 HCIE直播课视频教程