如何 运行 多个 curl 请求与多个变量并行
How to run multiple curl requests in parallel with multiple variables
设置
我目前有以下脚本可以使用具有多个变量的 ref 文件使用 curl
下载文件。当我创建脚本时它满足了我的需要,但是由于 ref 文件变得更大并且我通过 curl
请求的数据生成需要更长的时间,我的脚本现在需要太多时间才能完成。
Objective
我希望能够更新此脚本,所以我 curl
请求并下载多个准备就绪的文件 - 而不是等待每个文件按顺序请求和下载。
我环顾四周,发现我可以使用 xargs
或 parallel
来实现这一点,但是根据我过去看过的问题、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
设置
我目前有以下脚本可以使用具有多个变量的 ref 文件使用 curl
下载文件。当我创建脚本时它满足了我的需要,但是由于 ref 文件变得更大并且我通过 curl
请求的数据生成需要更长的时间,我的脚本现在需要太多时间才能完成。
Objective
我希望能够更新此脚本,所以我 curl
请求并下载多个准备就绪的文件 - 而不是等待每个文件按顺序请求和下载。
我环顾四周,发现我可以使用 xargs
或 parallel
来实现这一点,但是根据我过去看过的问题、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