Consider the following test case: func() { cat > /dev/foo <<_EOF_ || echo FAIL 11 _EOF_ } func declare -fp The func invocation works as expected -- write fails and 'echo FAIL' is invoked. However, 'declare -fp' transforms the function into: func () { cat > /dev/foo <<_EOF_ || 11 _EOF_ echo FAIL } which is no longer valid. A user ran into this [1] since my eclasses use '|| die' like this to handle write failures and portage uses 'declare -fp' for environment saving. [1]:http://forums.gentoo.org/viewtopic-p-7319862.html
seems to me this snippet has always been broken. bash 3.0, 3.1, 3.2, 4.0, 4.1, and 4.2 all fail the same way. one might say that since this is how bash 3.2 behaves, PMS mandates you never use this syntax :). we've seen similar issues in the past, but i can't find the bug for it. doesn't matter ... posted the snippet to upstream bug-bash list.
mmm actually that code is valid. you're right that bash-3.2 gets it wrong, but bash-4.0+ gets it right (if || is after the heredoc, it is correct). but as mentioned, since bash-3.2 gets it wrong, you may not use this syntax as long as PMS says we have to be compatible with bash-3.2. sample code: $ cat test.sh func() { cat > / <<EOF || echo FAIL 11 EOF } func declare -fp > x.sh . ./x.sh func here is bash-4.0 doing the correct thing: $ bash-4.0_p28 ./test.sh ./test.sh: line 2: /: Is a directory FAIL ./x.sh: line 3: /: Is a directory FAIL and here is bash-3.2 getting it wrong: $ bash-3.2_p50 ./test.sh ./test.sh: line 2: /: Is a directory FAIL ./x.sh: line 6: syntax error near unexpected token `||' ./x.sh: line 6: ` || echo FAIL' ./test.sh: line 2: /: Is a directory FAIL