bashshellgnu-findutils

How does `find <path> -name "*.sh" -exec chmod +x \{\} \;` work?


I found an old one-line shell script:

 find ./../ -name "*.sh" -exec chmod +x \{\} \;

I understand it grants execution rights on all the shell scripts in the directories below the parent directory. However, I haven't seen the syntax \{\} \; before.

I'm guessing the backslashes escape the characters to yield {} ;, but what does that mean and why does it work?


Solution

  • The \{\} means substitute the full pathname of the object that has been matched.

    The \; marks the end of the arguments of the command to be executed.

    So

    -exec chmod +x \{\} \;
    

    means run chmod +x <pathname> for every <pathname> that matches the preceding find filtering. In this case, that will be all files with the suffix .sh.

    You can read more about -exec in the man entry for the find command.

    The backslashes are required because the characters {, } and ; all have syntactic significance to the shell. So you have to tell it that they are literal characters to be passed through to the find command.

    The pattern "*.sh" is quoted for the same reason: to stop the shell itself from doing pathname expansion.