This question that went unanswered in the replies bears repeating:
Any idea why the command actually ran? If $foo and $bar were both undefined, rm -rf / should have errored out with the --no-preserve-root message.
The only way I can think of that this would have actually worked on a CentOS7 machine is if $bar evaluated to </i>, so what was run was rm -rf /.
As the above notes, I'm pretty sure recent versions of Redhat/CentOS actually protect against this sort of thing.
On the offchance you're not running a recent server, however, this could also be avoided by using `set -u` in the bash script, as it would cause undefined variables to error out.
I believe those variables were not handled by the shell but rather in an Ansible "playbook" - see http://docs.ansible.com/ansible/playbooks_variables.html
i.e. the variables where happening in a Jinja template and because undefined, rm -rf {foo}/{bar} was transformed by the template engine into rm -rf /
the playbook will fail if there are undefined variables, I find the story suspect.
Is there a version of ansible that doesn't have this behavior?
Or perhaps the variables were defined like
Or were set via some function that could return a null
By default, ansible errors out for undefined variables.
http://docs.ansible.com/ansible/playbooks_filters.html#defau...
Another lesson to be learned is that it's exceptionally bad practice to use Ansible to push out shell scripts that can be handled by native Ansible modules: http://docs.ansible.com/ansible/file_module.html
I feel like there is nobody replying who tested this theory because their computers don't work anymore.
It is a tragic story but rm -rf has been almost a joke in the industry for a very long while now. Even really old systems should have received an update of some form, to such an extent that the story in the op would be ridiculous rather than a discussion topic.
When I use the command I need to block out all distractions. I check my surroundings for things which might fall on my keyboard. I borderline make sure my phone is turned off before I carefully begin typing that.
I feel uncomfortable typing it into hacker news anywhere but the middle of a sentence. I can't imagine the bullets I would be sweating while deploying a bash script to all servers that included it. There is a problem that needs to be addressed.
Before you apply `set -u` to all of your scripts, be aware that an empty array counts as undefined. So if you have arrays for which being empty is valid, be sure to `set +u` right before accessing them (and then `set -u` again after).
Or write ${arr+"${arr[@]}"}, which is, you know, only slightly more awkward than bash arrays already were to begin with.
Really you just want to use a real programming language instead.
This is why you should never run rm -r with the -f switch the first time. -f says yes to all warnings, including the ones that confirm that you really mean to erase root. I see this constantly in SO and other answers, and it's a really really bad practice to do it without thinking.
This was inside a shellscript though. It could well be that the script e.g. needed to remove write-protected files, so the flag really had to be there.
Even in a script, would you really want it not to prompt you or fail under those conditions? Files are usually write-protected for a reason.
I wish git was better about having a deletable directory. Most of the time that I need to use the -f switch, it's because I get this trying to remove a .git directory: