8 ms·
Don't use traps unless you have to. They are subtly complex and require a great deal more code to deal with edge cases. There is almost always a simpler way to
by throwawaaarrgh 3y ago
Don't use traps unless you have to. They are subtly complex and require a great deal more code to deal with edge cases. There is almost always a simpler way to accomplish what you want.
If Bash has taught me anything, it's that many advanced features should seldom be used. Always resist the temptation to be fancy.
- thelastparadise 3y agoHow have exit traps come back to bite you?
- throwawaaarrgh 3y agoThe first is that the trap can come at any time. You can't assume at what point in the script it was running, so you have to test for different cases to find out what you now can/should do. Forget an edge case and now you've got an extra bug. Not using traps, it's clearer what happens at specific points in the execution of the rest of the code, so simpler to reason about how to deal with those cases as/where they happen. The second is different events can trigger an exit trap, and those may have different implications on what's going on. The third is there's parts of standards left out about what happens during/after a trap or when they get called, what data you have available, and different implementations can behave differently. Fourth is that sometimes people will use an exit trap to, say, report on a failure, but they may have lost context of what block they were in when it exited, and now the error reporting doesn't tell you everything you wanted to know. I can't remember more specifics atm because I stopped using them like a decade ago. I'll still use them to clean up temp files, but I also have to add the cleanup logic to the start of the script in case it didn't run.
- xmprt 3y agoAs with most things in programming, it sounds like if you use the wrong tool for the wrong job, then you're prone to writing bugs. Using traps is a great idea when used properly and dismissing it outright isn't doing anyone any favors.
- pcthrowaway 3y agoI agree with you but also the person you're responding to; I think the article sells traps too hard as a handy multi-purpose tool like a swiss army knife, when they're really more like a letter-opener; there are situations where it makes sense to use them, but you'd usually be better off with something else, and not knowing the difference can result in trying to use it as a precision blade, which ends up mangling things.
- pcthrowaway 3y agoThere's a bit more nuance in my opinion. If your cleanup logic is no more complicated than "perform some cleanup whenever the script exits for any reason, without concern for what state the things to clean up are in", I think trapping everything and calling the cleanup function is fine. If you have to do anything more complicated, it's probably a better idea to stick all that logic into a non-bash program. You can do it in Bash if you know what you're doing, but it's going to be ugly, hacky, error-prone, and tedious. Not using traps, it's clearer what happens at specific points in the execution of the rest of the code, so simpler to reason about how to deal with those cases as/where they happen. You can stick all kinds of logic into the cleanup function, but again, it's ugly. The second is different events can trigger an exit trap, and those may have different implications on what's going on. The third is there's parts of standards left out about what happens during/after a trap or when they get called, what data you have available, and different implementations can behave differently. Which is why I think it's preferable not to do this in bash if you have any concern for why the program is exiting Fourth is that sometimes people will use an exit trap to, say, report on a failure, but they may have lost context of what block they were in when it exited, and now the error reporting doesn't tell you everything you wanted to know. If you need any tracing, the only way this makes sense in bash is when running with -evx (errexit, verbose, trace) so you know exactly where you exited. This isn't always a bad idea, though -vx probably is most of the time. If you think you can do any complex logic in the trap function then you have to consider whether that logic might fail at any point, and depending on the signal there's a good chance you're on a clock as well.
- ykonstant 3y ago# usage : utility NEW_DIRECTORY -- user : I think not # trap 'cleanup' INT HUP TERM cleanup() { rm -rf "${mydir}" ;} # stuff mydir="${HOME}/$1" # but $1 is empty if test -z "$1"; then # handle; but while stuff is happening, # user presses Ctrl-C fi
- deleted 3y ago[deleted]
- dangus 3y agoIn my mind, as soon as you approach anything remotely resembling "fancy," you should move on to a different language or framework that isn't a bash or shell script at all. I start questioning whether I should be writing bash as soon as I hit about ten lines. I won't even consider writing functions or loops. If I'm manipulating the system, I'm probably using configuration management, and for most other tasks, I'm using a full-blown programming language with a nice set of standard libraries. E.g., Python and Ansible.
- IshKebab 3y agoIf Bash has taught me anything it's that Bash should seldom be used. Always resist the temptation to be lazy.