2016-10-10 105 views
1

脚本提交的文件,并提交后,提交的样品的API的服务回报 “TASK_ID”(#task.csv猛砸多卷曲请求发出

#file_submitter.sh 

#!/bin/bash 

for i in $(find $1 -type f);do 
     task_id="$(curl -s -F [email protected]$i http://X.X.X.X:8080/api/abc/v1/upload &)" 
     echo "$task_id" >> task.csv 
done 

运行方法:

$./submitter.sh /home/files/ 

结果: (这里761 & 762是API服务提交样本的task_id)

#task.csv 

{"task_url": "http://X.X.X.X:8080/api/abc/v1/task/761"} 
{"task_url": "http://X.X.X.X:8080/api/abc/v1/task/762"} 

我给整个文件夹路径(find $1 -type f)查找目录中的所有文件以上载文件。现在,我使用“&”运算符来提交/上传文件夹中的文件,该文件夹将从API服务(stdout)生成'task_id',我希望'task_id'(标准输出)将其存储在'task.csv'中。但是上传带有"&"而没有"&"的文件的时间是相同的。有没有更多的方法来提交并行/更快?有什么建议吗?

回答

1

您可以使用xargs-P选项:

find "$1" -type f -print0 | 
xargs -0 -P 5 -I{} curl -s -F file='@{}' http://X.X.X.X:8080/api/abc/v1/upload >> task.csv 

这将通过开展并行5个curl过程中减少总的执行时间。

+0

使用xargs,当我给路径'./submitter.sh/home/files/pdf /'时,它只返回一个结果。假设文件夹pdf有5个文件,输出结果必须大约是5个task_ids的权利? – Arun

+0

立即尝试我更新的答案。 – anubhava

+1

它运作良好!谢谢 – Arun

1

命令替换内部的命令$()在子外壳中运行;所以在这里你发送curl命令在该子shell的后台,而不是父shell。

摆脱命令替换的,只是做:

curl -s -F [email protected]$i http://X.X.X.X:8080/api/abc/v1/upload >task.csv & 
+0

要存储推出,'回声过程的TASK_ID curl命令后的>> task.cv'。 – Inian

1

你告诉shell将命令替换($())内并行。这不会做你想做的。试试这个:

#!/bin/bash 

for i in $(find $1 -type f);do 
     curl -s -F [email protected]$i http://X.X.X.X:8080/api/abc/v1/upload & 
done > task.csv 
#uncomment next line if you want the script to pause until the last curl is done 
#wait 

这使curl到背景和它的输出保存到task.csv

+0

谢谢埃里克。 'task_id'不是机器的任务/进程(echo $!)。这是在提交样本时由API服务自动生成的。更新了问题 – Arun

+1

我编辑了答案以反映更新 – Eric

+0

完美无缺。使用(&)&符号时启动多少进程。因为出来的结果,我得看到这么多的错误信息。由于我一次发送的请求数量。我们可以限制我们发送的查询吗? – Arun

1

anubhava建议使用xargs-P选项:

find "$1" -type f -print0 | 
xargs -0 -P 5 curl -s -F [email protected] http://X.X.X.X:8080/api/abc/v1/upload >> task.csv 

然而,追加到并联同一文件通常是一个坏主意:你真的需要知道了很多关于这个版本的操作系统如何缓冲输出为了安全起见。这个例子表明为什么:

#!/bin/bash 

size=3000 

myfile=/tmp/myfile$$ 
rm $myfile 

echo {a..z} | xargs -P26 -n1 perl -e 'print ((shift)x'$size')' >> $myfile 

cat $myfile | perl -ne 'for(split//,$_){ 
    if($_ eq $l) { 
    $c++ 
    } else { 
    /\n/ and next; 
    print $l,1+$c," "; $l=$_; $c=0; 
    } 
}' 
echo 

随着size=10你总是会得到(顺序可能会有所不同):

1 d10 i10 c10 n10 h10 x10 l10 b10 u10 w10 t10 o10 y10 z10 p10 j10 q10 s10 v10 r10 k10 e10 m10 f10 g10 

这意味着该文件包含10 D的随后10我,再接10℃的等。即26个职位的产出没有混合。

但其更改为size=30000和你喜欢的东西:

1 c30000 d30000 l8192 g8192 t8192 g8192 t8192 g8192 t8192 g5424 t5424 a8192 i16384 s8192 i8192 s8192 i5424 s13616 f16384 k24576 p24576 n8192 l8192 n8192 l13616 n13616 r16384 u8192 r8192 u8192 r5424 u8192 o16384 b8192 j8192 b8192 j8192 b8192 j8192 b5424 a21808 v8192 o8192 v8192 o5424 v13616 j5424 u5424 h16384 p5424 h13616 x8192 m8192 k5424 m8192 q8192 f8192 m8192 f5424 m5424 q21808 x21808 y30000 e30000 w30000 

首先30K C'S,然后30K D's,则8K L's,则8K克氏,8K T的,然后又8K克氏,等等。即26项产出混合在一起。非常不好。

因此,我建议不要并行追加到同一个文件:存在竞争条件的风险,并且通常可以避免。

在你的情况,你可以简单地使用GNU并行,而不是xargs的,因为GNU并行卫士对本场比赛状态:“$”

find "$1" -type f -print0 | 
parallel -0 -P 5 curl -s -F [email protected]{} http://X.X.X.X:8080/api/abc/v1/upload >> task.csv