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

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

각 줄에 1, 2, 3, 4가 포함된 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없는 -d/ 여전히 질식하고 선행 공백을 제거합니다. -0GNU xargs(이미 GNU 확장을 사용하고 있으므로 사용해야 함 )의 경우 각 입력 줄을 별도의 인수로 전달 -P하는 것이 가장 좋습니다.-d '\n'

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

( 인라인 쉘 스크립트에서 참조 되는 별도의 인수로 내용과 현재 행을 사용하여 입력의 bash각 행에 대해 하나의 호출을 호출합니다.)1$a$1$2

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

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

여기에서는 별도의 쉘 호출을 실행하거나 이와 같은 기능을 내보내지 않고도 기능을 포함하여 GNU와 같은 병렬 처리를 수행할 수 있는 자동 로드 기능이 zsh있는 기능 으로 전환할 수 있습니다 .zargsxargsxargs

$ 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

관련 정보