Open NateTheGreat68 opened 2 years ago
A great way to start is using #!/bin/bash -e
as the shebang line so it would exit on any error. This helps you getting silent errors sorted out before migrating to posix sh.
But I'm not sure why you would want to do it. Any distribution should support bash by default even when that's not the default login shell. I don't get why people try to bash bash for being bash - or whatever that is. It's not really an exotic dependency. And in a systemd environment, it even doesn't mean anything. I know and understand why people want to get rid of bashism in init scripts: Because bash may not be available early, and init may actually be powered by dash or busybox. Also, bash is quite slow to initialize compared to simpler implementations: Not running your init scripts with bash actually improves boot performance by quite a lot. But I really don't see the point in eliminating it from install scripts or configuration scripts.
You decide but just explicitly using the correct bash shebang should be enough. "bashism" is only a problem if your shebang is #!/bin/sh
but you're using bash inside the script - that silently pretends your default shell being bash - which is most probably not true especially in early boot environments.
Also, putting #!/bin/sh
as the shebang line is probably the worst "best practice" someone could make: There's no requirement I know of that forces /bin/sh
to be a 100% posix compatible shell. I'd rather explicitly mention the shell you tested with but still avoid bashism.
It might be worth the effort to deploy shellcheck (especially in your editor) instead and create an Azure pipeline or some other Github bot to run your PRs against a CI definition which also runs shellcheck, and runs a make install
. I don't know how to setup the pipeline but you can take the CI definition of xpadneo as an example.
Alright, you've convinced me: I'm going to abandon the migration away from bash. After I started looking into it, eliminating bashisms was going to be a big pain anyway. Point taken on setting -e, I'll incorporate that advice.
Yeah, the link you posted misses to explain their very first point 1: replace the shebang... That's not without side-effects. It's actually a bad recommendation for an article trying to explain some best practices.
Using /bin/sh
as the default shell (which is a fall-back shell anyways) is only useful if your scripts are targeted for very limited or minimalistic runtime environments, and you even don't know the exact implementation in advance. Then the minimum feature set is posix - and bash CAN do that. Just avoid bashism, but use bash in the shebang because that's what you tested with.
In the context of the article, it misses to point out that you really should test your script with all the implementations you're going to encounter in the wild (I can only guess that from the examples using docker). You really want to avoid that for this project. And it misses to describe the purpose and target of the idea. So in the end, it's a bad article. Not all parts, really, almost anything of it is true and useful. But it fails to point out its core idea which led you on the path of thinking that being a good idea and best practice. Spoiler: it isn't. ;-)
In a similar way, following the direction of Debian is almost always not a good idea. Actually, a lot of stuff they are doing is for the sole purpose of staying as compatible as they can with the old (and stable) runtime environment, and being able to offer their various enormous amounts of free choice of alternative implementations. This leads to very questionable decisions sometimes (and this includes trying to use /bin/sh
everywhere), e.g. where they add strange backward compatible glibc symbols to OpenSSL to be able to run modern software with old implementations and being able to swap the openssl implementations at the same time. In the aftermath, all other distributions had to deal with strange patches and workarounds in their packages to run binary software which was linked to Debian libs. So: No, Debian is almost never a good example for best practices. That's another reference I don't like about the article. OTOH, Debian is a very good distribution if you need to support your Linux-based products for years without taking the hassle to update your dependencies to almost bleeding-edge every year or so (which pulls a plethora of testing efforts). You really don't want that as part of the maintenance life-cycle of your major product version with long-term support - especially if this would involve recertification of certain components (where "product" is not a project like this but a set of various software components which need to work together to make a sum bigger than their parts). Debian is a great choice here and they are doing a great job - but that doesn't make it an outstanding example for best decisions.
In the end it sums up to: Always know your set of tools and WHY you use them, it depends on the context. And the article isn't pointing that out.
BTW: This is why I'm very doubtful if an Arch Linux base is the right choice for Steam Deck... It's a fast moving distribution, and yes, in the current phase of Proton development and GPU-compatibility, it is probably the best choice you can make. But in the long run, it may create more headache than needed. But I'm having faith in Valve's decisions - they just need to make sure that users don't fiddle with the installation base on their own - otherwise things will break fast.
Convert the script from bash to sh, testing to be sure it's compliant. See here for tips: https://dev.to/bowmanjd/writing-bash-scripts-that-are-not-only-bash-checking-for-bashisms-and-testing-with-dash-1bli
Review commands for any non-standard flags.