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
Tim
  • 101,790

1 Answers1

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 {} \;
Stephen Kitt
  • 434,908
  • 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 08 '18 at 21:12
  • You’re right, I’ve amended my answer. – Stephen Kitt Jun 08 '18 at 21:15