Chinaunix首页 | 论坛 | 博客
  • 博客访问: 90012
  • 博文数量: 24
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 231
  • 用 户 组: 普通用户
  • 注册时间: 2015-06-13 21:06
个人简介

来也匆匆 几十繁华一阵风; 去也匆匆 回头一看已成空

文章分类

全部博文(24)

文章存档

2016年(4)

2015年(20)

我的朋友

分类: Android平台

2015-09-11 14:06:08

xargs是给命令传递参数的一个过滤器,也是组合多个命令的一个工具.它把一个数据流分割为一些足够小的块,以方便过滤器和命令进行处理.由此 这个命令也是后置引用的一个强有力的替换.在一般使用过多参数的命令替换失败的时候,xargs来替换它一般都能成功.通常情况下,xargs从管道或 者stdin中读取数据,但是它也能够从文件的输出中读取数据. xargs的默认命令是echo.这意味着通过管道传递给xargs的输入将会包含换行和空白,不过通过xargs的处理,换行和空白将被空格取代.

 

假设有这样一个需求,我们需要从/home/rain文件系统中搜索字符串hello,命令如下:

$grep  -i  "hello"  /home/rain/*

这将导致命令行参数太多。而每个系统对于参数列表的大小都有限制。比如ARG_MAX一般至少定义为4096 bytes, 如果超过了ARG_MAX,将产生shell错误:

Argument list too long , 为了避免这个问题可以使用xargs命令, 格式为:

xargs [opt] [ command [initial-arguments] ]

其中optxargs本身的命令行参数。

它的作用为,build and execute command lines from standard input。他从stdin读取由空格分割的字符串(假设为arg0arg1,… argN),并执行command [initial-arguments] arg0 arg1 argN,如果参数太多的话,xargs保证参数大小在不超过系统限制的ARG_MAX bytes大小的前提下,一次或多次执行command [initial-arguments]命令。比如执行了如下命令:

$find / -name ‘*.h’ | xargs grep –i ‘stdin’ | less

假设执行两次,第一次为grep i stdin a1.h a2.h a3000.h | less

第二次为grep i stdin a3001.h a3002.h a4000.h | less

该命令的实际执行情况为:(推测)

Shell执行findxargsless程序, xargs顺序执行了两次grep程序。

xargsfind的结果读取数据是很普通的,不需要额外的解释。

xargsless的数据传递看起来有些麻烦,其实也挺简单的。xargsstdin读取管道的数据,并按照ARG_MAX为界限进行分割,执行forkexecv(grep)一次或多次就可以了。因为grep使用普通的printf来输出结果,而这样的结果正好作为less的输入。因为xargsgrep虽然存在父子关系,但是他们的stdout是同一个stdout。对于less程序来讲,grep的输出和xargs的输出是没有区别的。

注意:

[1] XXX | grep –i ‘hello’

[2] XXX | xargs grep –i ‘hello’

[1]的情况下,grep将通过管道读取XXXX的输出结果,并在该结果中搜索hello

[2]的情况下,xargs将通过管道读取XXXX的输出结果,并将该结果作为grep的最后的FILE参数,和grep i hello’组合成完整的命令(如 grep i hello stdio.h stdlib.h)后,执行该命令。grepstdio.h stdlib.h文件中搜索hello

两者对于管道的输出作不同的处理,前者是grep直接从stdin中读取管道数据,并搜索。后者是xargs(他的命令行选项为 grep i hello’)直接从stdin中读取管道数据,并和grep i hello’组合,然后调用exec执行该命令。这种不同是体现在grepxargs对读取管道数据后采取的不同处理,和管道本身的机制没有关系。

阅读(1328) | 评论(0) | 转发(0) |
0

上一篇:HTTP Header详解

下一篇:android 开源组件

给主人留下些什么吧!~~