인수가있는 이름으로 함수 호출

Oct 20 2020

나는 쉘 스크립팅 분야에서 꽤 새로운 편이고, 하나도, 하나 또는 여러 개의 인수로 다른 함수를 호출하는 것보다 자체적으로 함수를 호출 할 수 있는지 궁금합니다. 첫 번째 인수는 호출 할 함수의 이름이고 다른 모든 인수는 호출 할 함수의 인수입니다.

배경으로, 내가 사용하는 쉘 스크립트를 작성하려는 일부 내장 OpenFOAM의 즉 기능 runParallelrunApplication설명을 위해, 내가 전화, runSerial위의 예에서. 이름에서 알 수 있듯이 이러한 기능은 직렬 또는 병렬 모드로 명령을 실행하므로 다른 작업을 수행합니다.

OpenFOAM의 시뮬레이션은 여러 함수 호출로 구성되어 있으며 제가 원하는 것은 코드를 줄여서이 대신

#!/bin/sh

# $n_core is a user input how many cores to use printf 'On how many cores do you want to run the simulation?' read -r n_core if [ $n_core -eq "1" ]; then
  runSerial "functionOne"  # no arguments here
  runSerial "functionTwo" "arg1"
  runSerial "functionThree" "arg1" "arg2"
  ...
else
  runParallel "functionOne"  # no arguments here
  runParallel "functionTwo" "arg1"
  runParallel "functionThree" "arg1" "arg2"
  ...
fi

나는 이것을 이와 같은 것으로 바꿀 수 있는지 궁금했습니다.

#!/bin/sh

runSerialOrParallel()
{
    if [ $n_core -eq "1" ]; then runSerial "$1" "$2" ... else runParallel "$1" "$2" ... fi } # $n_core is a user input how many cores to use
printf 'On how many cores do you want to run the simulation?'
read -r n_core

runSerialOrParallel "functionOne"  # no arguments here
runSerialOrParallel "functionTwo" "arg1"
runSerialOrParallel "functionThree" "arg1" "arg2"

현재 내 runSerialOrParallel함수가 자신을 호출해야하는 함수에 대한 인수를 설명하는 방법에 대한 질문에 갇혀 있습니다. 따라서 functionTwo하나의 인수를 사용하여 직렬 또는 병렬로 실행하려면 functionTwo어떻게해야 runSerialOrParallel합니까?

어떤 도움을 주시면 대단히 감사하겠습니다. 제가 쉽게 찾을 수 있었지만 발견하지 못한 그 질문에 대한 모욕적 인 대답이 있다면 저를 용서해주십시오.

건배!

(저는 편집이 몇 가지 문제를 해결했으면 좋겠습니다. ..)

답변

1 StéphaneChazelas Oct 20 2020 at 14:53

Bourne과 같은 쉘 "$@"(따옴표가 중요합니다!)에서는 스크립트의 모든 인수로 확장되거나 함수 내에서 확장 된 경우 함수로 확장됩니다.

runSerialOrParallel()
{
    if [ "$n_core" -eq 1 ]; then
        runSerial "$@" else runParallel "$@"
    fi
}

만들 것 runSerialOrParallel있는 invoke runSerial또는 runParallel그 자체를받은 같은 인수. 첫 번째 인수가 함수 이름이고 해당 함수에 전달할 다음 인수가 더 있으면 runSerial함수는 다음과 같을 수 있습니다.

runSerial() {
  printf 'Running "%s" with %u argument%s:\n' "$1" "$(($# - 1))" "${3+s}"
  "$@"
}

(첫 번째 인수가 함수, 외부 명령 또는 내장 여부는 여기서 차이가 없습니다).

또는:

runSerial() {
  funcName=${1?No function specified}
  shift # removes the func name from the arguments

  printf 'Running "%s" with %u argument%s:\n' "$funcName" "$#" "${2+s}" "$funcName" "$@"
}

( ${2+s}로 확장 s번째 인수 (처음 세 번째)는 적어도 두 개의 인자하는 복수의 "인자"로 "인자"켜 지정되면 $funcName지정된 참조).

$ runSerial echo foo bar
Running "echo" with 2 arguments:
foo bar
$ runSerial echo foo Running "echo" with 1 argument: foo $ n_core=1
$ runSerialOrParallel echo foo
Running "echo" with 1 argument:
foo