Confusion about -c option in bash

63 views Asked by At

From the bash man-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,  the
            first  argument  is assigned to $0 and any remaining arguments are assigned to the
            positional parameters.

So I created a "script" file named foo.sh, containing the single line

echo par 0 is $0, par 1 is $1

, set it to executable, and invoked it as

bash -c ./foo.sh x y

I expected to see par 0 is x, par 1 is y, but it was printed par 0 is ./foo.sh, par 1 is.

In what respect did I misunderstand the man-page?

UPDATE Perhaps to clarify it (since my question seems to have given rise to some confusion): My goal is to execute foo.sh, but making it believe that its real name is not foo.sh, but x.

3

There are 3 answers

1
Philippe On BEST ANSWER

You would see the behaviour you wanted with this :

bash -c "$(cat foo.sh)" x y
3
Zig Razor On

The problem is not on -c option. The problem is on the script foo.sh, in a script sh if you take the parameter with $0 you will have ever the script/command name. So the script should do:

echo par 0 is $1, par 1 is $2

and all should work fine.

3
Léa Gris On

The inline script (the ./foo.sh argument just after the -c option) is not passing any argument to ./foo.sh:

bash -c ./foo.sh x y

This is the inline script:

./foo.sh

This first level script indeed receives x as argument $0 and y as argument $1. But it does not pass any argument when invoking foo.sh. It explains why foo.sh only see itself as the $0 argument, and nothing as argument $1.

Now try with this

bash -c './foo.sh "$@"' x y

And its output is:

par 0 is ./foo.sh, par 1 is y

This is because "$@" does not expand argument $0 which is the script itself.