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 :)
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.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)
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.
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.
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/2fb052d230654cc0c25e9e41a965...
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.