bashshell

Pass all args to a command called in a new shell using bash -c


I've simplified my example to the following:

file1.sh:

#!/bin/bash
bash -c "./file2.sh $@"

file2.sh:

#!/bin/bash
echo "first $1"
echo "second $2"

I expect that if I call ./file1.sh a b to get:

first a
second b

but instead I get:

first a
second

In other words, my later arguments after the first one are not getting passed through to the command that I'm executing inside a new bash shell. I've tried many variations of removing and moving around the quotation marks in the file1.sh file, but haven't got this to work.

Why is this happening, and how do I get the behavior I want?

(UPDATE - I realize it seems pointless that I'm calling bash -c in this example, my actual file1.sh is a proxy script for a command that gets called locally to run in a docker container so it's actually docker exec -i mycontainer bash -c '')


Solution

  • Change file1.sh to this with different quoting:

    #!/bin/bash
    bash -c './file2.sh "$@"' - "$@"
    

    - "$@" is passing hyphen to populate $0 and $@ is being passed in to populate all other positional parameters in bash -c command line.

    You can also make it:

    bash -c './file2.sh "$@"' "$0" "$@"
    

    However there is no real need to use bash -c here and you can just use:

    ./file2.sh "$@"