Shell-Script

使用參數按名稱呼叫函式

  • October 20, 2020

我在 shell 腳本方面還是個新手,我想知道是否可以呼叫一個函式本身而不是呼叫另一個沒有、一個或多個參數的函式。第一個參數是要呼叫的函式的名稱,其他所有參數都是要呼叫的函式的參數。

作為背景,我想編寫一個 shell 腳本來使用一些內置的 OpenFOAM 函式,即runParalleland 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呢?

任何幫助將不勝感激,如果對這個問題有褻瀆的答案,我很容易找到但沒有找到,請原諒我。

乾杯!

(我希望編輯清除了一些東西,我的壞..)

在類似 Bourne 的 shell"$@"中(注意引號很重要!)擴展為腳本的所有參數,或者如果在函式內部擴展,則擴展為函式,所以在這裡:

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

runSerialOrParallel呼叫runSerialrunParallel使用它自己收到的相同參數。如果第一個參數是函式名,而後面的參數是要傳遞給該函式的更多參數,那麼您的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

引用自:https://unix.stackexchange.com/questions/615299