Hi,
On 17/04/2019 17:29, Drew DeVault wrote:
Unless I'm misinterpreting the specification, it seems like dash doesn't
handle pattern matching in case statements correctly. The following
sample demonstrates the issue:
#!/bin/sh -eu
while read -r line
This will strip leading and trailing whitespace. To prevent that, you
need to set IFS to an empty string first.
do
case "$line" in
[:space:]*:)
This will match on a first character that is ':', 's', 'p', 'a', 'c',
'e', or ':' (again), not a first character that is a space. You want
[[:space:]]*: here.
echo "a"
;;
*:)
echo "b"
;;
*)
echo "c"
;;
esac
done <<EOF
libgit2 policy:
0.27.8-r0:
lib/apk/db/installed
https://mirror.sr.ht/alpine/sr.ht/
EOF
The expected output is b a c c, but the output in practice is b b c c.
Quoting the spec:
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_04_05
...case shall execute the compound-list corresponding to the first one of
several patterns (see Pattern Matching Notation)...
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_13
...patterns matching a single character shall match a single character:
ordinary characters, special pattern characters, and pattern bracket
expressions...
...an open bracket... shall introduce a pattern bracket expression... as in
XBD RE Bracket Expression...
http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03_05
...The following character class expressions shall be supported in all
locales:
[:space:]
Character class expressions cannot be used by themselves, they can only
be part of bracket expressions, which is why you need the double [[ and ]].
Am I misinterpreting the spec or is this indeed a problem with dash? In
addition to this issue, the following example cause a parsing error:
[ \t])
Both problems can be reproduced with bash.
[ \t] does not work because the space ends the word. Additionally, \t
does not mean "tab", it just means a literal "t". You could use [\ \ ]
instead, or [" "], where in both cases the second blank is a literal tab.
Cheers,
Harald van Dijk