4 ms·
> On the other hand, after a few years playing with bash and posix shell -- I'm fairly certain I'd prefer bash, to posix shell What are some bashisms that you
by schizoidboy 10y ago
> On the other hand, after a few years playing with bash and posix shell -- I'm fairly certain I'd prefer bash, to posix shell
What are some bashisms that you find particularly useful? I wonder if I can just reproduce them in POSIX. So far, I haven't found POSIX too bad, although I don't have much experience making huge and complicated shell scripts. posixcube does support some optional Bashisms already like tab auto-completion and `caller`.
> And shell script is a fickle language -- I'd at least consider using "trap" and/or "set -e"
I didn't like `set -e` because it disallows using "benign" error codes. For example, one of the most commonly used APIs in posixcube is cube_set_file_contents. You pass the file you want to update and the source file. If the file is updated, it returns 0; otherwise, it returns 1. This is commonly used like this:
if cube_set_file_contents "/etc/npt.conf" "templates/ntp.conf"; then
cube_service restart ntpd
fi
I hadn't considered `set -u` and it's part of POSIX. My initial reaction is that it's a nice feature, so thanks for pointing it out, and I might set it.
pipefail is a Bashism, and I'm torn on this. Handling errors in a pipeline is one of the worst parts of POSIX shell scripts. However, using something like pipefail means exiting with an error without a stack. I think it's always useful to have a stack to quickly jump to where the error is in which script. So I still prefer this guideline:
There are non-standard mechanisms like pipefail and PIPESTATUS, but the standardized
approach is to run each command separately and check the status. For example:
cube_app_result1="$(command1 || cube_check_return)" || cube_check_return
cube_app_result2="$(printf '%s' "${cube_app_result1}" | command2 || cube_check_return)" || cube_check_return
> I agree that ansible is far from perfect - but I'm not convinced posixcube is a great alternative right now.
Please see my reply to another comment in this thread, asking how a simple firewall whitelist configuration would be done. I think this would be a useful example to debate around.
> From a brief look at the code, it does look nicely structured and commented, though!
That's very nice to hear, thanks! This was my first time doing anything hardcore in shell scripting.
> I've seen people here on HN recommending some makefiles for deployment (along with simple shell scripts) -- and I've played a bit with using m4 for templates rather than here-documents -- and it looks like that might work fine. Does mean your base-installs/bootstraps/images will need m4 (or "compile" the templates on the workstation you run your automation from).
I really like that posixcube has 0 requirements, but I'm not philosophically opposed to requirements, so I'm certainly curious what a make-based system would look like. Does make have imperative programming like shell scripts?
> But right now, I feel GNU guix is the right approach: have a small, minimal, vm/container host (right now I'm playing with Ubuntu and LXD/LXC - Xen and KVM also works nicely), and have all images be managed by something like guix.
I'm not aware of that, I'll check it out.
Thanks for the comments.
- e12e 10y ago> What are some bashisms that you find particularly useful? I wonder if I can just reproduce them in POSIX. Mostly [[ vs old [/test, advanced parameter expansion/substitution, arrays and maybe local variables. It's been rather long since I attempted to get some dark magic working in posix shell - so I'm not entirely sure. Either way, any proper scripting language will be more ergonomic to work in when you've reached beyond trivial (which posixcube already has). There are simply too many anti-patterns to check for - too easy to miss quoting etc. Python isn't great for (posix) system automation - but it's pretty good. And now I can trust all my systems to have python3. Then I feel it a bit hard to use shell beyond simple "command1, command2, command3"-type simple automation. That said, it can be great fun to weave pipes and inputs in she'll, when you get it working. But as you've pointed out error handling with complex pipes isn't very good - and as always it's better to keep things simple, when possible.
- schizoidboy 10y agoYeah, I'll add some of the most common parameter expansion/substitution, string functions, array functions, etc. as APIs. I had a thought yesterday for handling pipeline failures by using set -e in a sub-shell. I still need to test this, but something like: (set -e; command1 | grep foo | grep bar | sed ...) || cube_check_return