Bash多个cURL请求问题

时间:2016-10-10 10:42:28

标签: bash curl gnu-parallel

脚本提交文件并发布提交,API服务返回" task_id"提交的样本(#task.csv

#file_submitter.sh

#!/bin/bash

for i in $(find $1  -type f);do
        task_id="$(curl -s -F file=@$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)以查找目录中的所有文件以上传文件。现在,我正在使用"&"操作员从文件夹中提交/上传文件,这将生成' task_id'来自API服务(stdout),我希望'task_id'(stdout)将其存储在'task.csv'中。但是上传包含"&"且没有"&"的文件所需的时间是相同的。还有更多方法可以并行/更快地进行提交吗?有什么建议吗?

4 个答案:

答案 0 :(得分:1)

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

摆脱命令替换,只做:

curl -s -F file=@$i http://X.X.X.X:8080/api/abc/v1/upload >task.csv &

答案 1 :(得分:1)

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

#!/bin/bash

for i in $(find $1  -type f);do
        curl -s -F file=@$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

答案 2 :(得分: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进程来减少总执行时间。

答案 3 :(得分:1)

anubhava建议将xargs-P选项一起使用:

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

然而,并行追加到同一个文件通常是一个坏主意:你真的需要知道很多关于这个版本的OS如何缓冲输出以确保安全。这个例子说明了原因:

#!/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个s后跟10个i后跟10个c,依此类推。即没有混合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,然后是30K d's,然后是8k l,然后是8K g,8K t,然后再是8k g,依此类推。即26项产出混合在一起。非常不好。

出于这个原因,我建议不要同时追加同一个文件:存在竞争条件的风险,通常可以避免。

在你的情况下你可以简单地使用GNU Parallel而不是xargs,因为GNU Parallel可以防止这种竞争条件:

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