I have a function like this
print_stuff_and_set_vars() {
IMPORTANT_VAL_1=""
IMPORTANT_VAL_2=""
echo -n "some stuff"
echo -n "some more stuff"
echo -n "result"
}
and I call it like this:
my_main_func() {
print_stuff_and_set_vars
print_stuff_and_set_vars
print_stuff_and_set_vars
echo "IMPORTANT_VAL_1 was $IMPORTANT_VAL_1"
}
Instead, I want to save all the echoed results to a string
my_main_func() {
# doesn't work -- result is empty
result="${print_stuff_and_set_vars}${print_stuff_and_set_vars}${print_stuff_and_set_vars}"
echo "the result length was ${#result}"
echo "$result"
echo "IMPORTANT_VAL_1 was $IMPORTANT_VAL_1"
}
This does work if I use $()
instead of ${}
to start a subshell, but then the global variables are not set.
Is there any way to save the result of a function to a string without starting a subshell? I know the obvious answer in this example would be to save "result" to a global variable instead of echoing it but in my actual script that would require a lot of changes and I want to avoid it if possible.
Actually, I only need to know the length so if there is a way to keep track of how much has been printed since the start of the function that would work fine too. I'm actually using zsh
if that makes a difference, too.
Assuming the output from the function print_stuff_and_set_vars
does not contain newline characters, how about:
mkfifo p # create a named pipe "p"
exec 3<>p # open fd 3 for both reading and writing
rm p # now "p" can be closed
print_stuff_and_set_vars() {
IMPORTANT_VAL_1="foo"
IMPORTANT_VAL_2="bar"
echo -n "some stuff "
echo -n "some more stuff "
echo -n "result "
}
my_main_func() {
print_stuff_and_set_vars 1>&3 # redirect to fd 3
print_stuff_and_set_vars 1>&3 # same as above
print_stuff_and_set_vars 1>&3 # same as above
echo 1>&3 # send newline as an end of input
IFS= read -r -u 3 result # read a line from fd 3
echo "the result length was ${#result}"
echo "$result"
echo "IMPORTANT_VAL_1 was $IMPORTANT_VAL_1"
}
my_main_func
exec 3>&- # close fd 3
Output:
the result length was 102
some stuff some more stuff result some stuff some more stuff result some stuff some more stuff result
IMPORTANT_VAL_1 was foo