The flaw is that you're using an automated forced removal of a directory—and of course to remove its contents you'd need an automated forced recursive removal of a directory. You're opening yourself up to security holes in your script.
For instance, check out the --one-file-system
flag for rm
. You probably wouldn't want to remove all the files in any filesystems mounted within mydir
...so you would have to include that flag (which has no abbreviation by the way).
Also, what about bind mounts? (See man mount
and search for bind
.) Those would be files technically on the same filesystem...how would rm -rf
handle those? Would it delete them all? That's probably not what you wanted, but to be sure you would have to research it out and test the behavior of rm
in relation to bind mounts. There are probably many many other edge cases that I didn't think of.
All this trouble comes about because you don't really want to "remove a directory and its contents"; what you actually want is to have an empty directory to work in.
There's a general principle here—when you specify something other than what you specifically want, because you think that's a route to get what you want, you are usually introducing needless complexity. The thing to do is to find how to specify what you want and then specify that explicitly.*
The better solution, as Jeff Schaller already pointed out in the comments, is to use mktemp
, which is actually designed for this purpose. Specifically, from man mktemp
:
Create a temporary file or directory, safely, and print its name.
The simplest use of mktemp
to create a directory would look like this:
mydir="$(mktemp -d)"
Then you could copy a file into it like so:
cp somefile "$mydir/"
At the end of your script, when you're all done with the directory, you can safely remove it (and whatever you've put in it) by using:
rm -rf "$mydir"
*Another example of this principle is the use of sed
commands to handle field-based or column-based files. You may be able to do it...but you can specify exactly what you want by using awk
, and with much less complexity.
if [ -d mydir ] && [ ! $(ls -A mydir 2>/dev/null) ]; then
...rm -rf mydir; mkdir mydir
. @JeffSchaller: I forgot option-r
.