管道命令“ | ”仅能处理经由前面一个指令传来的正确信息,也就是stdout的信息,对于 stderr并没有直接处理的能力。

管线命令可以使用下图表示:

管道后面第一个接的必须是能够接受stdin数据的命令,例如 less, more, head, tail 等。

# cat /etc/passwd | head -5
显示/etc/passwd的前五行

要让管道可以处理stderr,可以进行数据流重定向,将其转化为stdout(2>&1)

# cat /etc/passwdss  2>&1  | grep -o "file"

将stderr输出到空设备,stdout继续后面的指令执行

# cat /etc/passwd /etc/passwdss 2>/dev/null |head -5

xargs

xargs(英文全拼: eXtended ARGuments)是给命令传递参数的一个过滤器,也是组合多个命令的一个工具。
xargs 可以将管道或标准输入(stdin)数据转换成命令行参数,也能够从文件的输出中读取数据。
xargs 也可以将单行或多行文本输入转换为其他格式,例如多行变单行,单行变多行。
xargs 默认的命令是 echo,这意味着通过管道传递给 xargs 的输入将会包含换行和空白,不过通过 xargs 的处理,换行和空白将被空格取代。
xargs 是一个强有力的命令,它能够捕获一个命令的输出,然后传递给另外一个命令。

常用参数演示,更多参数请查看手册

默认输出(相当于echo单行输出)

# cat /etc/passwd|xargs

-n:参数多列输出(定界符为空格)

# cat /etc/passwd|xargs -n2

-d:自定义分界符

# echo "1:2:3"|xargs -d:

-I {}:指定命令行参数的替代字符串

# cat > test.txt <<EOF
aaa
bbb
ccc
EOF
# cat > test.sh <<EOF
echo \$*
EOF
# cat test.txt | xargs -I {} ./test.sh start {} end

-0:将null当作分隔符

由于xargs默认将空格作为分隔符,所以不太适合处理文件名,因为文件名可能包含空格。

find命令有一个特别的参数-print0,指定输出的文件列表以null分隔。然后,xargs命令的-0参数表示用null当作分隔符。

# find /var/log/ -type f -name "*.log" -print0 |xargs -0 rm -f

部分命令(如rm)参数过多会报错"参数列表过长",而无法执行,改用xargs就没有这个问题,因为它对每个参数执行一次命令。

-t:打印出执行命令

-p:确认执行是否执行命令

-L:指定多少行作为一个命令行参数

# cat > arg.txt <<EOF
"*.txt"
"*.log"
EOF
# cat arg.txt | xargs -L 1 find -name 

--max-procs:指定同时用多少个进程并行执行命令,值为0表示不限制进程

# cat arg.txt | xargs --max-procs 2 -L 1 find -name