GNU 병렬 사용 - 현재 전달된 문자열을 어떻게 병렬로 가져오나요?

GNU 병렬 사용 - 현재 전달된 문자열을 어떻게 병렬로 가져오나요?

저는 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에서 실행되는 셸 코드 내부의 별도 변수 로 출력을 캡처하면 비교(또는 원하는 모든 작업)를 수행할 수 있습니다.parallelparallel거기, 병행하여. 그리고 예를 들어printf 조건부로. 내부가 parallel외부에서 예상하는 형식으로 출력을 생성하는 한 원하는 논리를 구현하는 것은 사용자에게 달려 있습니다 read.

전달된 셸 코드는 parallel여전히 작은따옴표로 묶어야 합니다. 코드가 커짐에 따라 바로 이 코드에 작은따옴표를 사용(포함)해야 할 수도 있습니다. 그러면 인용이 다소 복잡해지고 읽기가 어려워집니다. 이러한 상황에서는 독립적으로 인용할 수 있는 별도의 스크립트로 코드를 이동하는 것이 좋습니다. 다음과 같이 기본 스크립트에서 호출합니다.

while read … ; done < <( … | parallel -j 20 -k 'path/to/separate_script {}' )

separate_script대체된 문자열 내부에서는 {}다음과 같이 사용할 수 있습니다 $1(잊지 마세요).큰따옴표로 묶으세요).

관련 정보