分类: LINUX
2010-08-05 21:01:57
xargs构造一个命令行,该命令行由指定的COMMAND, ARGUMENT以及从标准
输入按顺序读取的参数来组成;并确保读取的参数在长度和数量上符合
xargs选项指定的约束。然后,xargs调用该命令行,并等待执行完成。
如此反复,直到读取到结束条件,或者某次命令行执行返回255.
从标准输入读取的参数必须用空白字符(不在引号中)或者是换行符(未转义)
来分隔。不含双引号和换行符的字符串,可以用双引号来引起来。不含单引号和
换行符的字符串可以用单引号引起来。未引起来的字符可以在前面用\来转义。
COMMAND会执行若干次,直到end-of-file。如果COMMAND要从标准输入读取,会
导致结果未定义。
生成的命令行的长度,就是所有字符串(COMMAND,ARGUMENT)的长度之和(包括
某个字符串的结束符null terminator)。xargs会限制命令行的长度,使得命令行
在执行的时候,其参数和环境不会超过{ARG_MAX}-2048字节。在该约束下,如果
没有指定-n和-s选项,那么默认命令行长度就是至少{LINE_MAX}.
选项
-e[EOFSTR] 用EOFSTR来作为逻辑上的end-of-file字符串。如果没有-E和-e选项,
那么下划线(_)会被当作默认的EOF字符串。如果给了-e标志,但是
没有给EOFSTR可选参数,那么EOF功能会被禁用,下划线会按字面处理。
xargs读取标准输入,直到遇到逻辑EOF或者end-of-file.
-E EOFSTR 对于 /usr/bin/xargs:
指定EOFSTR作为end-of-file字符串来代替默认的下划线(_)。xargs从
标准输入读取,直到end-of-file或者遇到EOFSTR。EOFSTR不能为空。
对于 /usr/xpg6/bin/xargs:
指定EOFSTR作为end-of-file字符串来代替默认的下划线(_)。xargs从
标准输入读取,直到end-of-file或者遇到EOFSTR。如果EOFSTR为空,
那么EOFSTR功能禁用,下划线(_)会按字面处理。
-I REPLSTR 插入模式。每从标准输入读取1行,就执行依次COMMAND,并把该整行
当作单个参数,插入到ARGUMENT中的REPLSTR处。ARGUMENTs中最多能包
含5个REPLSTR。读取的每行字符串,开始的空白字符都会忽略。构成的
参数,不能超过255字节。-x选项会伴随-I选项强制自动打开。-I和-i
选项是互斥的,最后指定的生效。
-i[REPLSTR] 该选项与-I是等价的。如果没有指定可选参数REPLSTR,则采用{}.
-L NUMBER 每次从标准输入读取NUMBER行非空的行,就执行1次COMMAND。最后1次
调用COMMAND时,可能会由于不足NUMBER行剩下而有比较少的参数。
每行都以换行符结尾,除非该行结尾是空白字符,结尾的空白字符表示
继续包含下一个非空白行。-L, -l和-n选项是互斥的,最后一个生效。
-l[NUMBER] 该选项与-L等价,默认NUMBER是1,并自动强制打开-x选项。
-n NUMBER 执行COMMAND命令时,尽可能多的从标准输入中读取N个参数。
* 如果标准输入剩下多于0但不足N行,可能不够N个参数。
* 命令行长度超过-s选项或者LINE_MAX,那么可能不够N个参数
-p 提示模式。每次执行COMMAND前都提示用户。Trace mode(-t)会自动
打开,从而输出要执行的命令和提示信息到stderr。从/dev/tty
读取肯定的答复后,COMMAND会执行;否则本次执行会被忽略。
-s SIZE 执行COMMAND时,尽可能多的读取输入参数,但是长度不能超过SIZE。
命令行长度小于SIZE的情况:
* 参数总数超过-n指定的
* 读入的行数超过-L指定的
* EOF
如果DESCRIPTION中约束被满足,那么SIZE-{LINE_MAX}之间的值也是
可以支持的。大于实现支持的值或者超过DESCRIPTION中描述的值不
应该被当作错误。xargs在支持的范围里用最大值。
-t Trace Mode。打开跟踪模式,从而每次命令行在执行前都打印到stderr.
-x 如果包含NUMBER个参数或NUMBER行的命令行不符合-s指定的size,就终止。
OPERANDS
COMMAND 要调用的命令名,必须通过PATH环境变量能搜到。如果没有指定COMMAND,
默认会调用echo。如果COMMAND与shell builtin同名,结果未定义。
ARGUMENT 传递给COMMAND的初始选项或参数
USAGE
COMMAND可以用退出状态255来告诉xargs终止执行,尤其是当COMMAND知道继续在该输入
stream上执行不会成功时。因此,COMMAND在多数情况下要避免255退出值.
输入是按行解析的。空白字符用来分隔参数。如果xargs和find DIR -print之类的命令
一起组合使用,而文件名含有空白字符或者换行符,xargs执行会出错。
一个解决方法是:find调用脚本把文件名用引号引起来后,再传递给xargs。但是由于
xargs的引用规则与shell的引用规则不一致,可能还是会有错误。所以,可以把
引号起来的字符串所有字符前面都加\来转义。
某些实现支持大于{ARG_MAX};xargs产生的命令行长度大于{LINE_MAX}。这对COMMAND
不是问题。如果xargs用来产生文本文件,最好通过-s选项来限制每行的长度。
xargs如果遇到错误,返回127,这样就能区分究竟是调用COMMAND出错,还是COMMAND
执行出错。因为127很少用于返回。
示例
1: 把$1中的文件移动到$2
example% ls $1 | xargs -I {} -t mv $1{} $2/{}
2: 把小括号中的输出组成1行,写入到日志文件
example% (logname; date; printf "%s\n" "$0 $*") | xargs >>log
其实等价于
example% (logname; date; printf "%s\n" "$0 $*") >>log
3: 对连续的参数对,执行文件比较操作(假设文件名不含特殊字符)
example% printf "%s\n" "$*" | xargs -n 2 -x diff
4: 提示用户,把文件打包起来
每次一个文件
example% ls | xargs -p -L 1 ar -r arch
打包多个文件
example% ls | xargs -p -L 1 | xargs ar -r arch
5. REPLSTR为字节定义的字符串,一般选用{}
> (echo "1" ; echo 2)
1
2
#-I选项导致整行被当作1个参数。
> ( echo "1 a" ; echo 2 ) | xargs -I p echo "heihei" {}
heihei {}
heihei {}
> ( echo "1 a" ; echo 2 ) | xargs -I p echo "heihei" p
heihei 1 a
heihei 2
# p为REPLSTR
> ( echo "1 a" ; echo 2 ) | xargs -I p echo "heihei" p "hello"
heihei 1 a hello
heihei 2 hello
> ( echo "1 a" ; echo 2 ) | xargs -I p echo "heihei" p "hello" p
heihei 1 a hello 1 a
heihei 2 hello 2
> cat xargs.sh
#!/bin/bash
if [ "$#" == 0 ] ; then
echo "$0: arg num=0"
else
echo "argnum=$# $@"
fi
> ( echo "1 a" ; echo 2 ) | xargs -I p ./xargs.sh "heihei" p
argnum=2 heihei 1 a
argnum=2 heihei 2
> ( echo "1 a" d e; echo 2 ) | xargs -I p ./xargs.sh "heihei" p
argnum=2 heihei 1 a d e
argnum=2 heihei 2
> ( echo "1 a" d e ; echo 2 ) | xargs -I p ./xargs.sh p "heihei" p
argnum=3 1 a d e heihei 1 a d e
argnum=3 2 heihei 2
# 无-I选项,参数从输入行用空白分隔。
> echo "a b c " | xargs ./xargs.sh -f b
argnum=5 -f b a b c
> echo "a b c c e f g" | xargs -n 5 ./xargs.sh -f b
argnum=7 -f b a b c c e
argnum=4 -f b f g
# -I选项与-n选项貌似不兼容,
# -I在前, -n在后,{}未能识别
> echo "a b c c e f g" | xargs -I {} -n 5 ./xargs.sh {} -f b
argnum=8 {} -f b a b c c e
argnum=5 {} -f b f g
# -n在前, -I在后,整行当作参数
> echo "a b c c e f g" | xargs -n 5 -I {} ./xargs.sh {} -f b
argnum=3 a b c c e f g -f b
注意:
xargs从标准输入中读取数据,并以空白和换行符分割每个参数(引号中的空
白不作为分割符)。然后执行指定的命令(并把分解后的参数附加到命令后面)。
如果没有指定具体的命令,默认使用/bin/echo命令。
如果没有特别指定,xargs会把`_'当作结束标志。
综上所述,xargs不适合用作文本处理,特别是重要的数据处理。