Suponho que você provavelmente tenha um arquivo ou diretório chamado debug
em seu diretório de trabalho atual:
$ ls -l
total 8
-rw-r--r-- 1 jay wheel 58 Feb 1 05:01 T
$ grep [D]ebug T
1 Debug
$ grep [Dd]ebug T
1 Debug
2 debug
$ touch debug
$ ls -l
total 8
-rw-r--r-- 1 jay wheel 58 Feb 1 05:01 T
-rw-r--r-- 1 jay wheel 0 Feb 1 05:05 debug
$ grep [D]ebug T
2 debug
$ grep [Dd]ebug T
2 debug
Eu recomendo esta excelente ilustração porque você deve sempre escapar dos metacaracteres do shell.
Atualização para esclarecer o que está acontecendo : Estou assumindo que, como eu, estamos usando um sistema operacional com um sistema de arquivos que não diferencia maiúsculas de minúsculas (por exemplo, um Mac). Quando você executa o comando, seu shell executa várias expansões antes de executar grep
. Uma delas é expansão de nome de arquivo , na qual colchetes fornecem alternações:
[Dd]ebug
em um sistema de arquivos sensível seria expandido para Debug debug
, Debug
ou debug
dependendo de quais arquivos ele poderia corresponder. Como ele correspondia apenas ao arquivo debug
, seu comando se tornou:
grep debug T
Se você remover esse arquivo e executar touch Debug
, verá a saída do seu comando mudar, porque ele será interpolado como
grep Debug T
Sem o arquivo debug
em seu diretório, seu shell tenta interpolar os colchetes, mas falha sem uma correspondência, por isso passa o argumento inalterado.