You would do it this alternative way to work in non-bash shell:
#!/bin/sh
calc()
{
A="$1"
B="$2"
total=$(( A + B ))
diff=$(( A - B ))
# Return ASCII EOT (code 3) separated values
printf '%d\3' "$total" "$diff"
}
# Configure the Internal Field Separator to ASCII 03 End Of Text
IFS="$(printf '\3')"
# shellcheck disable=SC2046 # Intentionally split values
# Sets the arguments from the returned string
set -- $(calc 5 8)
TOT="$1"
DIF="$2"
echo "$TOT"
echo "$DIF"
One major drawback of calling the calc function in a sub-shell within the set arguments, is the loss of the function's shell return-code.
It means that it is up to the calc function to deal with erroring situations, like a division by zero.
For example: It can incorporate a return code within the returned IFS separated values.
But it means the error handling is much more complex.
I would not recommend implementing multiple return-values this way under non-bash shells.
It is still a valid option for a Bash shell to implement multi-return as an ASCII EOT delimited string, since the shell's return-code is preserved when reading and splitting the returned string the following way:
#!/usr/bin/env bash
# Call calc and parse returned split string into values
IFS=$'\3' read -r TOT DIF < <(calc 5 3)
# Save calc's return-code
_rc="$?"
# The return-code from the calc function is preserved
# and can be tested
if [ $_rc -ne 0 ]; then
printf 'calc failed with return-code %d\n' "$_rc" >&2
else
echo "$TOT"
echo "$DIF"
fi
sh(Bourne-shell) is usally not bash (Bourne-again shell).< <(...)(process substitution) is a *bashism is isn't provided by POSIX shell. You need to ensure you are invoking bash (which your#!/bin/bashshould do so long as you are not attempting to run assh yourscript). If so, usebash yourscript.