2

In the following command I would like to know why $0 was evaluated to the file found by find and not the echo command.

$ find . -type f -perm -u=x -exec bash -c '
  /bin/echo $0 is the name of the file' {} \;

I know that if I had used double quotes, $0 would equal -bash and using single quotes delays the expansion, but why doesn't it expand to /bin/echo since that is the called command (which normally would be $0)?

cuonglm
  • 150,973
  • 38
  • 327
  • 406
Gregg Leventhal
  • 7,480
  • 19
  • 65
  • 100
  • 1
    I'd understand why you'd want `$0` to expand to `bash`, but not `echo`. Do you expect `rm "$0"` to attempt to remove `rm`? See also http://unix.stackexchange.com/q/140779 and https://unix.stackexchange.com/q/152391 – Stéphane Chazelas May 12 '15 at 14:42
  • I don't want that behavior, I find this more useful, but I expected the behavior typically found when using $0 in a shell script where $0 represents the script itself. I was curious how it was working, not wishing it worked differently. – Gregg Leventhal May 12 '15 at 14:49

1 Answers1

3

From the bash manual page:

 -c    If the -c option is present, then commands are read from the first 
       non-option argument command_string.  If there are arguments after 
       the command_string,  they are assigned to the positional 
       parameters, starting with $0.

The filename is given to bash as an argument using the braces {}, so it is assigned to $0. The expansion of $0 is then done by bash prior to calling /bin/echo.

Dubu
  • 3,654
  • 18
  • 27
  • 3
    As discussed [here](http://unix.stackexchange.com/a/93331/80216) and [here](http://unix.stackexchange.com/q/30677/80216), some people like to insert a placeholder word between `sh -c "(command)"` and the argument list, if any, to straighten out this confusion.  For example, your command would become `find . -type f … -exec bash -c '/bin/echo $1 is the name of the file' placeholder {} \;`.  In the shell command, `$0` would equal `placeholder`.  (It is common to use things like `sh` or `_` as the placeholder.) – G-Man Says 'Reinstate Monica' May 12 '15 at 21:25