나는 이 스크립트를 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 값을 가진 두 개의 파일이 없기 때문에 모든 프로세스 요청을 중지하고 $j에 1을 추가한 다음 모든 것을 적절한 값으로 복원합니다. $i와 $j를 누르고 계속하세요.
나는 병렬화(그러나 많은 스레드를 찾는 것)에 갇혀 있지만 실제로 나를 방해하는 부분은 200이 모든 컬 프로세스를 종료한 다음 $i 및 $j 값에 대해 200 OK로 되돌아간다는 것입니다.
나는 이해하기를 바랍니다. 아직 샘플 스크립트를 작성하지 않았으며 이를 구현하는 방법을 연구 중입니다.
감사해요
편집하다
#ps -ax | grep "curl" | grep -v "grep" | awk '{print $1}'| xargs kill -9
나는 이 명령을 사용하여 조건부에서 사용할 수 있는 모든 컬 요청을 종료한 if 200
다음 $i 값을 i=i-1로 재설정하고 $j를 증가시키며 루프를 계속할 수 있다는 것을 알았습니다.
하지만 이 단계에서는 아무것도 병렬화되지 않습니다. xargs를 사용하여 컬 요청을 병렬화하는 방법을 알아낼 수 있지만 그렇게 하여 그 가치를 높일 수는 없습니다.
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을 조정하십시오.