6

While using fish as my shell, i'm trying to set permissions on a bunch of c source files in current dir with

find . -type f -name "*.c" -exec chmod 644 {} +;

I get an error

find: missing argument to `-exec'

or

find . -type f -name "*.c" -exec chmod 644 {} \;

I get an error

chmod: cannot access '': No such file or directory

What's wrong?

  • 1
    try quoting the {} with "{}" or '{}' i.e. find . -type f -name "*.c" -exec chmod 644 '{}' + – the_velour_fog Aug 4 '16 at 9:16
  • why the ; after + ? – Anthon Aug 4 '16 at 9:20
  • @Anthon, if you only just arrived at this question, originally the OP posted the question without the ;, ie. .... chmod 644 {} + . Then Thomas Dickey posted his answer, then the OP edited to add the ; as you see it now. I know that still doesn't explain properly why the OP did it though... – the_velour_fog Aug 4 '16 at 9:22
  • @the_velour_fog I reviewed the question from the first post queue, you don't see the answers there. The +; looks someone mixed up things from find's man page. – Anthon Aug 4 '16 at 9:25
  • The semicolon at the end of the first command is just unnecessary but doesn't matter, both bash and fish eat it before passing the arguments to find – ilkkachu Aug 4 '16 at 9:31
17

fish happens to be one of the few shells where that {} needs to be quoted.

So, with that shell, you need:

find . -type f -name '*.c' -exec chmod 644 '{}' +

When not quoted, {} expands to an empty argument, so the command becomes the same as:

find . -type f -name '*.c' -exec chmod 644 '' +

And find complains about the missing {} (or ; as + is only recognised as the -exec terminator when following {}).

With most other shells, you don't need the quotes around {}.

  • @Rahul Agreed. Can I change it to this answer? – Darc Nawg Aug 4 '16 at 9:38
  • I found this same trouble after much time trying to deal with git stashes O_o – Pysis Aug 4 '16 at 17:25
3

{ and } have special meanings in fish. They need to be escaped in order to work with find, for example:

find . -type f -name "*.c" -exec chmod 644 \{\} \;

Or you would have to quote {} like,

find . -type f -name "*.c" -exec chmod 644 '{}' \;
  • 1
    I tried escaping for the "+" and it didn't work (perhaps version-dependent). The single quotes work. – Thomas Dickey Aug 4 '16 at 9:20
  • @ThomasDickey find . -type f -name "*.c" -exec chmod 644 \{\} +; seems to work as well in fish. – Darc Nawg Aug 4 '16 at 9:26
  • 1
    It only works if you cut/paste. If you attempt to edit the line, it gets confused and breaks badly. – Thomas Dickey Aug 4 '16 at 19:25
  • @ThomasDickey I am completely agree with you. I haven't tried the command before posting it. – Rahul Aug 5 '16 at 9:51
3

Your examples miss the expected trailing semicolon:

find . -type f -name "*.c" -exec chmod 644 {} \;

After revising the question, it is "fish" shell. This is a known issue which can be worked around using quoting as @rahul noticed. However, the escaping suggested does not work for my configuration: single quoting does:

find . -type f -name "*.c" -exec chmod 644 '{}' \;
find . -type f -name "*.c" -exec chmod 644 '{}' +

What does happen (if one types the characters rather than cut/paste) is that on trying to edit the command-line to escape the curly braces, fish gets confused and cannot proceed. Here's a screenshot just after inserting the backslashes (no point in trying to cut/paste that):

editing the command-line

and then pressing return:

just press return

So no, fish doesn't really work with escaped curly braces. It only pretends to do that. Continuing to press enter gives a conclusive demo:

q.e.d.

Further reading:

  • but the what is wrong with the first expression ? – Rahul Aug 4 '16 at 9:12
  • 1
    I don't get an error with that. OP may be confused with the latter. – Thomas Dickey Aug 4 '16 at 9:13
  • With the above example I get chmod: cannot access '': No such file or directory – Darc Nawg Aug 4 '16 at 9:14
  • I am using fish shell. – Darc Nawg Aug 4 '16 at 9:15
  • Looks like fish is pre-interpreting the find command (and only knows about the second case). I'll take a quick look for source to clarify this. – Thomas Dickey Aug 4 '16 at 9:18

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.