4 ms·
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 ba
by Arch-TK 5y ago
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).
- gcmeplz 5y ago> 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.
- IndexPointer 5y agoTry GNU parallel.
- Arch-TK 5y agoSo in this case there's a couple notable things: `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.
- gcmeplz 5y agoThanks 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.
- dang 5y agoPlease 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. https://news.ycombinator.com/newsguidelines.html https://news.ycombinator.com/newsguidelines.html