3 ms·
This is, in my opinion, REALLY bad practice. Never use potentially dangerous commands (rm -f) to avoid the prospect of an error! Instead, one should practice
by julian_sark 5y ago
This is, in my opinion, REALLY bad practice.
Never use potentially dangerous commands (rm -f) to avoid the prospect of an error!
Instead, one should practice good error handling. For some scripts and depending on the audience "set -e" may be sufficient. But usually always better:
rm file.txt || echo "Warning: Deleting file.txt failed, continuing anyway."
Or, for longer shell scripts, I always include a little function that deals with error handling. You can call it in the same way:
rm file.txt || errorHandler("ignore")
As shown above, the function can be built to take various parameters, and can then for instance abort or ignore the error. It can also take care of updating a log file.
Somewhat related, I do logging in shell scripts with a function, too:
rm file.txt && log("info", "file successfully deleted")
That way, I only need to write the code that writes log lines with nice formating and timestamps and such once.
Somewhat related, one can trap various signals in a shell script, and call a bash function when they happen. Thus, one can trap SIGEXIT and call a cleanup function that triggers on Ctrl-C, and I'm almost certain (sorry, can't test right now) one can also trap SIGERR and catch errors in a shell script nicely (though I'm not sure if that also goes for external commands inside said shell script).
- bashonly 5y agoagreed w/ your general points, but passing arguments to bash functions does not work like this: errorHandler("ignore") it should just be: errorHandler "ignore"
- julian_sark 5y agoYou are certainly correct, thanks. I hastily typed this out, my bad.
- xorcist 5y agoThat's not it. Between [ -f file.txt ] && rm file.txt and rm -f file.txt the latter form is preferrable because it is easier and not as prone to concurrency problems. Although it should be said that concurrency and idempotency is seldom acquired just by using force-flags in isolated spots, the whole operation needs to take it into account. There are probably more steps involved than just removing one file. The linked article leaves out the bigger picture so it's probably not very helpful. Often it is sufficient to construct the new state under a temporary name and then move it in place in one operation.
- reacweb 5y agoyou will probably love perl. Perl encourages this programming style : unlink ('file.txt') or die "Can't remove file.txt: $!";
- julian_sark 5y agoSomewhat paradoxically, my opinion on perl can't be (cleanly) reproduced here ;)
- deleted 5y ago[deleted]