
각 줄에 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
/ 여전히 질식하고 선행 공백을 제거합니다. -0
GNU 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
있는 기능 으로 전환할 수 있습니다 .zargs
xargs
xargs
$ 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