Funktion mit Namen mit Argumenten aufrufen
Ich bin ziemlich neu in der Shell-Scripting-Front und habe mich gefragt, ob es möglich ist, eine Funktion aufzurufen, die selbst eine andere Funktion mit keinem, einem oder mehreren Argumenten aufruft. Das erste Argument wäre der Name der aufzurufenden Funktion, jedes andere Argument ist ein Argument für die aufzurufende Funktion.
Als Hintergrund möchte ich ein Shell-Skript schreiben, um einige integrierte OpenFOAM-Funktionen zu verwenden, nämlich runParallelund runApplication, die ich zur Verdeutlichung runSerialim obigen Beispiel aufgerufen habe . Diese Funktionen führen verschiedene Aktionen aus, da der Name andeutet, dass sie einen Befehl entweder im seriellen oder im parallelen Modus ausführen.
Eine Simulation in OpenFOAM besteht aus mehreren Funktionsaufrufen und alles, was ich tun möchte, ist, den Code so zu kürzen, dass stattdessen
#!/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
Ich fragte mich, ob ich das durch so etwas ersetzen könnte
#!/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"
Im Moment stecke ich bei der Frage fest, wie die Argumente für die Funktion zu erklären sind, die meine runSerialOrParallelFunktion selbst aufrufen soll. Wenn ich functionTwoalso seriell oder parallel ausgeführt werden möchte , mit einem Argument für sich functionTwoselbst, wie kann ich das im Inneren erreichen runSerialOrParallel?
Jede Hilfe wäre sehr dankbar und bitte verzeihen Sie mir, wenn es eine profane Antwort auf diese Frage gibt, die ich leicht hätte finden können, aber nicht.
Prost!
(Ich hoffe, die Bearbeitung hat einige Dinge geklärt, mein schlechtes ..)
Antworten
In Bourne-ähnlichen Shells "$@"(beachten Sie, dass die Anführungszeichen wichtig sind!) Wird auf alle Argumente des Skripts oder der Funktion erweitert, wenn diese innerhalb einer Funktion erweitert werden.
runSerialOrParallel()
{
if [ "$n_core" -eq 1 ]; then
runSerial "$@" else runParallel "$@"
fi
}
Würde runSerialOrParallelaufrufen runSerialoder runParallelmit den gleichen Argumenten, die es selbst erhalten hat. Wenn das erste Argument ein Funktionsname sein soll und die folgenden weiteren Argumente an diese Funktion übergeben werden sollen, runSerialkönnte Ihre Funktion ungefähr so aussehen:
runSerial() {
printf 'Running "%s" with %u argument%s:\n' "$1" "$(($# - 1))" "${3+s}"
"$@"
}
(Beachten Sie, dass es hier keinen Unterschied macht, ob das erste Argument eine Funktion, ein externer Befehl oder ein eingebautes Argument ist.)
Oder:
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" "$@"
}
(Das wird ${2+s}erweitert, swenn das zweite Argument (anfangs das dritte) angegeben wird, um "Argument" in mehrere "Argumente" umzuwandeln, wenn mindestens zwei Argumente $funcNameangegeben werden sollen.)
$ 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