저는 GNU 병렬을 사용하고 있으며 이해하고 싶습니다. 각 병렬 명령에 개별 문자열을 전달하려면 어떻게 해야 합니까?
예로서,GNU 병렬 문서현재 디렉터리에서 다른 디렉터리로 파일을 이동하는 방법을 보여줍니다.
ls | parallel mv {} destdir
그렇다면 병렬로 전달된 각 파일을 개별적으로 가져오거나 인쇄하는 방법이 있습니까?
병렬 처리 사례
여러 사이트를 확인하고 기록하는 병렬 처리를 해야 하는데
- http 반환 코드(2xx, 4xx, 5xx)
- 소스 URL
- 최종 도착 URL
- 컬 종료 코드
이 작업을 수행하는 코드는 다음과 같습니다.
unset return_code_array
unset destination_url_array
unset exit_code_array
while read -r return_code_var destination_url_var exit_code_var; do
destination_url_array+=("$destination_url_var")
exit_code_array+=("$exit_code_var")
return_code_array+=("$return_code_var")
done < <(printf '%s\n' "${all_valid_URLs_array[@]}" | parallel -j 20 -k 'curl --max-time 20 -sL -o /dev/null -w "%{response_code} %{url_effective} " {}; printf "%s %s\n" "$?" ')
결과적으로 세 개의 배열이 있고 여기에는 항목에 해당하는 각 줄에 대한 HTTP 반환 코드, 최종 대상 URL 및 컬 종료 코드 상태가 포함되어 있습니다 all_valid_URLs_array
. 동시에 destination_url_var
소스 URL과 일치하는지 비교하는 등 각각에 대해 일부 처리를 수행해야 하지만 병렬로 전달된 문자열을 가져오는 방법을 모릅니다.
현재 이러한 처리를 위해 위 루프 이후 두 번째 루프를 실행하고 있지만 원하는 작업이 가능한지 알고 싶습니다.
감사해요.
답변1
귀하의 예에서 'curl … {}; printf "%s %s\n" "$?" '
(두 번째 이유는 무엇입니까 %s
?) 작은 따옴표로 묶인 쉘 코드입니다. 여기에서 {}
두 번 이상 사용할 수 있습니다 .
curl … {}; printf "%s %s\n" "$?" {}
또는 변수를 생성하고 원하는 만큼 여러 번 사용하세요. 변수 이름은 설명적일 수 있으며 이는 장점입니다. 또 다른 장점이 있습니다. 일반적으로 대체되는 것은 {}
긴 문자열일 수 있으며, 이를 여러 번 대체하면 코드가 parallel
특정 쉘로 전달될 수 있습니다. IMO 한 번 대체하고 쉘이 문자열을 저장하고 재사용하도록 하는 것이 더 좋습니다.
source_URL={}; curl … "$source_URL"; printf "%s %s\n" "$?" "$source_URL"
GNU의 경우 쉘 코드에 parallel
포함시키는 것이 안전합니다 . {}
이 답변에서 명시적으로 언급된 예외는 다음과 같습니다.{}
쉘 코드에 절대로 포함하지 마십시오 !. 아마 당신도 이미 알고 있을 것입니다. 이 발언은 일반 청중을 위한 것입니다.
read
메인 루프를 조정해야 합니다 . 이제 읽어야 합니다.네변수. 이렇게 하면 소스 URL을 내부에서 parallel
메인 루프로 전송하여 이를 비교하거나 destination_url_var
원하는 작업을 수행할 수 있습니다.
여전히 이 접근 방식에서는 "원하는 모든 것"이 병렬화되지 않습니다.
외부에서 캡처하도록 인쇄하는 대신 curl
에서 실행되는 셸 코드 내부의 별도 변수 로 출력을 캡처하면 비교(또는 원하는 모든 작업)를 수행할 수 있습니다.parallel
parallel
거기, 병행하여. 그리고 예를 들어printf
조건부로. 내부가 parallel
외부에서 예상하는 형식으로 출력을 생성하는 한 원하는 논리를 구현하는 것은 사용자에게 달려 있습니다 read
.
전달된 셸 코드는 parallel
여전히 작은따옴표로 묶어야 합니다. 코드가 커짐에 따라 바로 이 코드에 작은따옴표를 사용(포함)해야 할 수도 있습니다. 그러면 인용이 다소 복잡해지고 읽기가 어려워집니다. 이러한 상황에서는 독립적으로 인용할 수 있는 별도의 스크립트로 코드를 이동하는 것이 좋습니다. 다음과 같이 기본 스크립트에서 호출합니다.
while read … ; done < <( … | parallel -j 20 -k 'path/to/separate_script {}' )
separate_script
대체된 문자열 내부에서는 {}
다음과 같이 사용할 수 있습니다 $1
(잊지 마세요).큰따옴표로 묶으세요).