This looks like it deletes one temp file. It deletes the whole directory, including the directory itself:
mkdir demo touch demo/keep.txt demo/old.tmp find demo -delete -name '*.tmp' ls demo # ls: cannot access 'demo': No such file or directory That's GNU findutils 4.10.0. There's no prompt and no warning. keep.txt is gone.
Why it happens
find doesn't treat its arguments as a list of options. It evaluates them as an expression, from left to right, for each file. So the command above means:
- Delete this file.
- Then check whether its name matches
*.tmp.
By the time -name runs, the damage is done. -delete isn't a setting that applies to whatever matched. It's an action that runs at the point where you wrote it.
The man page says this outright:
Warning: Don't forget that find evaluates the command line as an expression, so putting -delete first will make find try to delete everything below the starting points you specified.
The safe version
Run it with -print first, then swap in -delete as the last thing on the line:
mkdir demo touch demo/keep.txt demo/old.tmp find demo -name '*.tmp' -print # demo/old.tmp find demo -name '*.tmp' -delete ls demo # keep.txt The same order rule applies to -exec. Filters go first, and the action goes last.
What's the worst thing a command with the arguments in the wrong order has done to you?
