0

I have this line in a script that is supposed to be pruning old backups, except it throws an error that the target is a directory:

find $BACKUP_DIR* -mtime $RETENTION -exec rm {} \;  >> $MSG 2>&1

so I am trying to add the -rf to the rm command, but it's still not working [no errors!]

find $BACKUP_DIR* -mtime $RETENTION -exec "rm -rf" {} \;  >> $MSG 2>&1

What is the correct syntax for that command? I've tried double quotes, single quotes and backticks... do I have to escape the -rf somehow?

7
  • 5
    change it to : -exec rm -rf {} \; Commented Nov 7, 2014 at 22:03
  • @michael501 You can post that as an answer Commented Nov 7, 2014 at 22:08
  • nope that was the first thing I tried. It doesn't work I'm assuming because it looks like an argument to the find command. Commented Nov 7, 2014 at 22:12
  • @SeanKimball Why do you say it doesn't work? what error message do you get? Commented Nov 7, 2014 at 22:13
  • 1
    The problem is trying to quote "rm -rf", that causes the shell to pass that as a single token to find -exec which is interpreted as the name of the command, remove the quotes, tokens after -exec are interpreted as utility, followed by arguments, no further expansion or interpretation by the shell. Commented Nov 7, 2014 at 22:27

1 Answer 1

4

I typically prefer the -0 xargs method:

find ... -print0 | xargs -0r rm -rf

This does, however only work with commands which take one or multiple arguments till the end of the line. But it is quite safe as it takes any binary junk in the file name and present it as nicely separated arguments. It also avoids having to remeber this {} syntax. It also reduces the number of child executions. The -r option is needed in the GNU variant to make sure it does not call the command if no match is found. For FreeBSD it is ignored (as it is the default).

In your case, there is also a -delete action for GNU find:

find ... -delete

If you insist on using the escape method, then it would be:

find ... -exec /bin/rm -rf "{}" \;

Or if using GNU find, you can be a bit more efficient with:

find ... -exec /bin/rm -rf "{}" +

And just to be sure, use -ok :)

touch test1 test2 test3
find . -type f -ok rm -rf "{}" +
"rm -rf ./test1 ./test2 ./test3"? y

And to answer your question: no you don't have to escape the commands options. If it does not work, your problem is somewhere else, must likely in the startdir & search pattern. Try without output redirection and using -print or -ok to debug.

Sign up to request clarification or add additional context in comments.

4 Comments

Note that POSIX find supports the + notation, which typically renders the GNU -print0 and -0 extensions to find and xargs unnecessary.
I'm curious: why did you make your answer community wiki?
@JonathanLeffler I typically do that, so people can improve it. Some even refuse to upvote (for whatver reasons) non-wiki answers. And, I do not have only positive experiences with this:)
People can improve a non-wiki answer, either by edit or by suggestion. Your answer is good; I'd quibble about the order of -print0 vs +, but that is quibbling, not a serious issue. You should have a little more confidence.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.