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