Always do rm -rf "${var:?}/" so that the script aborts if the variable is empty. Or better yet rm -rf "./${var:?}/".
Edited to add quotes. Always quote a path: it might have spaces in it, without quotes that will become multiple paths! Which would also have avoided the particular bug in question.
Is there not also a way to disallow empty variables in the script, I think it is set -u? Then you don’t have to keep thinking “should I add a :? here because if empty it may lead to disaster” all the time. Might be even safer.
TL;DR: e aborts the whole script on a non-zero error. u aborts when using an undefined variable. -o pipefail aborts a piped compound command when one of the piped commands fail.
Any other way lies madness. Or erasing the whole filesystem apparently!
Yes! But -u is for undefined variables. It won’t stop a defined variable with an empty value. E.g foo="".
Also ? and :? have the advantage of telling you right then and there where the variable use is that it must be defined or not empty… having to trek back to (likely) the top of the script to check is easily forgotten.
Reminds me of a script a colleague has where it would sometimes accidentally wipe the entire production folder on a server. I pointed out the risk in his script and explained how to correct it like 2 years ago, give or take. He said he did, but then last week it happened again because apparently he had several scripts like that and only corrected one.
You can lead a horse to water, but you can’t force it to drink.
rm -rf ${var}/
is a disaster waiting to happen.Always do
rm -rf "${var:?}/"
so that the script aborts if the variable is empty. Or better yetrm -rf "./${var:?}/"
.Edited to add quotes. Always quote a path: it might have spaces in it, without quotes that will become multiple paths! Which would also have avoided the particular bug in question.
Is there not also a way to disallow empty variables in the script, I think it is
set -u
? Then you don’t have to keep thinking “should I add a:?
here because if empty it may lead to disaster” all the time. Might be even safer.set -euo pipefail
at the top of every script makes stuff a lot safer. Explanation here.Yep! I always do this too.
TL;DR:
e
aborts the whole script on a non-zero error.u
aborts when using an undefined variable.-o pipefail
aborts a piped compound command when one of the piped commands fail.Any other way lies madness. Or erasing the whole filesystem apparently!
Yes! But
-u
is for undefined variables. It won’t stop a defined variable with an empty value. E.gfoo=""
.Also
?
and:?
have the advantage of telling you right then and there where the variable use is that it must be defined or not empty… having to trek back to (likely) the top of the script to check is easily forgotten.Reminds me of a script a colleague has where it would sometimes accidentally wipe the entire production folder on a server. I pointed out the risk in his script and explained how to correct it like 2 years ago, give or take. He said he did, but then last week it happened again because apparently he had several scripts like that and only corrected one.
You can lead a horse to water, but you can’t force it to drink.
In this case the issue was that a change between kde5 and kde6 let to the variable being defined as
somepath /
(notice the space).And that’s why you also surround it with double quotes.
I usually have a whole block that checks if the var exists and exits if not, but this is way more elegant
Protects you from accidentally changing the variable within the block too!