我想在bash中执行这个脚本,这样我就可以理解它并稍后用python(我知道的少得多)编写它。
我的数据中有一些文件。 3、仅此而已。
https://www.example.com/data/file27-1.jpg
https://www.example.com/data/file51-2.jpg
https://www.example.com/data/file2576-3.jpg
URL='https://www.example.com/data/file'
i=1 ; j=1
for i in {1..3000} ; do
curl -I ${URL}file${i}-{j}.jpg
# here, pipe result into grep,
### if !200 ((i++)) (so do nothing) ;
### if 200 wget $URL$i$j and ((j++)), and i=i-1 so I can have the same $i at the next loop, for a incremented $j
" and go on into the the for loop
done
但curl
单独获取 3000 个链接需要一些时间。我想curl -I URL
以某种方式并行化,当我收到 200 响应时,停止所有进程请求,因为不会有两个文件具有相同的 $j 值,将 1 添加到 $j,并将所有内容恢复到适当的值值 $i 和 $j 并继续。
我陷入了并行化(但发现了很多线程),但真正阻碍我的部分是 200 会杀死所有卷曲进程,然后恢复到 200 OK $i 和 $j 值。
我希望我是可以理解的。我还没有编写示例脚本,我正在研究实现它的方法。
谢谢
编辑
#ps -ax | grep "curl" | grep -v "grep" | awk '{print $1}'| xargs kill -9
我发现我可以使用该命令来终止所有可以在条件下使用的curl请求if 200
,然后使用i=i-1重新设置$i值,增加$j,然后继续循环。
但在这个阶段,没有任何东西是并行化的:我可以找出如何使用 xargs 并行化curl请求,但我不能这样做来增加它的值。
我想到了一个临时文件,其中生成了 URL,但我希望它随着脚本的运行而生成。
答案1
这是一个小片段,可以帮助您完成您想要做的事情,我希望逻辑正确:
#!/bin/bash
i=0
j=0
pid=0
ppid=0
#Enable job control; It's not used here but it can be usefull if you need to do more job control
set -m
for i in {1..3000} ; do
#Execute each curl in the background to have a sort of multi-threading and get get the HEAD response status and put it in file descriptor 3 to be gathered later
exec 3< <(curl -I ${URL}file${i}-{j}.jpg | head -n 1 | cut -d$' ' -f2)
#Get the pid of the background job
pid="$!"
#Get the parent pid of the background job
ppid="$(ps -o ppid= -p $pid)"
#Gather the HTTP Response code
status="$(cat <&3)"
#Check
if [ "$status" -eq 200 ] ; then
i="$(($i - 1))"
j="$(($j + 1))"
echo "kill all previous background process by their parent"
pkill -P $ppid
else
i="$(($i + 1))"
fi
echo " status : $status"
echo " parent : $ppid"
echo " child : $pid"
done
答案2
如果你有 GNU Parallel,类似这样的东西应该可以工作(i=1..3000;j=1..1000):
do_j() {
j=$1
URL='https://www.example.com/data/file'
seq 3000 |
parallel --halt soon,success=1 -j100 "curl -I ${URL}file{}-${j}.jpg | grep 'HTTP.* 200 OK'"
}
export -f do_j
seq 1000 | parallel -j1 do_j
调整 -j1 和 -j100 以获得更多或更少的并行数。