My Redhat 9, OpenBSD 4.9, FreeBSD 10, Macos X, LinuxMint 17.3, and Ubuntu 14.04.4 all print OK when running this:
myfunc() { echo OK; }
export -f myfunc
perl -e open\(\$fh,\"\|-\",\"@ARGV\"\)\;close\$fh\; /bin/bash\ -c\ myfunc\\\ a
My Ubuntu 16.04.1 gives:
bash: myfunc: command not found
But if I remove \\\ a it works.
perl -e open\(\$fh,\"\|-\",\"@ARGV\"\)\;close\$fh\; /bin/bash\ -c\ myfunc
I have the feeling something is configured wrongly on my system, but what should I look for?
Edit
thrig found a shorter version that also fails. Using that I straced on a failing and a non-failing system:
stdout strace -ff perl -e 'system @ARGV' /bin/bash\ -c\ myfunc\\\ a|grep bash
Failing:
execve("/usr/bin/perl", ["perl", "-e", "system @ARGV", "/bin/bash -c myfunc\\ a"], [/* 71 vars */]) = 0
[pid 7728] execve("/bin/sh", ["sh", "-c", "/bin/bash -c myfunc\\ a"], [/* 71 vars */]) = 0
[pid 7729] execve("/bin/bash", ["/bin/bash", "-c", "myfunc a"], [/* 70 vars */]) = 0
Non-failing:
execve("/usr/bin/perl", ["perl", "-e", "system @ARGV", "/bin/bash -c myfunc\\ a"], [/* 20 vars */]) = 0
[pid 26497] execve("/bin/sh", ["sh", "-c", "/bin/bash -c myfunc\\ a"], [/* 20 vars */]) = 0
[pid 26498] execve("/bin/bash", ["/bin/bash", "-c", "myfunc a"], [/* 20 vars */]) = 0
That looks awfully similar. Removing the \\\ a gives on both systems:
execve("/usr/bin/perl", ["perl", "-e", "system @ARGV", "/bin/bash -c myfunc"], [/* 71 vars */]) = 0
[pid 7826] execve("/bin/bash", ["/bin/bash", "-c", "myfunc"], [/* 71 vars */]) = 0
So Perl drops the sh -c if there is only a single command. Maybe sh -c eats the function on the Ubuntu 16.04?
/bin/sh is dash on both systems.
Edit2
env shows the function. This displays the function as part of the environment on both systems:
perl -e 'system @ARGV' /bin/bash\ -c\ env
Ubuntu 16.04 and one working system:
BASH_FUNC_myfunc%%=() { echo OK
}
Other working system:
BASH_FUNC_myfunc()=() { echo OK
}
But this shows only the definition on the working systems:
perl -e 'system @ARGV' /bin/bash\ -c\ env';true'
Edit3
Workaround:
myfunc() { echo OK; }
export -f myfunc
perl -e open\(\$fh,\"\|-\",@ARGV\)\;close\$fh\; /bin/bash -c myfunc\ a