[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Parsing error when "case" in "for" in $()
From: |
Dan Douglas |
Subject: |
Re: Parsing error when "case" in "for" in $() |
Date: |
Tue, 11 Sep 2012 18:01:30 -0500 |
User-agent: |
KMail/4.8.3 (Linux/3.4.6-pf+; KDE/4.8.3; x86_64; ; ) |
On Tuesday, September 11, 2012 05:31:36 PM Steven W. Orr wrote:
> On 09/11/12 17:20, quoth Chris F.A. Johnson:
> > On Tue, 11 Sep 2012, Benoit Vaugon wrote:
> > ...
> >> Description:
> >> Cannot use "case" construction in a "for" loop in a $() sub shell.
> >> Should work but produces parsing error.
> >>
> >> Repeat-By:
> >> echo $(for x in whatever; do case y in *) echo 42;; esac; done)
> >
> > The closing parentheses in the case statement is being interpreted as the
> > closing for $(
> >
> >> Fix:
> >> Probably by fixing the bash parser.
> >
> > Balance the parentheses in the case statement:
> >
> > echo $(for x in whatever; do case y in (*) echo 42;; esac; done)
> >
>
> Thanks. I didn't know that the opening paren was optional and was needed in
> such a case as a disambiguator. Very nice. And if you really want to match
> something that starts with an open paren, just backslash it.
>
> As a style issue, it makes me wonder if I should always use the optional
> open paren as syntactic sugar...
I could only reproduce it with an unquoted command substitution. It may still
not be correct even though there are workarounds. The existance of an
enclosing compound command shouldn't affect the parsing of the inner one.
The workaround might be a good idea anyway. ksh fails this in some
permutations but not others, while most other shells seem to be able to handle
it (except zsh which usually fails). CC'd ast-devel in case they consider it a
bug worth fixing.
: $(case . in .) :; esac)
fails: zsh
: $(case . in (.) :; esac)
fails:
: $({ case . in .) :; esac; })
fails: sh bash zsh
: "$({ case . in .) :; esac; })"
fails: zsh
: $(for x in .; do case . in .) :; esac; done)
fails: sh bash zsh ksh
: "$(for x in .; do case . in .) :; esac; done)"
fails: zsh
bash/ksh compatable testcase:
---
#!/usr/bin/env bash
shells=( sh {{b,d}a,z,{,m}k}sh bb )
while IFS= read -r testCase; do
printf '%s\nfails: ' "$testCase"
for sh in "${shells[@]}"; do
"$sh" -c "$testCase" 2>/dev/null || printf '%s ' "$sh"
done
echo $'\n'
done <<"EOF"
: $(case . in .) :; esac)
: $(case . in (.) :; esac)
: $({ case . in .) :; esac; })
: "$({ case . in .) :; esac; })"
: $(for x in .; do case . in .) :; esac; done)
: "$(for x in .; do case . in .) :; esac; done)"
EOF
--
Dan Douglas
signature.asc
Description: This is a digitally signed message part.