"병렬"(GNU) 명령에 기능을 사용할 수 있게 만드는 방법은 무엇입니까?

"병렬"(GNU) 명령에 기능을 사용할 수 있게 만드는 방법은 무엇입니까?

echoBash에서 "정수"라는 인수 외에는 아무것도 하지 않는 함수를 생각해 보겠습니다 .

f () { num="${!1}"; echo $num is an integer; }
number=12
f number
# 12 is an integer

이 함수를 사용하여 파일에 몇 가지 명령을 작성한 다음 f이 함수(GNU)를 사용하여 이러한 명령을 병렬로 실행하고 싶습니다.parallel

# Write Commands to the file `Commands.txt`
rm Commands.txt
touch Commands.txt
for i in $(seq 1 5)
do
   echo "number=$i; f number" >> Commands.txt
done

모든 source것이 정상입니다

source Commands.txt
1 is an integer
2 is an integer
3 is an integer
4 is an integer
5 is an integer

그러나 명령을 병렬로 실행하려고 하면 f함수를 찾을 수 없다는 메시지가 반환됩니다.

parallel :::: Commands.txt
/bin/bash: f: command not found
/bin/bash: f: command not found
/bin/bash: f: command not found
/bin/bash: f: command not found
/bin/bash: f: command not found

파일의 모든 줄에 함수를 정의하지 않고도 함수를 f사용할 수 있게 만드는 방법이 있습니까 ?parallelCommands.txt

답변1

기본적으로 세 가지 옵션이 있습니다.

  1. export -f(이것은 POSIX가 아닌 bash 기능입니다)
  2. 각 호출에서 함수를 정의하는 셸을 실행합니다.
  3. 함수를 쉘 스크립트로 이동하고 실행하십시오.

옵션 1이 아마도 가장 설명하기 쉬울 것이므로 다음과 같이 설명하겠습니다.

$ f() { num=$1; echo "$num is an integer"; }
$ export -f f
$ cat Commands.txt 
number=1; f "$number" 
number=2; f "$number" 
number=3; f "$number" 
number=4; f "$number" 
number=5; f "$number" 
$ parallel :::: Commands.txt
1 is an integer
2 is an integer
3 is an integer
4 is an integer
5 is an integer

모집단이 잘못되었을 수 있으므로 리터럴 문자열 "number" 가 아닌 숫자를 전달 Commands.txt해야 합니다 . 이를 생성하는 스크립트는 이를 수행해야 합니다 ( 시간에 따라 해석되거나 문자열을 종료하는 것을 피하는 데 중요한 이스케이프 문자 에 유의하십시오 ).f "$number"Commands.txtf numberecho "number=$i; f \"\$number\""$numberecho"

답변2

Bash는 환경 변수를 통해 함수를 내보낼 수 있습니다.

export -f f

이는 bash 기능이며 sh 계열의 다른 쉘에서는 사용할 수 없습니다.

또는 함수를 스크립트로 만드세요. 스크립트와 함수는 함수 정의 줄을 제외하고 동일한 구문을 갖습니다.

#!/bin/bash
num="${!1}"; echo $num is an integer;

이렇게 하려면 스크립트에 전달된 변수를 내보내야 합니다. 그 안에 있는 줄은 다음 Command.txt과 같아야 합니다.

export number=1; f number

또는

number=1 f number

관련 정보