I have a script that parses file names into an array using the following method taken from a Q&A on SO:unset ARGSARGID=1while IFS= read -r -d $'\0' FILE; do    ARGS[ARGID++]=$FILEdone < <(find $@ -type f -name '*.txt' -print0)This works great and handles all types of filename variations perfectly. Sometimes, however, I will pass a non-existing file to the script, e.g:$ findscript.sh existingfolder nonexistingfolderfind: `nonexistingfile': No such file or directory...Under normal circumstances I would have the script capture the exit code with something like RET=$? and use it to decide how to proceed. This does not seem to work with the process substitution above.What's the correct procedure in cases like this? How can I capture the return code? Are there other more suitable ways to determine if something went wrong in the substituted process?
How do I capture the exit code / handle errors correctly when using process substitution?
bash;exit;error handling;process substitution
You can pretty easily get the return from any subshelled process by echoing its return out over its stdout. The same is true of process substitution:while IFS= read -r -d $'\0' FILE ||     ! return=$FILEdo    ARGS[ARGID++]=$FILEdone < <(find . -type f -print0; printf $?)If I run that then the very last line - (or \0 delimited section as the case may be) is going to be find's return status. read is going to return 1 when it gets an EOF - so the only time $return is set to $FILE is for the very last bit of information read in. I use printf to keep from adding an extra \newline - this is important because even a read performed regularly - one in which you do not delimit on \0 NULs - is going to return other than 0 in cases when the data it has just read in does not end in a \newline. So if your last line does not end with a \newline, the last value in your read in variable is going to be your return.Running command above and then:echo $returnOUTPUT0And if I alter the process substitution part......done < <(! find . -type f -print0; printf $?)echo $returnOUTPUT1A more simple demonstration:printf \\n%s list of lines printed to pipe |while read v || ! echo $vdo :; doneOUTPUTpipeAnd in fact, so long as the return you want is the last thing you write to stdout from within the process substitution - or any subshelled process from which you read in this way - then $FILE is always going to be the return status you want when it is through. And so the || ! return=... part is not strictly necessary - it is used to demonstrate the concept only.