Timeline for answer to How to wait in bash for several subprocesses to finish, and return exit code !=0 when any subprocess ends with code !=0? by Luca Tettamanti
Current License: CC BY-SA 4.0
Post Revisions
32 events
| when toggle format | what | by | license | comment | |
|---|---|---|---|---|---|
| Jun 21, 2024 at 16:46 | history | edited | Akaisteph7 | CC BY-SA 4.0 | show how to create array as well |
| Apr 21, 2024 at 6:14 | comment | added | user129393192 | Why does this not work if I quote ${pid} like "${pid}"? | |
| Aug 31, 2023 at 20:02 | comment | added | Charles Wood | The man page for wait says that it waits for all currently active child processes, so it seems like just wait by itself would do the same thing? (If a process finishes before you get to wait, then waiting for that process's PID would be a no-op anyway, right?) | |
| Jan 17, 2023 at 9:02 | comment | added | djsmiley2kStaysInside | Why is an associtive array used, why not just pids+=( $! ) | |
| May 15, 2022 at 16:44 | comment | added | Richard Tyler Miles | Note: Use the command set -eEBm or simply just set -e, man, will cause your script to fail with debugging info if wait returns a non-zero exit. It's perfect for debugging, but read the manual carefully for how you'd prefer to have exits behave. | |
| Feb 17, 2022 at 8:44 | comment | added | Gabriel Staples | This answer also doesn't show how to read back the error codes from the subprocesses being waited on. I added that feature to my answer as well. That's a key part of the question. | |
| Jan 11, 2022 at 17:24 | comment | added | Gabriel Staples | I figured it out. For a full, runnable example based on this answer, including to see how n_procs and procs might actually be implemented and iterated over, see my new answer here. | |
| Jan 11, 2022 at 16:44 | comment | added | Gabriel Staples | What type of variable is n_procs, and what does it contain? What type of variable is procs, and what does it contain? Can someone please update this answer to make it runnable by adding definitions for those variables? I don't understand how. | |
| S Oct 18, 2021 at 12:33 | history | suggested | nextloop | CC BY-SA 4.0 | update markdown format +2 |
| Oct 17, 2021 at 14:04 | review | Suggested edits | |||
| S Oct 18, 2021 at 12:33 | |||||
| Apr 7, 2020 at 11:06 | comment | added | Sergio Santiago | Important to set set -e in case you want to fail your script if a process fail and return the exit code from the failing process. | |
| Dec 12, 2019 at 17:53 | comment | added | Ian Tait | As @Alnitak said, what about the case where I want to report a failure immediately when any one of the processes dies with a non-zero exit code? If I have 3 processes that are all long running, and the 3rd process fails immediately, with the method proposed in the answer I would not find out about the failure of the 3rd process until I have waited for the other 2 processes to finish, which could be hours later. | |
| Sep 5, 2019 at 22:54 | comment | added | Charles Duffy | Better to use for pid in "${pids[@]}" rather than for pid in ${pids[*]}. Sure, someone who sets IFS to a value that contains numerics is asking for trouble, but still, better to write code that works right even when people are asking for trouble. :) | |
| Feb 19, 2019 at 17:40 | review | Suggested edits | |||
| Feb 19, 2019 at 19:25 | |||||
| Jun 25, 2018 at 10:36 | history | edited | Cristian Ciupitu | CC BY-SA 4.0 | added link to documentation |
| May 17, 2018 at 16:29 | comment | added | nhooyr | That is still buggy. If the PID is reused, the exit code of wait will be non zero because you can only wait on childs of the current process which will make it look like one of the commands failed even if they didn't. | |
| S Apr 23, 2018 at 10:41 | history | suggested | knarf | CC BY-SA 3.0 | adding @synack comment to the answer |
| Apr 23, 2018 at 9:52 | review | Suggested edits | |||
| S Apr 23, 2018 at 10:41 | |||||
| Apr 23, 2018 at 9:50 | comment | added | knarf | moving @synack comment to the answer | |
| May 27, 2014 at 15:15 | comment | added | synack | @Nils_M: You're right, I'm sorry. So it would be something like: for i in $n_procs; do ./procs[${i}] & ; pids[${i}]=$!; done; for pid in ${pids[*]}; do wait $pid; done;, right? | |
| May 27, 2014 at 14:38 | comment | added | Nils_M | @Kits89 This does not work for me. According to wait man pages, wait with multiple PID's only returns the return value of the last process waited for. So you do need an extra loop and wait for each PID separately, as suggested in the answer. | |
| Jan 19, 2014 at 23:53 | comment | added | synack | FYI, I found out an elegant way to do what the answer says: for i in $n_procs; do ./procs[${i}] & ; pids[${i}]=$!; done; wait ${pids[*]}; | |
| Aug 12, 2010 at 11:13 | comment | added | conny | You can also use %n to refer to the n:th backgrounded job, and %% to refer to the most recent one. | |
| Jan 7, 2009 at 17:17 | vote | accept | tkokoszka | ||
| Dec 10, 2008 at 15:27 | comment | added | tkokoszka | PID may be reused indeed, but you cannot wait for a process that is not a child of the current process (wait fails in that case). | |
| Dec 10, 2008 at 15:13 | comment | added | Luca Tettamanti | About the race: with wait(2) the PID won't be reused until it has been waited upon (it's a zombie); with bash scripts the doc is not very clear, but it seems (I tried...) that the shell waits for the PID and stores the return value for later use - so the PID may be reused :| | |
| Dec 10, 2008 at 15:02 | comment | added | Luca Tettamanti | Hum, I interpreted the code in the question as a barrier. As you said, apparently there's no way to wait for "any" child... | |
| Dec 10, 2008 at 14:52 | comment | added | Alnitak | one thing, though - doesn't this risk a race condition if you're specifying PIDs, that PID dies, and then another process is spawned with the same PID? | |
| Dec 10, 2008 at 14:51 | comment | added | Alnitak | Ah, I see - different interpretation :) I read the question as meaning "return exit code 1 immediately when any of subprocesses exit". | |
| Dec 10, 2008 at 14:41 | comment | added | Luca Tettamanti | Weel, since you are going to wait for all the processes it doesn't matter if e.g. you are waiting on the first one while the second has already finished (the 2nd will be picked at the next iteration anyway). It's the same approach that you'd use in C with wait(2). | |
| Dec 10, 2008 at 14:17 | comment | added | Alnitak | how can you loop on 'wait', when that makes the script block until that specific process has died? | |
| Dec 10, 2008 at 14:07 | history | answered | Luca Tettamanti | CC BY-SA 2.5 |