On Mon, May 15, 2017 at 11:53:57PM -0400, Jeff King wrote:
> My /bin/sh isn't bash, but I should be able to build with
> SHELL_PATH=/bin/bash to reproduce. But I can't:
>
> $ bash
> $ foo() { echo >&2 "in foo"; }
> $ export -f foo
> $ bash -c foo
> in foo
>
> $ strace -f 2>&1 git.compile rebase -x 'foo;' HEAD^ | grep foo
> Executing: foo;
> [pid 1788] execve("/bin/bash", ["/bin/bash", "-c", "foo;", "foo;"], [/*
> 60 vars */] <unfinished ...>
> foo;: foo: command not found
>
> So I'm not sure why the direct "bash -c" can find it, but somehow the
> variable doesn't make it through to the "bash -c" at the lower level.
> Replacing "foo;" with "env" shows the environment, but BASH_FUNC_foo
> isn't set in it. I'm not sure where it's getting eaten, though.
Hmph. It looks like "dash" eats it. My "git.compile" above is a symlink
to /path/to/git/bin-wrappers/git. But it looks like our Makefile isn't
smart enough to rebuild bin-wrappers when you switch SHELL_PATH, so it
will had "/bin/sh" in it. Which points to dash on my machine. And
indeed, dash seems to wipe the environment:
$ foo() { echo >&2 "in foo"; }
$ export -f foo
$ bash -c foo
in foo
$ dash -c "bash -c foo"
bash: foo: command not found
I wonder if it's related to ShellShock protections, or if dash just
rejects variable names with the "%" in them or something. Anyway. That
explains why I had trouble reproducing. Using bash consistently as my
shell lets me reproduce Eric's results. And doing the semicolon trick
does make it work again.
So I feel confident that I've analyzed the problem correctly, at least.
-Peff