Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have a script that parses file names into an array using the following method taken from a Q&A on SO:

unset ARGS
ARGID="1"
while IFS= read -r -d $'\0' FILE; do
    ARGS[ARGID++]="$FILE"
done < <(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 nonexistingfolder
find: `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?

share|improve this question

1 Answer 1

up vote 5 down vote accepted

Processes in process substitution are asynchronous: the shell launches them and then doesn't give any way to detect when they die. So you won't be able to obtain the exit status.

You can write the exit status to a file, but this is clumsy in general because you can't know when the file is written. Here, the file is written soon after the end of the loop, so it's reasonable to wait for it.

… < <(find …; echo $? >find.status.tmp; mv find.status.tmp find.status)
while ! [ -e find.status ]; do sleep 1; done
find_status=$(cat find.status; rm find.status)

Another approach is to use a named pipe and a background process (which you can wait for).

mkfifo find_pipe
find … >find_pipe &
find_pid=$!
… <find_pipe
wait $find_pid
find_status=$?

If neither approach is suitable, I think you'll need to head for a more capable language, such as Perl, Python or Ruby.

share|improve this answer
    
Thank you for this answer. The methods you described work fine but I must admit that they are slightly more complicated than I had anticipated. In my case I settled for a loop before the one shown in the question that iterates through all arguments and prints an error if one of them isn't a file or folder. While this doesn't handle other types of errors that could occur in the substituted process it's good enough for this specific case. If I ever need a more sophisticated error handling method in situations like this I'll certainly come back to your answer. –  Glutanimate May 10 at 15:20

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.