$(case x in x)...
The man page berates old-timers: When the old-style backquote form of substitution is used... However, who is it that is too hungry for the next ")"?: $ k=$(case x in x) :;; esac) bash: syntax error near unexpected token `;;' $ k=$(case x in x) :; esac) bash: syntax error near unexpected token `esac' $ k=`case x in x) :; esac` $ The man page even mentions: Command substitutions may be nested. To nest when using the backquoted form, escape the inner backquotes with backslashes. But tripping/conflict over case esac innards hadn't been discovered until today for $() so isn't mentioned. Fix the "bug" or mention it here and in the "case ... esac" sections of all docs. By the way, >> How can one make a "ESC ." command that will get the last word from >> the last line, even if we have just hit a few ^P's? C> You'll have to modify the source, since ^P changes your position in C> the history list. (It is more likely that the source will modify me. Anyway, I end up pasting with the mouse 30 times a day. I have only once in my life used ^R.ESC. or ^P^P^P...ESC. as offered.) ___ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash
Re: $(case x in x)...
> However, who is it that is too hungry for the next ")"?: > $ k=$(case x in x) :;; esac) > bash: syntax error near unexpected token `;;' > $ k=$(case x in x) :; esac) > bash: syntax error near unexpected token `esac' > $ k=`case x in x) :; esac` I believe this is a bug in bash 3.0. I have confirmed that it still exists in bash-3.1-beta1, but have not yet tested if bash 3.1 final patchlevel 1 has fixed the bug. POSIX requires (http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_03) that in the $(command) form, "Any valid shell script can be used for command." The rationale page (http://www.opengroup.org/onlinepubs/009695399/xrat/xcu_chap02.html) then proceeds to list several examples of $() commands where an unmatched ')' can appear inside the nested command, when used as part of a valid shell script (although it did not list the example of case with unmatched ')'). Furthermore, the rationale page states under the Case Conditional Construct: "At one time, using the leading parenthesis was required if the case statement was to be embedded within a "$()" command substitution; this is no longer the case with the POSIX shell." Therefore, I read this as stating that POSIX requires your example to succeed, and that bash has a bug (FYI, the bug also appears in my installed versions of zsh and ksh). Meanwhile, as a workaround, use: $ k=$(case x in (x) :; esac) -- Eric Blake ___ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash
Re: $(case x in x)...
> I have confirmed that > it still exists in bash-3.1-beta1, but have not yet tested > if bash 3.1 final patchlevel 1 has fixed the bug. My results: bash 3.1, with or without patch 1, still has the bug. $ k=$(case x in x) echo hi; esac) bash: syntax error near unexpected token `esac' > The rationale page > (http://www.opengroup.org/onlinepubs/009695399/xrat/xcu_chap02.html) > then proceeds to list several examples of $() commands where > an unmatched ')' can appear inside the nested command, when used > as part of a valid shell script. Of which, bash gets 2 of the three examples WRONG: Required: $ echo $( > cat < a here-doc with ) > eof > ) a here-doc with ) $ echo $( > echo abc # a comment with ) > ) abc $ echo $( > echo ')' > ) ) bash 3.0.16: $ echo $( > cat << /eof > a here-doc with ) a here-doc with $ # oops, the ) in the here-doc was consumed to close the $(), and $ # without a warning of a missing eof delimiter $ echo $( > echo abc # a comment with ) abc $ # oops, the ) in the comment was consumed to close the $() $ echo $( > echo ')' > ) ) $ # The only correct answer of the three bash 3.1.1: $ echo $( > cat << /eof > a here-doc with ) a here-doc with $ # oops, the ) in the here-doc was consumed to close the $(), and $ # without a warning of a missing eof delimiter $ echo $( > echo abc # a comment with ) > ) abc ) $ # oops, an extra ) snuck through to the outer echo $ echo $( > echo ')' > ) ) $ # The only correct answer of the three -- Eric Blake ___ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash