Meu Redhat 9, OpenBSD 4.9, FreeBSD 10, MacOS X, LinuxMint 17.3 e Ubuntu 14.04.4, todos imprimem OK ao executar este:
myfunc() { echo OK; }
export -f myfunc
perl -e open\(\$fh,\"\|-\",\"@ARGV\"\)\;close\$fh\; /bin/bash\ -c\ myfunc\\ a
Meu Ubuntu 16.04.1 fornece:
bash: myfunc: command not found
Mas se eu remover \\ a
, isso funciona.
perl -e open\(\$fh,\"\|-\",\"@ARGV\"\)\;close\$fh\; /bin/bash\ -c\ myfunc
Tenho a sensação de que algo está configurado incorretamente no meu sistema, mas o que devo procurar?
Editar
Othrig encontrou uma versão mais curta que também falha. Usando isso eu me esforcei em um sistema com falha e sem falha:
stdout strace -ff perl -e 'system @ARGV' /bin/bash\ -c\ myfunc\\ a|grep bash
Falha:
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
Sem falhas:
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
Isso parece muito semelhante. Removendo o \\ a
nos dois sistemas:
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
Então o Perl descarta o sh -c
se houver apenas um único comando. Talvez sh -c
come a função no Ubuntu 16.04?
/bin/sh
é dash
em ambos os sistemas.
Edit2
env
mostra a função. Isso exibe a função como parte do ambiente em ambos os sistemas:
perl -e 'system @ARGV' /bin/bash\ -c\ env
Ubuntu 16.04 e um sistema de trabalho:
BASH_FUNC_myfunc%%=() { echo OK
}
Outro sistema de trabalho:
BASH_FUNC_myfunc()=() { echo OK
}
Mas isso mostra apenas a definição dos sistemas de trabalho:
perl -e 'system @ARGV' /bin/bash\ -c\ env';true'
Editar3
Solução alternativa:
myfunc() { echo OK; }
export -f myfunc
perl -e open\(\$fh,\"\|-\",@ARGV\)\;close\$fh\; /bin/bash -c myfunc\ a