xargs 命令应该紧跟在管道操做符以后。它使用标准输入做为主要的数据源,将从 stdin 中
读取的数据做为指定命令的参数并执行该命令。node
[root@dns-node2 ~]# cat example.txt | xargs 1 2 3 4 5 6 7 8 9 10 11 12 13
-n 指定每行个数shell
[root@dns-node2 ~]# cat example.txt | xargs -n 3 1 2 3 4 5 6 7 8 9 10 11 12 13
xargs 命令接受来自 stdin 的输入,将数据解析成单个元素,而后调用指定命令并将这些元
素做为该命令的参数。 xargs 默认使用空白字符分割输入并执行/ bin/echo 。
若是文件或目录名中包含空格(甚至是换行)的话,使用空白字符来分割输入就会出现问题。
好比My Documents目录就会被解析成两个元素: My 和 Documents ,而这二者均不存在。
天无绝人之路,此次也不例外。
咱们能够定义一个用来分隔参数的分隔符。 -d 选项能够为输入数据指定自定义的分隔符命令行
[root@dns-node2 ~]# echo "a1xb2xc3xd4" | xargs -d x a1 b2 c3 d4
xargs 命令能够同 find 命令很好地结合在一块儿。 find 的输出能够经过管道传给 xargs, 由后
者执行 -exec 选项所没法处理的复杂操做。若是文件系统的有些文件名中包含空格, find 命令的
-print0 选项可使用 0 (NULL)来分隔查找到的元素,而后再用 xargs 对应的 -0 选项进行解
析。code
[root@dns-node2 tmp]# find ./ -iname "*.sh" |xargs -0 grep sleep -L grep: ./testSet.sh
先说下咱们的需求:
1 咱们有参数保存在参数文件里面,咱们要从这个参数文件里面读取参数而且提供给某个命令使用,那咱们可使用xargs来结合使用
首先查看参数列表:dns
[root@dns-node2 tmp]# cat args.txt timeout 3 interval 3 hostname 1.1.1.1
那下一步就是把这些参数都传给脚本字符串
[root@dns-node2 tmp]# cat args.txt | xargs -n 2 ./testPrint.sh
经过-n 参数来控制传多少个参数给testPring.sh ,若是不写-n 那么就把全部参数传入给testPrint.sh ,不然就由-n来指定参数个数。-n 1就是传一个参数。cmd
2 第二种状况是假设咱们脚本须要2个参数,其中有一个参数时固定的,另一个参数可变的。那怎么保持固定参数不变呢?经过-I参数来指定替换字符串。这个字符串会在 xargs 解析输入时被参
数替换掉。若是将 -I 与 xargs 结合使用,对于每个参数,指定命令只会执行一次,此时若是结合-n使用的话,-n是无效的test
[root@dns-node2 tmp]# cat args.txt | xargs -I {} ./testPrint.sh {} fixedArgs timeout 3 fixedArgs# interval 3 fixedArgs# hostname 1.1.1.1 fixedArgs#
-I {} 指定了替换字符串。为该命令提供的各个参数会经过 stdin 读取并依次替换掉字符串 {} 。file
使用 -I 的时候,命令以循环的方式执行。若是有3个参数,那么命令就会连
同 {} 一块儿被执行3次。 {} 会在每次执行中被替换为相应的参数。循环
使用 find 命令的 -print0 选项生成以空字符( '\0' )做为分隔符的输出,而后将其做为
xargs 命令的输入
若是不使用-print0的话而在xargs 使用-0参数的话,由于二者发生矛盾了,你们能够看到下面第一条命令报错了
[root@dns-node2 tmp]# find . -type f -name "*.txt" | xargs -0 ls -l ls: cannot access ./output.txt ./args.txt : No such file or directory # 报错了?,没有使用-print0 [root@dns-node2 tmp]# find . -type f -name "*.txt" -print0 | xargs -0 ls -l -rw-r--r-- 1 root root 38 Sep 16 22:49 ./args.txt -rw-r--r-- 1 root root 8 Sep 4 22:28 ./output.txt
xargs 会将参数放置在指定命令的尾部,所以没法为多组命令提供参数。咱们能够经过建立子shell来处理这种复杂状况。子shell利用while循环读取参数并执行命令,有2种方法,就像这样:
1 方法1
[root@dns-node2 tmp]# ls *.sh | (while read arg; do cat $arg; done)
2 方法2
[root@dns-node2 tmp]# ls *.sh | xargs -I a cat a
在 while 循环中,能够将 cat $arg 替换成任意数量的命令,这样咱们就能够对同一个参数
执行多条命令。也能够不借助管道将输出传递给其余命令。这种利用 () 建立子shell的技巧能够应
用于各类问题场景。子shell操做符内部的多条命令在执行时就像一个总体,所以:
$ cmd0 | ( cmd1;cmd2;cmd3) | cmd4
若是 cmd1 是 cd / ,那么就会改变子shell工做目录,然而这种改变仅局限于该子shell内部。
cmd4 则不受工做目录变化的影响。
shell的 -c 选项能够调用子shell来执行命令行脚本。它能够与 xargs 结合解决屡次替换的问
题。下列命令找出了全部的C文件并显示出每一个文件的名字,文件名前会加上一个换行符( -e 选
项容许进行转义替换)。在文件名以后是该文件中含有main的全部行:
[root@dns-node2 tmp]# ls *.sh | xargs -I {} sh -c "echo -ne '\n {}: ';grep sleep {}"