通过名称和参数调用函数

通过名称和参数调用函数

我在 shell 脚本方面相当陌生,想知道是否可以调用一个函数本身,而不是调用另一个不带参数、一个或多个参数的函数。第一个参数是要调用的函数的名称,其他每个参数都是要调用的函数的参数。

作为背景,我想编写一个 shell 脚本来使用一些内置的 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

在类似 Bourne 的 shell 中"$@"(请注意,引号很重要!)扩展为脚本的所有参数,或者如果在函数内部扩展则扩展为函数,因此这里:

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

相关内容