Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash多个cURL请求问题_Bash_Curl_Gnu Parallel - Fatal编程技术网

Bash多个cURL请求问题

Bash多个cURL请求问题,bash,curl,gnu-parallel,Bash,Curl,Gnu Parallel,脚本提交文件并提交后,API服务返回已提交样本的“任务id”(\task.csv) 运行方法: $./submitter.sh /home/files/ 结果:(这里761和762是从API服务提交的样本的任务id) 我提供了整个文件夹路径(find$1-typef)来查找目录中的所有文件以上载文件。现在,我正在使用“&”操作符提交/上传文件夹中的文件,该文件夹将从API服务(stdout)生成“task\u id”,我希望'task\u id'(stdout)将其存储在'task.csv'中

脚本提交文件并提交后,API服务返回已提交样本的“任务id”(
\task.csv

运行方法:

$./submitter.sh /home/files/
结果:(这里761和762是从API服务提交的样本的任务id)


我提供了整个文件夹路径(
find$1-typef
)来查找目录中的所有文件以上载文件。现在,我正在使用“&”操作符提交/上传文件夹中的文件,该文件夹将从API服务(stdout)生成“task\u id”,我希望
'task\u id'
(stdout)将其存储在
'task.csv'
中。但是上传带有
“&”
和不带
“&”
的文件所需的时间是相同的。还有其他方法可以并行/更快地提交吗?有什么建议吗

命令替换中的命令,
$()
,在子shell中运行;因此,这里是在该子shell的后台发送
curl
命令,而不是父shell

摆脱命令替换,只需执行以下操作:

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

命令替换中的命令,
$()
,在子shell中运行;因此,这里是在该子shell的后台发送
curl
命令,而不是父shell

摆脱命令替换,只需执行以下操作:

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

您告诉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

您告诉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

您可以将
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
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

这将通过并行启动5个
curl
进程来减少总执行时间。

您可以使用
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
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

这将通过并行启动5个
curl
进程来减少总执行时间。

anubhava建议使用
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
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
您将始终获得(订单可能不同):

这意味着该文件包含10个d,后面是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,然后是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

阿努巴瓦建议使用
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
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
您将始终获得(订单可能不同):

这意味着该文件包含10个d,后面是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,然后是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

要存储已启动进程的任务id,请在
curl
命令后执行
echo“$!”>>task.cv
。要存储已启动进程的任务id,请在
curl
命令后执行
echo“$!”>>task.cv
。谢谢Eric。“任务id”不是机器的任务/进程(echo$!)。这是API服务在提交样本时自动生成的。更新后的问题解决方案完美无瑕。当使用(&)符号时,它会启动多少进程。因为在结果出来的时候,我会看到很多错误信息。由于我一次发送的请求数量太多。我们可以限制我们发送的查询吗?为此,您可以使用
xargs
:例如
find“$1”-type f-print0 | xargs-0-n1-I%-p5 curl-s-f”file=%http://X.X.X.X:8080/api/abc/v1/upload >task.csv
将同时运行5次卷发。如果您需要实际的速率限制,请编写一个脚本,调用curl,然后
sleep
s。“任务id”不是机器的任务/进程(echo$!)。这是API服务在提交样本时自动生成的。更新后的问题解决方案完美无瑕。当使用(&)符号时,它会启动多少进程。因为在结果出来的时候,我会看到很多错误信息。由于我一次发送的请求数量太多。我们可以限制我们发送的查询吗?为此,您可以使用
xargs
:例如
find“$1”-type f-print0 | xargs-0-n1-I%-p5 curl-s-f”file=%http://X.X.X.X:8080/api/abc/v1/upload >task.csv
将同时运行5次卷发。如果需要实际速率限制,请编写一个脚本,调用curl然后
sleep
s。使用xargs,当我给出路径“/submitter.sh/home/files/pdf/”时,它只返回一个结果。假设文件夹pdf有5个文件,那么