エクスポートされた関数の子関数のHeredocが失敗します。

エクスポートされた関数の子関数のHeredocが失敗します。

これは働きます:

#!/bin/bash

foo() {
    gen() {
        cat <<EOF
bar
EOF
        true
    }
    gen
}

foo
export -f foo
bash -c foo

最後の行で失敗します。

#!/bin/bash

foo() {
    gen() {
        cat <<EOF
bar
EOF
    }
    gen
}

foo
export -f foo
bash -c foo

与える:

bar
bash: foo: line 9: syntax error: unexpected end of file
bash: error importing function definition for `foo'
bash: foo: command not found

true最後のものはなぜ必要ですか?

$ bash --version
GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

答え1

これは2019年7月に最初に報告されたバグです。以下を参照してください。

非常に似たテストケースを持つSOに関する質問もあります(上記の最後のEメールリンク)。Bashでネストされた関数定義と区切り文字を使用して関数をエクスポートする

CHANGESファイルには、bash-5.0-releaseとbash-5.1-alphaの間の内容がリストされています。

ll. Fixed a bug with printing function definitions containing here documents.

私がテストできる限り、あなたのテストケースはBash 4.4と現在のgitバージョンで動作します。


declare -p -f fooここで私が疑問に思うのは、関数が定義されていることを見ると、here-docがgen存在した場合に発生しなかった外部に打ち込まれたことを見ることができるということです。trueそこに何かが混乱しているようです。これは作業バージョンです:

$ declare -p -f foo
foo () 
{ 
    function gen () 
    { 
        cat 
    } <<EOF
bar
EOF

    gen
}

これは壊れています:

$ declare -p -f foo
foo ()
{   
    function gen ()
    {   
        cat <<EOF
    }
bar
EOF 

    gen
}

<< EOFリダイレクトが間違った場所にあります。閉幕式}。 gitバージョンは、KshやZshと同様に、実際に配置された場所にリダイレクトを配置するようです。

関連情報