There are multiple methods for functions to return values:
1st method is to provide the result in a global variable. This method also works for all POSIX-shell variants:
#!/bin/sh
# Here we use the global ret variable to get the result of the function
ret=
max() {
ret=$1
shift
for n
do
[ "$n" -gt "$ret" ] && ret=$n
done
}
max 1 8 2 7 42 23 17
printf 'The maximum of %s is %s\n' '1 8 2 7 42 23 17' "$ret"
The other common method is also POSIX-shell friendly. It involves streaming the result to stdout
(printing it), and capturing it into a variable when calling the function. This involves a sub-shell and is to be avoided in a loop for this reason:
#!/bin/sh
max() {
gtst=$1
shift
for n
do
[ "$n" -gt "$gtst" ] && gtst=$n
done
# Print the result
printf %s "$gtst"
}
# Capture the printout of max into the ret variable
ret=$(max 1 8 2 7 42 23 17)
printf 'The maximum of %s is %s\n' '1 8 2 7 42 23 17' "$ret"
The third method involves addressing a variable indirectly by its name, using eval
:
#!/bin/sh
max() {
# Get the name of the return variable
ret_name=$1
shift
gtst=$1
shift
for n
do
[ "$n" -gt "$gtst" ] && gtst=$n
done
# Evaluate expression to assign returned value to provided variable name
eval "$ret_name=$gtst"
}
# will get the result into the variable ret
max ret 1 8 2 7 42 23 17
# shellcheck disable=SC2154 # dynamically referrenced ret
printf 'The maximum of %s is %s\n' '1 8 2 7 42 23 17' "$ret"
Finally this method use nameref variables which are only available to Bash starting at version 4.2:
#!/bin/bash
max() {
# Get the name of the return variable into a nameref variable
local -n gtst=$1
local -i n
shift
gtst=$1
shift
for n
do
declare -p gtst
[ "$n" -gt "$gtst" ] && gtst=$n
done
}
# will get the result into the variable ret
declare -i ret
max ret 1 8 2 7 42 23 17
# shellcheck disable=SC2154 # dynamically referrenced ret
printf 'The maximum of %s is %s\n' '1 8 2 7 42 23 17' "$ret"
Same output for all versions:
The maximum of 1 8 2 7 42 23 17 is 42