3 ms·
My main problem with POSIX shell is it is hard to test, as people might use bash, ash, zsh or dash as sh. Bash is at least not a moving target.
by CJefferson 6y ago
My main problem with POSIX shell is it is hard to test, as people might use bash, ash, zsh or dash as sh. Bash is at least not a moving target.
- saagarjha 6y agoYou can run it through shellcheck, no?
- thomasbacklund 6y agoUsing `shellcheck --shell sh` is a good start :) If adhering to POSIX it should run the same in bash, ash and dash. Bash is kind of a moving target in it self, since it comes with many new features. You have to be aware of which version you are targeting. For instance when using arrays, associative arrays, there is a diff between version 3 and 4. Version 5 is even more competent and it's easy start digging to deep into the cookie jar and getting your hand stuck in there :)
- patrec 6y ago> Using `shellcheck --shell sh` is a good start :) > If adhering to POSIX it should run the same in bash, ash and dash. Not so. Shellcheck will tell you about syntactically invalid bashisms, but will not warn you about the zillions of things that are under or unspecified in posix. Pertinent minimal example: $ echo $'#!/bin/sh\ntrap "echo exiting" EXIT\nsleep 1h' > exit.sh $ shellcheck --shell sh exit.sh && echo "ALL GOOD!" $ /bin/dash exit.sh ^C $ /usr/bin/zsh exit.sh ^C $ /bin/bash exit.sh ^Cexiting Good luck finding a person who can use trap in a way that actually works as intended across different posix conform shells without consulting stack overflow first.
- thomasbacklund 6y agoIndeed, it's such a messy job coding for shell.. Comes with a lot trial and error. The above will work as (tested in ash/dash/bash): #!/usr/bin/env sh trap "echo exiting" INT sleep 1h But to your point, yes, how to actually know that without doing trial n' error & stackoverflow. Thanks for the `sleep 1h`, didn't know that you could do hour as unit :) (edited: turned out INT is enough to trap)
- patrec 6y agoNope, INT is (generally) too specific :) Sometimes of course, you just want to run something on SIGINT and not on normal exit, SIGHUP or whatever. But maybe the main use case for trap is implementing try/finally logic and you really want it to fire whenever the shell exits, not matter how (to clean up resources like temporary files). Bash's `trap EXIT` mostly does what you want ("run this when the shell exits"), but writing something that behaves this way across shells (and doesn't fire multiple times etc). is amazingly painful.
- thomasbacklund 6y agoOk, I though it was to catch CTRL-c :) trap EXIT, does work for me in ash/dash/bash, though, when just letting the code flow exit with and without errors. Not sure your use case, but I can for sure concur that traps are very painful to get right, especially when getting into child/grandchild processes land, taking terminal session, etc in regard.
- patrec 6y agoIt would be nice if bash were not a moving target. I have run into several bash incompatibilities in real life. Bash on macOS differs substantially from bash on Linux because it's much older. But bash is also generally somewhat poorly designed, leading to lots of aggravating and puzzling behavior for "corner cases" and this behavior not infrequently changes between versions. So for example set -u for the longest time used to trigger on defined but empty arrays (which is hardly an obscure edge case), but what workarounds are possible differs quite a bit between versions: https://gist.github.com/dimo414/2fb052d230654cc0c25e9e41a9651ebe https://gist.github.com/dimo414/2fb052d230654cc0c25e9e41a965...
- thomasbacklund 6y agoYeah, I agree.. I was listening to the Command Line Heroes podcast the other day, about Bash. First version was stored on tape. So it has some legacy, hehe. Already then the requirement was to be backwards compatible with sh, so yeah, corner cases are around for sure. If writing bash I do aim at version 3, because as you say they got that on MacAttack.