导出函数中子函数中的 Heredoc 失败

Ole*_*nge 4 bash here-document

这有效:

#!/bin/bash

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

foo
export -f foo
bash -c foo
Run Code Online (Sandbox Code Playgroud)

这在最后一行失败:

#!/bin/bash

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

foo
export -f foo
bash -c foo
Run Code Online (Sandbox Code Playgroud)

给予:

bar
bash: foo: line 9: syntax error: unexpected end of file
bash: error importing function definition for `foo'
bash: foo: command not found
Run Code Online (Sandbox Code Playgroud)

为什么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.
Run Code Online (Sandbox Code Playgroud)

ilk*_*chu 5

这是一个错误,显然于 2019 年 7 月首次报告,请参阅:

还有一个关于 SO 的问题,有一个非常相似的测试用例(链接到上面的最后一封邮件):Exporting a function with an nested function definition and heredoc in bash

CHANGES 文件在 bash-5.0-release 和 bash-5.1-alpha 之间列出了这个:

ll. Fixed a bug with printing function definitions containing here documents.
Run Code Online (Sandbox Code Playgroud)

据我测试,您的测试用例适用于 Bash 4.4 和当前的 git 版本。


我在这里发现奇怪的是,如果您在declare -p -f foo定义函数之后查看,您会看到 here-doc 已被踢出外gen,如果true存在,则不会发生这种情况。看起来它把那里的东西弄乱了。这是工作版本:

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

    gen
}
Run Code Online (Sandbox Code Playgroud)

这是破碎的:

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

    gen
}
Run Code Online (Sandbox Code Playgroud)

请注意,<< EOF重定向位于错误的位置。闭幕式}。git 版本看起来将重定向放在实际放置的位置,与 Ksh 和 Zsh 所做的相同。