On 8/6/20 11:31 AM, Jason A. Donenfeld wrote: > That doesn't always work: > > set -e > while read -r line; do > echo "$line" & > done < <(echo 1; sleep 1; echo 2; sleep 1; exit 77) > sleep 1 > wait $! > echo done
So instead of your contrived case, write it properly. Check the process substitution first, and make sure as a bonus you don't run anything if if it failed: set -e mapfile -t lines < <(echo 1; sleep 1; echo 2; sleep 1; exit 77) wait $! for line in "${lines[@]}"; do echo "$line" & sleep 1 wait $! echo done (And in bash 5.1 you can remember each &'ed command to wait on later.) > Either way, tagging on `wait $!` everywhere, and hoping it works like > I want feels pretty flimsy. Are you sure you're opposed to set -o > procsuberr that would do the right thing for most common use cases? You're asking to add broken behavior which does the wrong thing in bizarre, outrageous ways in many cases. Your rationale is it works in your specific case, and you have a mysterious aversion to wait $! which you haven't explained. (Why is it flimsy? It performs exactly as documented.) I think the problem here is twofold: You have an emotional attachment to errexit and you think it solves problems, so you want to turn everything into it. Ultimately, you really don't have issues with "flimsy" anything, but you want bash to be a different language, one with a formal exception model, strong types, and possibly objects. Such a language would then react to *programmer errors* by failing to compile, or dumping a traceback of the call site, and could be used as a beginner-friendly language that doesn't surprise the newbies. There are a number of good languages like that. Shell isn't one of them. Sometimes you need to understand how edge cases work. Nevertheless, there are ways to code robustly in it. In another language, you'd run forked commands upfront and save their results to some sort of object or variable, and only then process it (after checking the return code or using a function that automatically raises exceptions on failure). You can do that in bash too, as I demonstrated with mapfile and wait $! It isn't really a terrible disadvantage that you need more characters to type out your intent. Most particularly when your intent is "I want this command to run async, but I also want it to exit the script at XXX location if previous aysnc commands have failed". You cannot really get around explicitly tagging the place where you want to raise errors. Using an RNG to randomly raise the error automatically at unpredictable locations isn't a valuable feature to add. -- Eli Schwartz Arch Linux Bug Wrangler and Trusted User
signature.asc
Description: OpenPGP digital signature