如何 运行 多个 curl 请求与多个变量并行

How to run multiple curl requests in parallel with multiple variables

设置

我目前有以下脚本可以使用具有多个变量的 ref 文件使用 curl 下载文件。当我创建脚本时它满足了我的需要,但是由于 ref 文件变得更大并且我通过 curl 请求的数据生成需要更长的时间,我的脚本现在需要太多时间才能完成。

Objective

我希望能够更新此脚本,所以我 curl 请求并下载多个准备就绪的文件 - 而不是等待每个文件按顺序请求和下载。

我环顾四周,发现我可以使用 xargsparallel 来实现这一点,但是根据我过去看过的问题、youtube 视频和其他论坛帖子, 我一直没能找到一个例子来解释是否可以使用多个变量。

有人可以确认这是否可行,哪种工具更适合实现这一目标?我当前的脚本配置是否正确,或者我是否需要修改很多脚本才能插入这些命令?

我怀疑这可能是之前有人问过的问题,我可能只是没有找到正确的问题。

账号-list.tsv

client1 account1    123 platform1   50
client2 account1    234 platform1   66
client3 account1    344 platform1   78
client3 account2    321 platform1   209
client3 account2    321 platform2   342
client4 account1    505 platform1   69

download.sh

#!/bin/bash
set -eu

user="user"
pwd="pwd"
D1=$(date "+%Y-%m-%d" -d "1 days ago")
D2=$(date "+%Y-%m-%d" -d "1 days ago")
curr=$D2
cheese=$(pwd)

curl -o /dev/null -s -S -L -f -c cookiejar 'https://url/auth/' -d name=$user -d passwd=$pwd

while true; do

        while IFS=$'    ' read -r client account accountid platform platformid
        do
                curl -o /dev/null -s -S -f -b cookiejar -c cookiejar 'https://url/auth/' -d account=$accountid
                curl -sSfL -o "$client€$account@$platform£$curr.xlsx" -J -b cookiejar -c cookiejar "https://url/platform=$platformid&date=$curr"
        done < account-list.tsv

        [ "$curr" \< "$D1" ] || break
        curr=$( date +%Y-%m-%d --date "$curr +1 day" ) ## used in instances where I need to grade data for past date ranges.

done

exit

并行 运行 多个进程的一个(相对)简单的方法是将调用的核心包装在一个函数中,然后在 while 循环中调用该函数,确保将后台函数调用,eg:

# function definition

docurl () {
    curl -o /dev/null -s -S -f -b cookiejar -c cookiejar 'https://url/auth/' -d account=$accountid
    curl -sSfL -o "$client€$account@$platform£$curr.xlsx" -J -b cookiejar -c cookiejar "https://url/platform=$platformid&date=$curr"
}

# call the function within OP's inner while loop

while true; do

    while IFS=$'    ' read -r client account accountid platform platformid
    do
        docurl &            # put the function call in the background so we can continue loop processing while the function call is running

    done < account-list.tsv

    wait                    # wait for all background calls to complete 

    [ "$curr" \< "$D1" ] || break

    curr=$( date +%Y-%m-%d --date "$curr +1 day" ) ## used in instances where I need to grade data for past date ranges.
done

此方法的一个问题是,对于大量 curl 调用,可能会使底层系统陷入困境 and/or,导致远程系统拒绝 'too many' 并发电话。在这种情况下,有必要限制并发 curl 调用的数量。

一个想法是保留当前 运行ning(后台)curl 调用的数量的计数器,当我们达到限制时,我们 wait 让后台进程来在产生新的之前完成,例如:

max=5                       # limit of 5 concurrent/backgrounded calls
ctr=0

while true; do

    while IFS=$'    ' read -r client account accountid platform platformid
    do
        docurl &

        ctr=$((ctr+1))

        if [[ "${ctr}" -ge "${max}" ]]
        then
            wait -n         # wait for a background process to complete
            ctr=$((ctr-1))
        fi

    done < account-list.tsv

    wait                    # wait for last ${ctr} background calls to complete

    [ "$curr" \< "$D1" ] || break

    curr=$( date +%Y-%m-%d --date "$curr +1 day" ) ## used in instances where I need to grade data for past date ranges.
done

使用 GNU Parallel 并行获取 100 个条目看起来像这样:

#!/bin/bash
set -eu

user="user"
pwd="pwd"
D1=$(date "+%Y-%m-%d" -d "1 days ago")
D2=$(date "+%Y-%m-%d" -d "1 days ago")
curr=$D2
cheese=$(pwd)

curl -o /dev/null -s -S -L -f -c cookiejar 'https://url/auth/' -d name=$user -d passwd=$pwd

fetch_one() {
    client=""
    account=""
    accountid=""
    platform=""
    platformid=""

    curl -o /dev/null -s -S -f -b cookiejar -c cookiejar 'https://url/auth/' -d account=$accountid
    curl -sSfL -o "$client€$account@$platform£$curr.xlsx" -J -b cookiejar -c cookiejar "https://url/platform=$platformid&date=$curr"
}
export -f fetch_one

while true; do
    cat account-list.tsv | parallel -j100 --colsep '\t' fetch_one
    [ "$curr" \< "$D1" ] || break
    curr=$( date +%Y-%m-%d --date "$curr +1 day" ) ## used in instances where I need to grade data for past date ranges.
done

exit