POSIX documentation for pattern matching said that:
An ordinary character is a pattern that shall match itself. It can be any character in the supported character set except for NUL, those special shell characters in Quoting that require quoting, and the following three special pattern characters. Matching shall be based on the bit pattern used for encoding the character, not on the graphic representation of the character. If any character (ordinary, shell special, or pattern special) is quoted, that pattern shall match the character itself. The shell special characters always require quoting.
As I understand, the pattern
["!"a] will match any of
a. That's also the behavior in most shells I tried, except
$ for shell in /bin/*[^c]sh; do printf '=%-17s=\n' "$shell" "$shell" -c 'case a in ["!"a]) echo 1;; esac' done =/bin/ash = 1 =/bin/bash = 1 =/bin/dash = 1 =/bin/heirloom-sh = 1 =/bin/ksh = =/bin/lksh = 1 =/bin/mksh = 1 =/bin/pdksh = 1 =/bin/posh = 1 =/bin/schily-osh = 1 =/bin/schily-sh = 1 =/bin/yash = 1 =/bin/zsh =
ksh93 seem to treat
["!"a] the same as
[!a], which match any character except
$ for shell in ksh93 zsh; do printf '=%-6s=\n' "$shell" "$shell" -c 'case b in ["!"a]) echo 1;; esac' done =ksh93 = 1 =zsh = 1
Is there any reason (historical, development, ...) for
ksh93 behave like that?
zsh does the same thing in both
busybox sh, Solaris
/usr/xpg4/bin/sh and FreeBSD
sh also behave like POSIX documentation.
ksh88 also behave like most other shells, the behavior changed between
$ ksh88 -c 'case a in ["!a"]) echo yes; esac' yes $ ksh88 -c 'case b in ["a-c"]) echo yes; esac' $