이름과 매개변수로 함수 호출하기

이름과 매개변수로 함수 호출하기

저는 쉘 스크립팅을 처음 접했고, 매개변수 없이 하나 이상의 매개변수를 사용하여 다른 함수를 호출하는 대신 함수 자체를 호출하는 것이 가능한지 알고 싶습니다. 첫 번째 매개변수는 호출할 함수의 이름이고, 나머지 매개변수는 각각 호출할 함수의 매개변수입니다.

배경 지식으로, 나는 설명을 위해 위의 예에서 호출한 일부 내장 OpenFOAM 함수, 즉 runParallel및 를 사용하는 쉘 스크립트를 작성하고 싶습니다. 이러한 함수는 이름에서 알 수 있듯이 다양한 작업을 수행하며 직렬 또는 병렬 모드에서 명령을 실행합니다.runApplicationrunSerial

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

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

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

자신이 받은 것과 동일한 인수를 사용 하여 runSerialOrParallel호출 됩니다 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

관련 정보