This post and comments section means I no longer wonder why 99% of shell scripts I come across look inept. I'm sorry guys but seriously please actually learn bash (and ideally not from this blog post). There's so many things wrong in the post and the comments that it's difficult to enumerate.
To start with, if you ever feel the need to write a O(n) for loop for finding which commit broke your build, you DID need git-bisect.
Definitely DONT'T wait for PIDs like that and if you do want to write code like that, maybe actually use the arrays bash provides?
If your complaint is that for a in b c d; do ...; done is unclear, then maybe also use lists there, because what's definitely LESS clear is putting things in a variable and relying on splitting.
And most importantly, DO quote things (except when it's unnecessary).
Please don't call names or post supercilious putdowns. It's not the culture we want here.
If you know more than others, that's wonderful and it's great to share some of what you know so the rest of us can learn. But please do it without putdowns, and please do it in a way people can actually learn from. "Definitely DONT'T wait for PIDs like that" doesn't actually explain anything.
> Definitely DONT'T wait for PIDs like that and if you do want to write code like that, maybe actually use the arrays bash provides?
What pattern would you recommend for waiting for PIDs / parallelizing commands & preserving exit codes? Fair point about arrays being a better fit rather than a string there.
`wait` can take no parameters this means that if you just ran a bunch of things in the background in your script and want to wait for all of them to finish, you don't need to track the PIDs or a loop, you can just `wait`.
`wait` is a bash builtin (in this case) and as such it has no parameter limit (although I am told that actually there are some weird limits but it's very unlikely you will be able to spawn enough processes at once from a bash script to hit the limits). Given an array `pids` you can just do: `wait "${pids[@]}"`
The only problem with the two above approaches is that in the former case, wait loses the return status and in the second case wait loses all but the status of the last ID you pass it, so the third option is:
pids=()
do_thing_1 &
pids+=("$!")
do_thing_2 &
pids+=("$!")
for pid in "${pids[@]}"; do
wait "$pid" || status=$?
done
exit "${status-0}"
Now you only have the issue left that this will report the LAST failing status.
Thanks for the explanations! Tracking if anything fails is normally important for what I'm doing, so I quite like that array-based solution. I really like that `"$pid" || status=$?`; it's much nicer than `if ! wait $pid; then status=1; fi` I have in there.
To start with, if you ever feel the need to write a O(n) for loop for finding which commit broke your build, you DID need git-bisect.
Definitely DONT'T wait for PIDs like that and if you do want to write code like that, maybe actually use the arrays bash provides?
If your complaint is that for a in b c d; do ...; done is unclear, then maybe also use lists there, because what's definitely LESS clear is putting things in a variable and relying on splitting.
And most importantly, DO quote things (except when it's unnecessary).