Bash:并行卷曲和变量

Bash:并行卷曲和变量

我想在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 以获得更多或更少的并行数。

相关内容