Uma instrução if expr (sem colchetes) verifica o status de retorno de expr depois de ser avaliado como um comando bash. Após o sucesso, ele é tratado como um valor true .
Por outro lado, if [[ expr ]] com colchetes duplos é uma palavra-chave bash -specific que pode manipular seu próprio conjunto de opções, como -f /path/to/file para testar a existência de arquivos, ou até mesmo manipular testes de variáveis, como $a == $b . Dentro desses colchetes, você deve explicitamente dizer para avaliar alguma expressão como um conjunto de comandos bash com if [[ $(cmds) ]] . Caso contrário, ele tratará qualquer coisa lá como uma expressão especial e será analisado de maneira diferente.
Há também a construção if [ expr ] , que geralmente é um alias (ou, em alguns casos, uma implementação aproximada de) if test expr . Se o comando test tiver uma opção disponível para uso, você também poderá usá-lo entre colchetes individuais.
Para mais diversão, há a construção if ((expr)) , que é melhor quando se lida com números, já que tudo dentro é avaliado como uma expressão aritmética. Essa também é uma palavra-chave, como os colchetes duplos.
Basicamente, if expr e if [ expr ] são portáveis (ou seja, todos os shells podem lidar com eles e lidar com eles de forma muito idêntica) e if [[ expr ]] e if (( expr )) são específicos da implementação, ou seja, são palavras-chave cuja avaliação depende altamente no shell em que você está usando (e se você não estiver usando algo como bash , zsh ou ksh , eles podem nem existir).