Você está perdendo algumas outras regras de sintaxe. Dentro de uma expansão de colchetes, além dos intervalos simples, há também alguns tipos de expressões com vários caracteres que começam com [ . (Veja o regex (7) manual para Linux ou FreeBSD em "Com exceção destas e algumas combinações usando '[' (veja os próximos parágrafos)".) Estas são:
- Agrupando elementos:
[.….] - Classes de equivalência:
[=…=] - Classes de caracteres:
[:…:]
(Você pode ter visto ou usado expressões como [[:digit:]] - na verdade, é uma classe de caractere [:digit:] que é o elemento isolado de uma expansão de suporte […] ).
Portanto, no seu caso, como o . passa a ser imediatamente após um [ , eles são reconhecidos como o delimitador de abertura de um elemento de intercalação. O GNU grep 3.1 tem a mensagem de erro correta:
$ printf 'abcde.fgh' | grep -iEq '^[^][.$^*_-]'
grep: Unmatched [, [^, [:, [., or [=
As mesmas expressões podem ser usadas para escapar de tais situações usando, e. [...] ou [=.=] para incluir um ponto regular, ou similarmente [=-=] para corresponder a um traço, se não houver nenhum lugar para movê-los.