Sim, isso é um problema de cotação: [ ! $3 ]
expande para [ ! south brisbane qld ]
(quatro argumentos entre [
e ]
). E quando ele vê quatro argumentos, com o primeiro um !
, [
espera ver algo como [ ! arg1 op arg2 ]
onde op
é um operador binário. (isso, novamente, é uma das coisas diferentes entre [ .. ]
e [[ .. ]]
; veja este Q e também este Q )
brisbane
não é um operador válido, portanto, ele reclama e retorna 2, o que é falso, portanto, as instruções dentro do if
não são executadas. Para saber a diferença entre um erro e um teste de falha regular, você precisa testar explicitamente o valor de retorno em relação a 2.
Por outro lado, se $3
estiver vazio, o teste se tornará [ ! ]
, um teste de um argumento que verifica se o único argumento não é vazio (é, é a cadeia de um caractere !
) . Nesse caso, ele funciona como planejado, embora talvez não pelo motivo esperado.
Você deseja que [ ! "$3" ]
ou [ -z "$3" ]
mantenha a string como um argumento para [
.
É claro que você também pode inverter o sentido do teste e fazer o trabalho real dentro do if
, para que um erro no teste evite a execução dos comandos principais. Mas isso tornaria a estrutura do código um pouco mais clara.