1
$ ls -l
total 0
-rw-rw-r-- 1 t t 0 Jun  8 16:37 'file; echo hello'
$ find . -exec echo {} \;
.
./file; echo hello

I was wondering why the following command doesn't ls -l each file in the current directory? Why does it report some file named 1? Thanks.

$ find . -exec sh -c "ls -l $@" sh {} \;
ls: cannot access '1': No such file or directory
ls: cannot access '1': No such file or directory

$ find . -exec sh -c "echo ls -l $@" sh {} \;
ls -l 1
ls -l 1
2

In both cases, $@ is expanded by your current shell, before it runs find, because it’s in a double-quoted string. I’m guessing you have $1 set to 1 (run printf "%s\n" "$@" to see the current values of the positional parameters).

To run your experiments as I think you intend, you should use single quotes around the command and double quotes around $@ (to avoid extra splitting); for example:

find . -exec sh -c 'ls -l "$@"' sh {} \;
| improve this answer | |
  • Thanks. find . -exec sh -c 'ls -l "$@"' sh {} \; seems better, in that it can prevent word splitting which find . -exec sh -c "ls -l \$@" sh {} \; and find . -exec sh -c "ls -l '$@'" sh {} \; can't? – Tim Jun 8 '18 at 21:12
  • You’re right, I’ve amended my answer. – Stephen Kitt Jun 8 '18 at 21:15

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.