1

This is driving me nuts as I know it is something easy, but I can't seem to find the solution. Arrgh! I just need to add a find command in to my script so it removes older files before running a new backup. I'd rather control this through variables instead of typing out the exact command. The command does work in the script if I type it out in there instead of using variables.

FIND="/usr/bin/find" BUILD="~/" FINDOPTS="-type f -mtime +3 -exec rm -rf {} \;" echo $find $BUILD $FINDOPTS ## remove the 2 week old backup echo "Removing old backups... " $FIND $BUILD $FINDOPTS 

If I just echo the $FIND $BUILD $FINDOPTS command it shows just like the command does if I type it out. Only difference is it will actually run when I type it.

Typing out /usr/bin/find ~/ -type f -mtime +3 -exec rm -rf {} \; works just fine.

The error that I get is:

/usr/bin/find: missing argument to `-exec' 

Can anyone help explain why this is? Thank you!

    2 Answers 2

    4

    Notwithstanding better overall solutions, here's the reason why it failed in this script:

    FINDOPTS="-type f -mtime +3 -exec rm -rf {} \;" ^ 

    The parameter find is waiting for is the character ;. Since ; is (not really by accident) also the shell's end of command delimiter, it has to be escaped in a shell command, hence usually typed \;. If now you put this character in a variable, it won't ever be evaluated by the shell as a delimiter. Thus it musn't be escaped.

    Reproducing the error without variable:

    $ find /etc -exec ls "\;" find: missing argument to `-exec' 

    So just replace the string with:

    FINDOPTS="-type f -mtime +3 -exec rm -rf {} ;" 
    1
    • Thank you. That solved my issue and you explained it nicely so that I understand exactly what is happening here. Really great answer, for me, at least.
      – saleetzo
      CommentedMar 27, 2018 at 21:26
    2

    Rather than find [...] -exec rm, I suggest using the built-in functionality:

    find [...] -delete 

    From the manual:

     -delete Delete found files and/or directories. Always returns true. This executes from the current working directory as find recurses down the tree. It will not attempt to delete a filename with a ``/'' character in its pathname relative to ``.'' for security reasons. Depth-first traversal processing is implied by this option. Following symlinks is incompatible with this option. 

    (as an aside, you do realize that the command in your question will delete any files older than three days since their last modification, yes?)

    1
    • Nice -- I never used -delete whenever using find commands for some reason. Always -exec or some xargs. I'll consider it for the future. Yeah, I just put a quick and dirty version in the example to find out where the issue was. The real command has some more specification in it and its not in the actual ~/ folder. Thanks tho!
      – saleetzo
      CommentedMar 27, 2018 at 20:03

    You must log in to answer this question.

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.