shell技巧-Parallel命令行并行工具(xargs增强版)

shell技巧-Parallel命令行并行工具(xargs增强版)

之前写过xargs的高级用法,但是在工作中发现xargs并不能实现所有的需求。我发现xargs存在下面两个痛点。

  1. 本身无法调整格式化参数的位置
  2. 控制命令行并行的数量支持不友好

为什么要用parallel代替xargs?

xargs能实现的功能parallel都能做。

交换参数的位置

第一个可以通过sh命令来解决,但是本身不优雅。比如

root@VM-32-8-ubuntu:~# seq 1 6 | xargs -n2 echo
1 2
3 4
5 6
root@VM-32-8-ubuntu:~# seq 1 6 | xargs -n2 sh -c 'echo $2 $1' _
2 1
4 3
6 5
root@VM-32-8-ubuntu:~# seq 1 6 | parallel -n2 echo {2} {1}
2 1
4 3
6 5

虽然可以通过sh -c 这种曲线救国的方式来交换参数位置,但是每条命令都得新启动一个shell来执行。

经测试在数据量大的情况下,xargs sh -c 效率非常低下。极为不推荐!

root@VM-32-8-ubuntu:~# seq 1 6 | xargs -n2 | awk '{print $2,$1}'
2 1
4 3
6 5

写这篇文章的时候突然想到还能用xargs配合awk来交换列。

root@VM-32-8-ubuntu:~# seq 1 6 | xargs -n2 | awk '{print $2,$1}'
2 1
4 3
6 5

命令并行数量

可以使用 & 的方式让命令全部在后台执行,但是会一次性全部执行,占满CPU甚至出现卡顿的情况。

虽然 xargs 也支持 -P 多个CPU同时运行。

-P, --max-procs=MAX-PROCS    run at most MAX-PROCS processes at a time

比如我们写一个ping探测内网存活的shell命令。

root@VM-32-8-ubuntu:~# ifconfig eth0 | grep inet
        inet 172.19.32.8  netmask 255.255.240.0  broadcast 172.19.47.255
root@VM-32-8-ubuntu:~# 
root@VM-32-8-ubuntu:~# seq 0 255 | sed 's/^/172.19.32./g' |  xargs -n1 sh -c 'ping -c1 $1 &' _
PING 172.19.32.1 (172.19.32.1) 56(84) bytes of data.
.....
PING 172.19.32.8 (172.19.32.8) 56(84) bytes of data.
64 bytes from 172.19.32.8: icmp_seq=1 ttl=64 time=0.044 ms
--- 172.19.32.8 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.044/0.044/0.044/0.000 ms
PING 172.19.32.9 (172.19.32.9) 56(84) bytes of data.
......

通过 & 方式,相当于一瞬间起了256个shell来执行ping命令。这种方式并不优雅,如果用这种方式扫b段,那就要同时起65536个子进程,CPU???

使用sh -c 每次还需要多起一个shell,不使用sh -c 则又不支持调整参数位置。

用parallel的写法如下

seq 1 255 | sed 's/^/172.19.32./g' |  parallel -j5 ping {1} -c1

赞赏

微信赞赏支付宝赞赏

Zgao

愿有一日,安全圈的师傅们都能用上Zgao写的工具。

发表评论