GNU Parallel 메일링 리스트에 따르면 이는 GNU Parallel 특정 문제가 아닙니다. 그들은 내가 여기에 내 문제를 게시할 것을 제안했습니다.
제가 받고 있는 오류는 "깨진 파이프" 오류입니다. 하지만 먼저 문제의 맥락과 이 오류의 원인을 설명해야 한다고 생각합니다. GNU Parallel에서 '읽는 동안' 루프가 포함된 bash 스크립트를 사용하려고 할 때 발생합니다.
다음과 같은 기본 bash 스크립트가 있습니다.
#!/bin/bash
# linkcheck.sh
while read domain
do
host "$domain"
done
큰 목록(250MB)을 파이프로 연결하고 싶다고 가정해 보겠습니다.
cat urllist | ./linkcheck.sh
250MB 상당의 URL에 대해 호스트 명령을 실행하는 것은 다소 느립니다. 속도를 높이기 위해 입력을 파이핑하기 전에 여러 개의 덩어리로 나누고 여러 작업을 병렬로 실행하고 싶습니다. GNU Parallel은 이를 수행할 수 있습니다.
cat urllist | parallel --pipe -j0 parallel ./linkcheck.sh {}
{}는 urllist의 내용으로 한 줄씩 대체됩니다. 내 시스템 기본 설정이 병렬 인스턴스당 500개의 작업을 실행할 수 있다고 가정합니다. 이 제한을 해결하기 위해 Parallel 자체를 병렬화할 수 있습니다.
cat urllist | parallel -j10 --pipe parallel -j0 ./linkcheck.sh {}
이것은 5000'ish 작업을 실행합니다. 또한 슬프게도 "깨진 파이프" 오류가 발생합니다.(배시 FAQ). 그러나 while 읽기 루프를 제거하고 {}에 공급되는 모든 것에서 직접 입력을 받으면 스크립트가 작동하기 시작합니다. 예:
#!/bin/bash
# linkchecker.sh
domain="$1"
host "$1"
왜 while 읽기 루프에서는 작동하지 않습니까? "깨진 파이프" 메시지를 중지하기 위해 SIGPIPE 신호를 끄는 것이 안전합니까? 아니면 데이터 손상과 같은 부작용이 있습니까?
읽어 주셔서 감사합니다.
답변1
그래서 그랬데
고양이 URL 목록 | 병렬 --pipe -j0 병렬 ./linkcheck.sh {}
올바르게 작동합니까? 나는 당신의 문제의 일부가 다음 --pipe
과 같이 두 번째를 생략했다는 것일 수 있다고 생각합니다.
고양이 URL 목록 | 병렬 -j10 --파이프 병렬 -j0--파이프./linkcheck.sh {}
그런데, 말할 필요도 없지
고양이one_file|some_command
언제든지 이것을 다음으로 변경할 수 있습니다.
some_command<one_file
결과적으로 프로세스가 하나 줄어들고 파이프도 하나 줄어듭니다. ( cat
입력 파일이 여러 개인 경우 사용하는 것이 적절하거나 필요할 수 있습니다 .)
답변2
파이프가 아직 열려 있는 동안 하위에서 linkcheck.sh의 다른 복사본을 실행하도록 분기하는 것과 하위가 실제로 읽으려고 시도하는 사이의 창으로 인해 잘못된 경쟁 조건으로 인해 오류가 발생할 수 있는 것 같습니다. 해당 창에서 다른 복사본이 EOF를 읽었고 파이프가 닫혔습니다.