Ao criar scripts, geralmente escrevo meus ifs com a seguinte sintaxe, pois é mais fácil entender que o que vem a seguir não é verdadeiro.
if [ ! "$1" = "$2" ]; then
Outros dizem que o caminho abaixo é melhor
if [ "$1" != "$2" ]; then
A questão é quando pergunto por que e se existem diferenças, ninguém parece ter resposta.
Então, existem diferenças entre as duas sintaxes? Um deles é mais seguro que o outro? Ou é apenas uma questão de preferência / hábito?
!(x==y)
a partir(!x)==y
.if [ ! "$string" = "one" ]
traduz em senão o valor de$string
igualone
. E isso seif [ "$string" != "one"]
traduz se o valor de$string
não for igual aone
?!=
sintaxe) é apenas mais óbvio.Respostas:
Além dos argumentos cosméticos / de preferência, um motivo pode ser o fato de haver mais implementações em que
[ ! "$a" = "$b" ]
falhas nos casos de canto do que com[ "$a" != "$b" ]
.Ambos os casos devem ser seguros se as implementações seguirem o algoritmo POSIX , mas ainda hoje (início de 2018), ainda existem implementações que falham. Por exemplo, com
a='(' b=')'
:Com
dash
versões anteriores à 0.5.9, como a 0.5.8 encontradash
no Ubuntu 16.04, por exemplo:(corrigido em 0.5.9, consulte https://www.mail-archive.com/[email protected]/msg00911.html )
Essas implementações tratam
[ ! "(" = ")" ]
como[ ! "(" "text" ")" ]
é[ ! "text" ]
(teste se "texto" é a cadeia nula), enquanto o POSIX exige que seja[ ! "x" = "y" ]
(teste "x" e "y" para igualdade). Essas implementações falham porque executam o teste errado nesse caso.Observe que há ainda outra forma:
Esse requer um shell POSIX (não funcionará com o shell Bourne antigo).
Observe que várias implementações também tiveram problemas com
[ "$a" = "$b" ]
(e[ "$a" != "$b" ]
) e ainda se assemelham às[
do/bin/sh
Solaris 10 (um shell Bourne, o shell POSIX está dentro/usr/xpg4/bin/sh
). É por isso que você vê coisas como:Em scripts, tentando ser portável para sistemas antigos.
fonte
! "$a" = "b"
você precisa ter mais cuidado com a forma como a escreve para especificar a comparação. Pelo seu exemplo, entendo que o segundo comando retorna, onot zero
que pode ser benéfico ou preocupante. Poderia ser benéfico se você quiser sair se eles não corresponderem, ou incomodando se você quiser ver se a comparação caiu[ ! "$a" = "$b" ]
apenas falha quando$a
é(
e$b
é)
, alega que elas são idênticas quando não são,(
não é a mesma string que)
, mas[
executa o teste errado nesse caso.[ ! "$a" = "$b" ]
às vezes, é manipulado incorretamente em implementações de shell de buggy (que eu acho que está mais ou menos reafirmando a primeira frase da resposta).A
x != y
sintaxe é melhor porque! x == y
é propensa a erros - requer conhecimento da precedência dos operadores, que difere de idioma para idioma. A sintaxe! x == y
poderia ser interpretado como!(x == y)
ou(!x) == y
, dependendo prioridade!
vs=
.Por exemplo, na
c++
negação!
vem antes do operador de comparação / relacional==
, portanto, o seguinte código:retorna
Comportamento semelhante pode ser observado em muitas outras línguas, incluindo, por exemplo
awk
- uma ferramenta frequentemente usada no mundo Unix.Por outro lado, reunir operadores via via
x != y
não leva a nenhuma confusão como um padrão bem estabelecido. Além disso, tecnicamente falando!=
muitas vezes não são dois, mas apenas um operador, portanto, deve ser ainda mais marginalmente mais rápido que avaliar do que comparar separadamente e depois negar. Portanto, embora ambas as sintaxes funcionem no bash, eu recomendaria seguirx != y
, pois é muito mais fácil ler e manter o código que segue alguma lógica padrão.fonte
Esse tipo de coisa é muito baseada em opiniões, pois a "resposta" depende muito da maneira como o cérebro de um indivíduo é conectado. Embora seja verdade que, semanticamente,
NOT ( A == B )
seja idêntico a(A != B )
, um pode ser mais claro para uma pessoa e o outro para outra. Também é dependente do contexto. Por exemplo, se eu tiver um sinalizador definido, os significados podem ficar mais claros com uma sintaxe do que com outra:em oposição a
fonte
if ( FS_OPEN != fileHandleStatus )
como resultado da facilidade de acidentalmente digitando=
em vez de==
nas línguas em que o primeiro é atribuição eo teste de igualdade mais tarde (como C) ...