Ketika scripting, saya biasanya menulis ifs saya dengan sintaks berikut karena lebih mudah bagi saya untuk memahami bahwa apa yang terjadi selanjutnya tidak benar.
if [ ! "$1" = "$2" ]; then
Yang lain mengatakan bahwa cara di bawah ini lebih baik
if [ "$1" != "$2" ]; then
Masalahnya adalah ketika saya bertanya mengapa dan apakah ada perbedaan tampaknya tidak ada yang punya jawaban.
Jadi, apakah ada perbedaan antara kedua sintaksis? Apakah salah satunya lebih aman dari yang lain? Atau itu hanya masalah preferensi / kebiasaan?
!(x==y)
dari(!x)==y
.if [ ! "$string" = "one" ]
jika tidak nilai$string
sama denganone
. Dan iniif [ "$string" != "one"]
diterjemahkan menjadi jika nilai$string
tidak sama denganone
?!=
sintaksis) lebih jelas.Jawaban:
Selain argumen kosmetik / preferensi, satu alasan bisa jadi bahwa ada lebih banyak implementasi di mana
[ ! "$a" = "$b" ]
gagal dalam kasus sudut daripada dengan[ "$a" != "$b" ]
.Kedua kasus harus aman jika implementasi mengikuti algoritma POSIX , tetapi bahkan hari ini (awal 2018 saat penulisan), masih ada implementasi yang gagal. Misalnya, dengan
a='(' b=')'
:Dengan
dash
versi sebelum 0.5.9, seperti 0.5.8 yang ditemukansh
di Ubuntu 16.04 misalnya:(diperbaiki dalam 0,5.9, lihat https://www.mail-archive.com/[email protected]/msg00911.html )
Implementasi tersebut diperlakukan
[ ! "(" = ")" ]
seperti[ ! "(" "text" ")" ]
itu[ ! "text" ]
(uji apakah "teks" adalah string nol) sementara POSIX mengamanatkannya[ ! "x" = "y" ]
(uji "x" dan "y" untuk kesetaraan). Implementasi tersebut gagal karena mereka melakukan tes yang salah dalam kasus itu.Perhatikan bahwa masih ada formulir lain:
Yang itu membutuhkan shell POSIX (tidak akan bekerja dengan shell Bourne yang lama).
Perhatikan bahwa beberapa implementasi memiliki masalah dengan
[ "$a" = "$b" ]
(dan[ "$a" != "$b" ]
) juga dan masih seperti[
builtin/bin/sh
pada Solaris 10 (shell Bourne, shell POSIX berada di/usr/xpg4/bin/sh
). Itu sebabnya Anda melihat hal-hal seperti:Dalam skrip mencoba menjadi portabel untuk sistem lama.
sumber
! "$a" = "b"
Anda harus lebih berhati-hati tentang bagaimana Anda menulisnya untuk menentukan perbandingan. Dari contoh Anda, saya mengerti bahwa perintah kedua kembalinot zero
yang bisa bermanfaat atau mengganggu. Ini bisa bermanfaat jika Anda ingin keluar jika mereka tidak cocok, atau menyusahkan jika Anda ingin melihat apakah perbandingannya[ ! "$a" = "$b" ]
hanya gagal ketika$a
adalah(
dan$b
adalah)
, klaim mereka adalah identik ketika mereka tidak,(
tidak string sama)
, tapi[
melakukan tes yang salah dalam kasus itu.[ ! "$a" = "$b" ]
kadang-kadang ditangani dengan tidak benar dalam implementasi buggy shell (yang saya pikir lebih atau kurang menyatakan kembali kalimat pertama dari jawaban).The
x != y
sintaks adalah lebih baik karena! x == y
rawan kesalahan - membutuhkan pengetahuan tentang operator didahulukan yang berbeda dari bahasa ke bahasa. Sintaks! x == y
bisa diartikan sebagai!(x == y)
atau(!x) == y
, tergantung pada prioritas!
vs=
.Misalnya, dalam
c++
negasi!
datang sebelum operator perbandingan / relasional==
, maka kode berikut:kembali
Perilaku serupa dapat diamati dalam banyak bahasa lain, termasuk misalnya
awk
- alat yang sering digunakan di dunia Unix.Di sisi lain, mengumpulkan operator melalui
x != y
tidak menyebabkan kebingungan sebagai pola yang mapan. Selain itu, secara teknis!=
seringkali bukan hanya dua, tetapi hanya satu operator, sehingga harus lebih cepat untuk mengevaluasi daripada perbandingan yang terpisah dan kemudian negasi. Oleh karena itu, walaupun kedua sintaks bekerja di bash, saya akan merekomendasikan untuk mengikutix != y
karena lebih mudah untuk membaca dan memelihara kode yang mengikuti beberapa logika standar.sumber
Hal semacam ini sangat didasarkan pada opini, karena "jawaban" sangat tergantung pada bagaimana otak seseorang terjadi. Memang benar bahwa secara semantik
NOT ( A == B )
identik dengan yang(A != B )
satu mungkin lebih jelas bagi satu orang dan yang lain bagi orang lain. Ini juga tergantung pada konteks. Misalnya, jika saya memiliki set bendera, artinya mungkin lebih jelas dengan satu sintaks atas yang lain:sebagai lawan
sumber
if ( FS_OPEN != fileHandleStatus )
sebagai akibat dari kemudahan mengetik secara tidak sengaja=
alih-alih==
dalam bahasa di mana yang pertama adalah penugasan dan tes kesetaraan yang kemudian (seperti C) ...