Wenn Sie benannte Parameter bevorzugen, ist es möglich (mit ein paar Tricks), benannte Parameter tatsächlich an Funktionen zu übergeben (ermöglicht auch das Übergeben von Arrays und Referenzen).
Mit der von mir entwickelten Methode können Sie benannte Parameter definieren, die an eine Funktion wie die folgende übergeben werden:
function example { args : string firstName , string lastName , integer age } {
echo "My name is ${firstName} ${lastName} and I am ${age} years old."
}
Sie können Argumente auch als @required oder @readonly mit Anmerkungen versehen, ... rest-Argumente erstellen, Arrays aus sequentiellen Argumenten erstellen (z. B. string[4]
) und die Argumente optional in mehreren Zeilen auflisten :
function example {
args
: @required string firstName
: string lastName
: integer age
: string[] ...favoriteHobbies
echo "My name is ${firstName} ${lastName} and I am ${age} years old."
echo "My favorite hobbies include: ${favoriteHobbies[*]}"
}
Mit anderen Worten, Sie können Ihre Parameter nicht nur bei ihren Namen aufrufen (was einen besser lesbaren Kern ausmacht), sondern auch Arrays übergeben (und Verweise auf Variablen - diese Funktion funktioniert jedoch nur in Bash 4.3)! Außerdem befinden sich die zugeordneten Variablen alle im lokalen Bereich, genau wie $ 1 (und andere).
Der Code, mit dem dies funktioniert, ist ziemlich leicht und funktioniert sowohl in Bash 3 als auch in Bash 4 (dies sind die einzigen Versionen, mit denen ich es getestet habe). Wenn Sie an weiteren Tricks wie diesen interessiert sind, die das Entwickeln mit Bash viel schöner und einfacher machen, können Sie sich mein Bash Infinity Framework ansehen. Der folgende Code ist als eine seiner Funktionen verfügbar.
shopt -s expand_aliases
function assignTrap {
local evalString
local -i paramIndex=${__paramIndex-0}
local initialCommand="${1-}"
if [[ "$initialCommand" != ":" ]]
then
echo "trap - DEBUG; eval \"${__previousTrap}\"; unset __previousTrap; unset __paramIndex;"
return
fi
while [[ "${1-}" == "," || "${1-}" == "${initialCommand}" ]] || [[ "${#@}" -gt 0 && "$paramIndex" -eq 0 ]]
do
shift # first colon ":" or next parameter's comma ","
paramIndex+=1
local -a decorators=()
while [[ "${1-}" == "@"* ]]
do
decorators+=( "$1" )
shift
done
local declaration=
local wrapLeft='"'
local wrapRight='"'
local nextType="$1"
local length=1
case ${nextType} in
string | boolean) declaration="local " ;;
integer) declaration="local -i" ;;
reference) declaration="local -n" ;;
arrayDeclaration) declaration="local -a"; wrapLeft= ; wrapRight= ;;
assocDeclaration) declaration="local -A"; wrapLeft= ; wrapRight= ;;
"string["*"]") declaration="local -a"; length="${nextType//[a-z\[\]]}" ;;
"integer["*"]") declaration="local -ai"; length="${nextType//[a-z\[\]]}" ;;
esac
if [[ "${declaration}" != "" ]]
then
shift
local nextName="$1"
for decorator in "${decorators[@]}"
do
case ${decorator} in
@readonly) declaration+="r" ;;
@required) evalString+="[[ ! -z \$${paramIndex} ]] || echo \"Parameter '$nextName' ($nextType) is marked as required by '${FUNCNAME[1]}' function.\"; " >&2 ;;
@global) declaration+="g" ;;
esac
done
local paramRange="$paramIndex"
if [[ -z "$length" ]]
then
# ...rest
paramRange="{@:$paramIndex}"
# trim leading ...
nextName="${nextName//\./}"
if [[ "${#@}" -gt 1 ]]
then
echo "Unexpected arguments after a rest array ($nextName) in '${FUNCNAME[1]}' function." >&2
fi
elif [[ "$length" -gt 1 ]]
then
paramRange="{@:$paramIndex:$length}"
paramIndex+=$((length - 1))
fi
evalString+="${declaration} ${nextName}=${wrapLeft}\$${paramRange}${wrapRight}; "
# continue to the next param:
shift
fi
done
echo "${evalString} local -i __paramIndex=${paramIndex};"
}
alias args='local __previousTrap=$(trap -p DEBUG); trap "eval \"\$(assignTrap \$BASH_COMMAND)\";" DEBUG;'