5

Ubuntu 14.04 から 16.04 に移行するときに、エクスポートされた関数が見つからないために、いくつかの Bash スクリプトが失敗していることに気付きました。これはシェルショックのバグの修正に関係しているのでしょうか, 私は関数を単純に説明export -fし、Bash 内部の関数表現に依存していません. 障害は、間に別のプロセスがある場合にのみ、直接の Bash サブシェルでは発生しません。たとえば、 awk / Perl / Vim を呼び出す Bash は別の Bash を呼び出します。Perl の例を次に示します。

良い

$ foo() { echo "foobar"; }
$ export -f foo
$ export -f; foo
foo ()
{
    echo "foobar"
}
declare -fx foo
foobar
$ bash -c "export -f; foo"
foo ()
{
    echo "foobar"
}
declare -fx foo
foobar
$ perl -e 'system("bash -c \"export -f; foo\"")'
foo ()
{
    echo "foobar"
}
declare -fx foo
foobar
$ echo $BASH_VERSION
4.3.11(1)-release

悪い

$ foo() { echo "foobar"; }
$ export -f foo
$ export -f; foo
foo ()
{
    echo "foobar"
}
declare -fx foo
foobar
$ bash -c "export -f; foo"
foo ()
{
    echo "foobar"
}
declare -fx foo
foobar
$ perl -e 'system("bash -c \"export -f; foo\"")'
bash: foo: command not found
$ echo $BASH_VERSION
4.3.42(1)-release

私は何か間違ったことをしていますか、それともこれはバグですか?

編集:@chepnerは、Bashが特別な名前のシェル識別子を使用して関数を保存していることを指摘しました。dash(0.5.8-2.1ubuntu2、0.5.7-4ubuntu1 での作業) を通過すると、これらの識別子は削除されます。でksh、それらは生き続けます。で確認しました

$ dash
$ sudo strings /proc/$$/environ | grep foo # Still passed from Bash to Dash
BASH_FUNC_foo%%=() {  echo "foobar"
$ bash
$ sudo strings /proc/$$/environ | grep foo # But went missing from Dash to Bash
$ exit
$ exit
$ ksh
$ sudo strings /proc/$$/environ | grep foo
BASH_FUNC_foo%%=() {  echo "foobar"
$ bash
$ sudo strings /proc/$$/environ | grep foo # Kept from Ksh to Bash
BASH_FUNC_foo%%=() {  echo "foobar"

:set shell=/bin/bash同様に、Vim の動作は/で変更できます。:set shell=/bin/ksh

それで、dash責任がありますか?

4

2 に答える 2