Preferido

Preferido

Existe uma diferença no bash ou um uso preferencial de negação de uma instrução?

if ! [[ -z "${var}" ]]; then
  do_something
fi

Contra

if [[ ! -z "${var}" ]]; then
  do_something
fi

Responder1

! [[ expression ]]

Isso será verdadeiro se todo o teste retornar falso

[[ ! expression ]]

Isso será verdadeiro se a expressão individual retornar falso.


Como o teste pode ser uma expressão composta, isso pode ser muito diferente. Por exemplo:

$ [[ ! 0 -eq 1 || 1 -eq 1 ]] && echo yes || echo no
yes
$ ! [[ 0 -eq 1 || 1 -eq 1 ]] && echo yes || echo no
no

Pessoalmente, prefiro usar a negação dentro da construção de teste, quando aplicável, mas está perfeitamente bem fora, dependendo da sua intenção.

Responder2

A ! cmdé na verdade umcanoe !nega o código de saída dotodocano.

Do homem bash:

Pipelines Um pipeline é uma sequência de um ou mais comandos separados por um dos operadores de controle | ou |&. O formato de um pipeline é:

         [time [-p]] [ ! ] command [ [|||&] command2 ... ]

...
Se a palavra reservada ! precede um pipeline, o status de saída desse pipeline é a negação lógica do status de saída conforme descrito acima. O shell aguarda que todos os comandos no pipeline sejam finalizados antes de retornar um valor.

Nesse sentido, um:

! [[ 2 -eq 2 ]]

É a negação ( !) do código de saída do todo [[(depois que tudo tiver sido executado). Portanto, este tem um código de saída 0:

!  [[ 2 -eq 2 && 3 -eq 4 ]]

No entanto

Um [[ ! ]]é umComando composto(não é um cano). Do homem bash:

Comandos compostos
...
[[ expressão ]]
Retorna um status de 0 ou 1 dependendo da avaliação da expressão condicional expressão.
As expressões são compostas pelas primárias descritas abaixo em EXPRESSÕES CONDICIONAIS.

Portanto, este tem um código de saída 1:

[[ ! 2 -eq 2 && 3 -eq 4 ]]

Porque isso é realmente equivalente a isto:

[[ ( ! 2 -eq 2 ) && ( 3 -eq 4 ) ]]

Que, por avaliação de curto-circuito, o lado direito do &&nunca é avaliado e é na verdade equivalente a esta expressão muito mais curta:

[[ ! 2 -eq 2 ]]

O que sempre será falso (1).

Resumindo: dentro de [[, o ! afetapeçasda expressão.

Preferido

Usar o !inside [[é muito mais comum (e portátil para mais shells (com [)), mas às vezes pode ser confuso se não for explicitamente controlado pelo uso criterioso de ()para delimitar a extensão da negação (o que pode se tornar um problema dentro [das construções).

Mas (em bash, ksh e zsh) o resultado ! [[é claramente definido e mais fácil de entender: execute o todo [[e negue o resultado.

Qual deles deve ser usado é uma questão de preferência pessoal (e compreensão).

informação relacionada