xargs 및 개별 변수를 사용하여 함수 병렬화

xargs 및 개별 변수를 사용하여 함수 병렬화

네 줄로 구성된 텍스트 파일이 있는데 각 줄에는 1, 2, 3, 4가 있습니다. 또한 병렬화하려는 함수가 있습니다.foo() { echo "$1 is not $2"; }

함수를 내보냅니다.export -f foo

이제 병렬화를 위해 텍스트 파일의 매개변수를 사용하여 함수를 호출하고 싶습니다 xargs.그리고a=0또한 변수()를 함수의 매개변수로 사용하고 싶습니다 . 그래서 저는 함수를 호출했습니다.cat txt | xargs -I "{}" -P 2 bash -c 'foo {} $a'

하지만이는 변수( a=0)를 무시합니다. 그리고 출력:

"1은 아님"..."4는 아님" 등

호출하면 cat txt | xargs -I "{}" -P 2 bash -c 'foo {} 0'작동하고 올바른 출력을 얻습니다.

"1은 아니야0"..." 4 아니오0"등

a=0하지만 0을 사용하는 대신 변수()를 사용하여 호출 해야 합니다 . 어떻게 해야 합니까?

답변1

쉘 코드에 포함시키는 것은 {}명령 주입 취약점을 야기하므로 항상 나쁜 생각입니다. 데이터를 별도의(코드가 아닌) 매개변수로 전달하는 것이 항상 더 좋습니다.

또한 / -I가 없으면 따옴표와 백슬래시를 차단하고 선행 공백을 제거합니다. GNU (이미 GNU 확장을 사용하고 있기 때문에 사용해야 함 )의 경우 각 입력 줄을 별도의 인수로 전달하는 것이 좋습니다-d-0xargs-P-d '\n'

xargs -a txt -rd'\n' -P2 -n1 bash -c 'foo "$2" "$1"' bash "$a"

( 인라인 쉘 스크립트에서는 sum이라고 하는 별도의 인수로 현재 행의 내용을 사용하여 각 입력 행 bash에 대해 한 번씩 호출이 수행됩니다.)1$a$1$2

또는 다음을 사용하여 -I:

xargs -a txt -rd'\n' -P2 -I'{}' bash -c 'foo "$1" "$2"' bash {} "$a"

여기에서 별도의 쉘 호출을 실행하거나 함수를 내보낼 필요가 없는 기능을 포함하여 GNU처럼 병렬화 할 수 zsh있는 zargs자동 로드 가능한 기능 으로 전환할 수 있습니다 .xargsxargs

$ autoload zargs
$ foo() print -r - $1 is not $2
$ zargs -P2 -I {} {1..4} -- foo {} $a
1 is not foo
2 is not foo
3 is not foo
4 is not foo

답변2

GNU Parallel을 사용하면 다음과 같습니다:

foo() { echo "$1 is not $2"; }
export -f foo
seq 4 > txt
a=0
cat txt | parallel foo {} $a

관련 정보