parallel
parallel是使用Perl写的一个并行执行shell命令行的工具。用法也比较复杂,按最简单的来用,
cat myshell|parallel --bar -j 20,然后批量执行shell中的内容。每个shell,可以执行一个复杂的命令。
资源
-
下面的文章,用法讲解的比较多。
教程
格式
parallel [options] [command [arguments]] < list_of_arguments
parallel [options] [command [arguments]] (::: arguments|:::: argfile(s))...
cat ... | parallel --pipe [options] [command [arguments]]
-j n Run n jobs in parallel
-k Keep same order
-X Multiple arguments with context replace
--colsep regexp Split input on regexp for positional replacements
{} {.} {/} {/.} {#} {%} {= perl code =} Replacement strings
{3} {3.} {3/} {3/.} {=3 perl code =} Positional replacement strings
With --plus: {} = {+/}/{/} = {.}.{+.} = {+/}/{/.}.{+.} = {..}.{+..} =
{+/}/{/..}.{+..} = {...}.{+...} = {+/}/{/...}.{+...}
-S sshlogin Example: foo@server.example.com
--slf .. Use ~/.parallel/sshloginfile as the list of sshlogins
--trc {}.bar Shorthand for --transfer --return {}.bar --cleanup
--onall Run the given command with argument on all sshlogins
--nonall Run the given command with no arguments on all sshlogins
--pipe Split stdin (standard input) to multiple jobs.
--recend str Record end separator for --pipe.
--recstart str Record start separator for --pipe.
常用选项:
::: 后面接参数
:::: 后面接文件
-j、--jobs 并行任务数
-N 每次输入的参数数量
--xargs会在一行中输入尽可能多的参数
-xapply 从每一个源获取一个参数(或文件一行)
--header 把每一行输入中的第一个值做为参数名
-m 表示每个job不重复输出“背景”(context)
-X 与-m相反,会重复输出“背景文本”
-q 保护后面的命令
--trim lr 去除参数两头的空格,只能去除空格,换行符和tab都不能去除
--keep-order/-k 强制使输出与参数保持顺序 --keep-order/-k
--tmpdir/ --results 都是保存文件,但是后者可以有结构的保存
--delay 延迟每个任务启动时间
--halt 终止任务
--pipe 该参数使得我们可以将输入(stdin)分为多块(block)
--block 参数可以指定每块的大小
安装
(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash
安装完成后就是一个一万多行的perl脚本,把脚本复制到其他机器一样可以用。一般用yum之类的工具直接安装即可。
shell命令
生成shell命令,然后从标准输入中,读命令,并执行--bar ,即增加一个进度条。
for i in `seq 1 10000`; do echo "curl --silent '10.131.236.12:35500/?a=qr&s=cc&p=188'"; done | parallel --bar -j 20
从shell中读,毕竟太慢了,可以先将文件拆分,然后每个命令执行拆分后的命令。
失败时,记录到日志里面。
占位符号
seq 5|parallel echo test_{} 2>/dev/null
echo 1,2 | parallel -d, echo {}
通过管道从标准输入读取命令参数,然后将参数传递给后面的echo命令,大括号{}这里将会填充从标准输入中的参数,-d,表示使用逗号,作为参数分隔符
管道模式
cat mylog | grep pattern
cat my_large_log | parallel --pipe grep pattern
#以上两条结果相同,只是parallel会多核并行执行。
当不需要传参数的时候,直接-n 0,大概是,相当于起n个进程
seq 3 |parallel -n 0 curl -I www.baidu.com
#-n 传递的最大参数个数。-n 0表示不传参数。
多进程
a.sh b.sh c.sh,要求a、b可同时执行,a、b均执行结束后,再执行c.sh。实现如下:
parallel -j 2 "sh a.sh" "sh b.sh";
sh c.sh
实战
作为参数调用
psm.sh
curl -s "http://10.10.10.10:35500/?y=$1"
echo " "$1
调用
cat psm.csv |parallel ./psm.sh {} -j 10 > psm_result.txt
注意curl不能太高,否则,出现很多TIME_WAIT 的情况。
netstat -tunp |grep TIME_WAIT |wc -l
作为命令调用
一行一条命令。作为临时的压测工具
for i in `seq 1 10000`; do echo "curl --silent '10.10.10.10:35500/?a=qr&s=cc&p=188'"; done | parallel --bar -j 20