0

I have many functions which return an array.

function myfunction() {
local -i status=0
local -a statusmsg=()

... do ....
statusmsg=($(do something ...)) 

if [[ ${status} -eq 0 ]]; then
   ....
   return 0
else
   for (( statusmsgline=0; statusmsgline<${#statusmsg[@]}; statusmsgline++ ))
   do
      printf "%s\n" "${statusmsg[${statusmsgline}]}"
   done
   return 1
fi
}

in the script I use mapfile as suggested here How to return an array in bash without using globals?

mapfile -t returnmsg <<< "$(myfunction "${param1}" "${param2}" "${paramX}" ...)"
if [ $? -eq 1 ]] ; then
 ... do something
fi

Using mapfile the array is well returned as it was generated but return code is ever and ever 0 (mapfile exit code) and can't retrieve the status code returned by the function. I tried to use shopt -s lastpipe and shopt -so pipefail but without any success.

Is there any way to retrieve the array from function and the exit code at the same time ?

Kind Regards

Community
  • 1
  • 1
moocan
  • 111
  • 2
  • 11

1 Answers1

0

Read the whole array into one string variable, evaluate the status, then pass the string variable on to mapfile.

output=$(myfunction ...)
if [ $? -eq 1 ] ; then
  # do something
fi
mapfile -t array <<< "$output"

Warning: if the output of myfunction is very long the script may become slow or may even run out of memory. In this case you should write to a file or file descriptor instead.

The $() removes trailing empty lines. If those are important to you, then you can write either the exit status or the output to a file. Here we write the exit status at it is always short. Writing a long output to the file system and reading it afterwards would have more overhead.

mapfile -t array <(myfunction ...; echo $? > /tmp/status)
if [ "$(< /tmp/status; rm -f /tmp/status)" -eq 1 ] ; then
  # do something
fi

There's also a way to work without these temporary variables/files by leveraging bash's options:

shopt -s lastpipe
myfunction ... | mapfile -t array
if [ "${PIPESTATUS[0]}" -eq 1 ] ; then
  # do something
fi
# you may want to do `shopt -u lastpipe` here
Socowi
  • 25,550
  • 3
  • 32
  • 54
  • Thank you for your kindly help. I apologize for my late answer. I was not far from your third solution which is working very well. Thank you! – moocan May 18 '20 at 17:44
  • @moocan I'm glad I could help. Thank you for accepting the answer – better late then never :) – Socowi May 18 '20 at 19:21