[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: GNU Parallel Bug Reports Unexpected execution of /bin/sh when SHELL
From: |
Ole Tange |
Subject: |
Re: GNU Parallel Bug Reports Unexpected execution of /bin/sh when SHELL or PARALLEL_SHELL is bash |
Date: |
Tue, 24 Nov 2015 22:58:01 +0100 |
On Fri, Nov 20, 2015 at 11:27 PM, Zhiming Wang <address@hidden> wrote:
> Consider the following script named 'test':
>
> #!/bin/bash
> func () {
> echo $BASH
> cat <(echo 'hello, world');
> }
> export -f func
> SHELL=/bin/bash parallel ::: func
>
> When the script is executed in OS X (where /bin/sh is bash in sh emulation
> mode; see
> https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/sh.1.html):
>
> > ./test
> sh: func: line 1: syntax error near unexpected token `('
> sh: func: line 1: ` cat <(echo 'hello, world')'
> sh: error importing function definition for `func'
> /usr/local/bin/bash
> hello, world
>
> One can immediately spot two issues here:
>
> 1. Errors printed by sh. Bash-emulated sh tries to import exported functions
> anyway (which I see as a defect), but sh doesn't have process
> substitution,
> hence the errors. However, *why is /bin/sh called in the first place?*
/bin/sh is used for some internal calls: One of the calls is a call to
`ps` to figure out the parent shell.
On my MacOSX I can get the same behaviour by simply:
#!/bin/bash
(echo "#!/bin/sh"; echo "echo foo") > /tmp/bar
chmod 755 /tmp/bar
# OK:
/tmp/bar
# Fails:
func() {
cat <(echo joe)
}
export -f func
/tmp/bar
When these internal calls are run the function is still exported. This
confuses /bin/sh when hitting bash dialects. So GNU Parallel should
probably provide /bin/sh with a clean environment for its internal
calls - i.e. strip any functions for those calls.
> Note that 'func' is successfully executed despite the error messages, and
> the value of $BASH is /usr/local/bin/bash instead of /bin/sh, so bash is
> executed after all.
Yep. After running the internal calls to /bin/sh it starts bash.
> Also note that the error messages are only reproducible on systems where
> /bin/sh is bash. For instance, Debian's /bin/sh is dash, which doesn't try
> to import exported functions in bash, so one won't see the error messages
> on Debian.
>
> 2. Although the parent shell and $SHELL are both /bin/bash, the shell that
> gets executed in the end is /usr/local/bin/bash,
Problem is here that `ps` does not give us full path to the shell: We
only get the command name `-bash`. So GNU Parallel looks through your
$PATH and the first command named `bash` it finds is apparently
/usr/local/bin/bash.
> which seems to contradict
> the $PARALLEL_SHELL part of the man page, according to which the shell is
> determined in the following order:
>
> * $PARALLEL_SHELL;
> * The shell that started GNU Parallel (if it can be determined);
> * $SHELL;
> * /bin/sh.
Unless you have a way to get full path of the parent command then this
part of the bug cannot be solved due to missing information from `ps`,
so help me rephrase the man page, so the above behaviour is more
clear.
/Ole