我在 shell 脚本方面相当陌生,想知道是否可以调用一个函数本身,而不是调用另一个不带参数、一个或多个参数的函数。第一个参数是要调用的函数的名称,其他每个参数都是要调用的函数的参数。
作为背景,我想编写一个 shell 脚本来使用一些内置的 OpenFOAM 函数,即runParallel
和runApplication
,为了澄清起见,我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