GNU를 사용한 병렬 연산

GNU를 사용한 병렬 연산

2의 거듭제곱을 통해 일부 스크립트를 병렬로 실행하고 싶습니다. 내가 원하는 두 가지 기능의 목록을 GNU Parallel에 제공하면 잘 작동합니다.

%>parallel echo {} ::: 32, 64, 128, 256, 512, 1024
32
64
128
256
512
1024
%>

또한 문제 없이 GNU Parallel에 다양한 값을 제공할 수 있습니다.

%>parallel echo {} ::: {5..10}
5
6
7
8
9
10
%>

그러나 GNU Parallel 명령에 산술 비트를 포함하자마자 구문 오류가 발생합니다.

%>parallel echo $((2**{})) ::: {5..10}
bash: 2**{}: syntax error: operand expected (error token is "{}")
%>

다음과 같이 for 루프에서 이러한 값을 생성할 수 있다는 사실이 놀랍습니다.

%>for N in {5..10}; do echo $((2**N)); done
32
64
128
256
512
1024
%>

GNU Parallel을 사용하여 이를 수행하는 방법은 무엇입니까? 나는 순서에 관심이 없습니다.

답변1

실행 중인 전체 명령을 인용해야 합니다 parallel. 예를 들면 다음과 같습니다.

$ parallel 'echo $((2**{}))' ::: {5..10}
32
64
128
256
512
1024

실제로 명령의 bash 산술 부분을 인용하는 것만으로도 효과가 있습니다.

$ parallel echo '$((2**{}))' ::: {5..10}
32
64
128
256
512
1024

그 이유는 따옴표가 없으면 bash는 산술을 확장하고 평가하려고 시도하기 때문입니다.앞으로그것을 넘겨준다고 해서 parallel때릴 2**{}만한 가치가 있는 것이 없다는 의미는 아닙니다. 오류 메시지는 실제로 병렬이 아닌 bash에서 발생합니다.

$ echo $((2**{}))
-bash: 2**{}: syntax error: operand expected (error token is "{}")

답변2

@cas는 쉘 사용 방법을 보여줍니다. 저는 개인적으로 문자열을 대체하기 위해 {= perl =}을 사용하는 것을 좋아합니다.

parallel echo '{= $_=2**$_ =}' ::: {5..10}

그러나 차이점은 미미하고 취향의 문제입니다.

$(( expression ))Perl 버전이 더 나은 경우도 있습니다. 어떤 이유로든 구조가 없는 쉘(예: 물고기)을 사용해야 하거나 더 많은 계산 능력이 필요한 경우:parallel echo '{= $_=2**($_/2) =}'

관련 정보