Os colchetes são uma notação abreviada para realizar um teste condicional. Os colchetes [
, bem como [[
são comandos reais dentro do Unix, acredite ou não.
Pense:
$ [ -f /etc/rc.local ] && echo "real file"
real file
-and-
$ test -f /etc/rc.local && echo "real file"
real file
No Bash, o [
é um comando interno, assim como um executável. [[
é apenas uma palavra-chave para o Bash.
Exemplo
Você pode confirmar isso usando type
:
$ type -a [
[ is a shell builtin
[ is /usr/bin/[
$ type -a [[
[[ is a shell keyword
Você pode ver o executável físico aqui:
$ ls -l /usr/bin/[
-rwxr-xr-x 1 root root 37000 Nov 3 2010 /usr/bin/[
builtins vs. keywords
Se você der uma olhada na página man do Bash, man bash
, você encontrará as seguintes definições para o 2:
-
palavras-chave - Palavras reservadas são palavras que têm um significado especial para o shell. As seguintes palavras são reconhecidas como reservadas quando não mencionadas e a primeira palavra de um comando simples (consulte SHELL GRAMMAR abaixo) ou a terceira palavra de um caso ou comando:
! case do done elif else esac fi for function if in select then until while { } time [[ ]]
-
builtins - Se o nome do comando não contiver barras, o shell tentará localizá-lo. Se existe uma função de shell com esse nome, essa função é invocada como descrito acima em FUNÇÕES. Se o nome não corresponder a uma função, o shell a procurará na lista de built-ins do shell. Se uma correspondência for encontrada, esse builtin é invocado.
Se o nome não for nem uma função do shell nem um builtin e não contiver barras, o bash pesquisará cada elemento do PATH em um diretório que contenha um arquivo executável com esse nome. O Bash usa uma tabela de hash para lembrar os nomes completos dos arquivos executáveis (veja o hash em SHELL BUILTIN COMMANDS abaixo). Uma pesquisa completa dos diretórios no PATH é executada somente se o comando não for encontrado na tabela de hash. Se a pesquisa não for bem-sucedida, o shell procurará uma função de shell definida denominada command_not_found_handle. Se essa função existir, ela é invocada com o comando original e os argumentos do comando original como seus argumentos, e o status de saída da função se torna o status de saída do shell. Se essa função não estiver definida, o shell imprimirá uma mensagem de erro e retornará um status de saída de 127.
man page
Se você examinar a página do manual do Bash, encontrará os detalhes.
test expr
[ expr ]
Return a status of 0 or 1 depending on the evaluation of the
conditional expression expr. Each operator and operand must be
a separate argument. Expressions are composed of the primaries
described above under CONDITIONAL EXPRESSIONS. test does not
accept any options, nor does it accept and ignore an argument of
-- as signifying the end of options.
Por fim, na página do manual:
test and [ evaluate conditional expressions using a set of rules
based on the number of arguments.
EDIT # 1
Pergunta de acompanhamento do OP.
Ok, so why is there a need for an "if" then? I mean, why "if" even exists if "[" would suffice.
O if
faz parte de um condicional. O comando test
ou [ ... ]
simplesmente avalia o condicional e retorna um 0 ou um 1. O 0 ou 1 é então acionado pela instrução if. Os 2 estão trabalhando juntos quando você os usa.
Exemplo
if [ ... ]; then
... do this ...
else
... do that ...
fi