使用參數按名稱呼叫函式
我在 shell 腳本方面還是個新手,我想知道是否可以呼叫一個函式本身而不是呼叫另一個沒有、一個或多個參數的函式。第一個參數是要呼叫的函式的名稱,其他所有參數都是要呼叫的函式的參數。
作為背景,我想編寫一個 shell 腳本來使用一些內置的 OpenFOAM 函式,即
runParallel
andrunApplication
,為了清楚起見,我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
呼叫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