내가 여기서 하고 있는 일은 약간 복잡하므로 이해가 될 만큼 충분히 잘 설명할 수 있기를 바랍니다. tldr 버전은 파일에서 10줄을 읽은 다음 해당 파일의 입력을 기반으로 스크립트를 실행하려는 것입니다. 완료되면 파일이 완성될 때까지 다음 10단계를 계속한 다음 종료됩니다.
이것은 긴 이야기입니다. 뉴스그룹의 일부 보관 작업을 수행하려고 합니다. 보관하려는 42227개의 뉴스그룹 목록이 있습니다. 유즈넷 서버에서 정보를 추출하기 위해 sinntp 애플리케이션을 사용하고 있습니다. Python으로 작성되었으며 심각한 버그가 있습니다. 뉴스 그룹 메시지가 손실되면 재시도 없이 명령이 실패합니다.
내 솔루션은 downloader.sh입니다. sinntp가 실패하면 downloader.sh는 완료될 때까지 강제로 재시도합니다. 완료되면 영구 저장을 위해 출력 파일의 이름을 바꾸고 압축합니다(최종적으로 archive.org에 저장).
다운로더.sh:
#!/bin/bash
while getopts g: flag
do
case "${flag}" in
g) group=${OPTARG};;
esac
done
downloader() {
nntp-pull $group
}
until downloader; do
echo "restarting download" >&2
sleep 1
done
if [ $? -eq 0 ]; then
mv -v $group $group.mbox && zip -rm $group.mbox.zip $group.mbox
fi
이번에는 하나의 뉴스그룹만 다운로드됩니다. 또한 메인 뉴스그룹 파일을 읽고 downloader.sh를 병렬로 실행하는 두 번째 스크립트 archiver.sh를 작성했습니다.
아카이버.sh
#!/bin/bash
cat newsgroup_list_working.txt | parallel -j 10 ./downloader.sh -g {}
그러나 실제로는 작동하지 않았습니다. 여러 번 다운로드가 중단되고 새 다운로드가 시작되지 않습니다. 디스크나 메모리가 부족하지 않고 CPU 성능도 100%가 아닙니다. 또한 문제 없이 다른 작업을 실행할 수 있으므로 디스크 I/O가 최대치에 이르지 않습니다. 다운로드 속도가 1MB가 조금 넘는 정도라서 네트워크에는 문제가 없는 것 같습니다.
어떤 조언이라도 대단히 감사하겠습니다!
답변1
명령당 10개의 인수를 읽을 수 있습니다.
cat file | parallel -N10 ./downloader.sh -g {5}
여기서 5는 뉴스 그룹 이름이 포함된 줄입니다.
--dry-run
GNU Parallel에게 실행할 명령을 표시하도록 지시하는 데 사용됩니다 .
cat file | parallel --dry-run -N10 ./downloader.sh -g {5}
-j 300%
올바른 명령이 표시되면 각 CPU 스레드가 3개의 작업을 병렬로 실행하도록 조정할 수 있습니다 .