DEV Community

techen spectre
techen spectre

Posted on Originally published at langstop.com

`find -delete` before `-name` deletes everything

 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
Enter fullscreen mode Exit fullscreen mode

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:

  1. Delete this file.
  2. 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
Enter fullscreen mode Exit fullscreen mode

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?

Top comments (0)