Skip to content

Instantly share code, notes, and snippets.

@thwarted
Last active June 10, 2022 22:31
Show Gist options
  • Save thwarted/eb0d9f59e41373a1fb6b to your computer and use it in GitHub Desktop.
Save thwarted/eb0d9f59e41373a1fb6b to your computer and use it in GitHub Desktop.
defines a function `assign` that allows returning multiple values from a function/command
#!/bin/bash
# assign var1 varN... = c arg...
# execute c and assign captured values to the list of variables
#
# values can be output from c by redirecting/writing to:
# >${outvar[x]}
# >&x
# where x is the index of the variable you want to return the value
# in
assign() {
local tdir=$( mktemp -d )
local resetnullglob
shopt -u | grep -q nullglob && resetnullglob=1 && shopt -s nullglob
trap 'rm -rf "$tdir"' RETURN
local -a outvar
local ret redirs c=1
while [[ $# -gt 0 && $1 != = ]]; do
> "${tdir}/${1}"
outvar[$c]="${tdir}/${1}"
redirs="$redirs ${c}>${tdir}/${1}"
shift
c=$(( c + 1 ))
done
shift
if [[ $# -ne 0 ]]; then
eval "$@" $redirs
ret=$?
local varfile varname resetnullglob
for varfile in $tdir/* ; do
varname=${varfile##*/}
eval "${varname}"'=$(<$varfile)'
done
fi
[[ $resetnullglob ]] && shopt -u nullglob
return $ret
}
# modstrings_and_fortune
# invoke with `assign`
# in $@:
# $1: <string to uppercase>
# $2: <string to lowercase>
# $3: <string to remove numbers from>
# out:
# 1: <uppercased string>
# 2: <lowercased string>
# 3: <string without numbers>
# 4: <a fortune>
modstrings_and_fortune() {
local inarg1=${1}
local inarg2=${2}
local inarg3=${3}
echo "${inarg1}" | tr a-z A-Z > ${outvar[1]}
echo "${inarg2}" | tr A-Z a-z > ${outvar[2]}
echo "${inarg3}" | tr -d 0-9 > ${outvar[3]}
fortune > ${outvar[4]} 2>&1
return 27
}
main() {
local var1 var2 var3 myfortune
local stdout stderr
assign var1 var2 var3 myfortune = modstrings_and_fortune uppercaseme LOWERCASEME no23423432numbers
echo "ret=$?"
echo "var1=$var1"
echo "var2=$var2"
echo "var3=$var3"
echo "fortune=$myfortune"
echo
# there are readable and unreadable directories in /var/log
# find will produce output on both stdout and stderr in that case
assign stdout stderr = find /var/log
echo "filecount=$( wc -l <<<"$stdout" )"
echo "errorlines=$( wc -l <<<"$stderr" )"
}
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment