Dalam Bash, dua bilangan bulat dapat dibandingkan menggunakan ekspresi kondisional
arg1 OP arg2
OP adalah salah satu
-eq
,-ne
,-lt
,-le
,-gt
, atau-ge
. Operator biner aritmatika ini mengembalikan true jika arg1 sama dengan, tidak sama dengan, kurang dari, kurang dari atau sama dengan, lebih besar dari, atau lebih besar dari atau sama dengan arg2 , masing-masing. Arg1 dan arg2 mungkin bilangan bulat positif atau negatif.
atau ekspresi aritmatika:
<= >= < >
perbandingan
== !=
persamaan dan ketidaksetaraan
Mengapa kita memiliki dua cara berbeda untuk membandingkan dua bilangan bulat? Kapan menggunakan yang mana?
Misalnya, [[ 3 -lt 2 ]]
gunakan ekspresi kondisional, dan (( 3 < 2 ))
gunakan ekspresi aritmatika. Keduanya mengembalikan 0 bila perbandingannya benar
Saat membandingkan dua bilangan bulat, dapatkah kedua metode ini selalu digunakan secara bergantian? Jika ya, mengapa Bash memiliki dua metode daripada satu?
= != < <= > >=
bandingkan string .1 -eq 01
but1 != 01
and8 -lt 42
but8 > 42
Jawaban:
Ya, kami memiliki dua cara berbeda untuk membandingkan dua bilangan bulat.
Tampaknya fakta-fakta ini tidak diterima secara luas di forum ini:
Di dalam idiom
[ ]
operator untuk perbandingan aritmatika adalah-eq
,-ne
,-lt
,-le
,-gt
dan-ge
.Karena mereka juga di dalam perintah uji dan di dalam a
[[ ]]
.Ya dalam idiom ini,
=
,<
, dll operator tali.Di dalam idiom
(( ))
operator untuk perbandingan aritmatika adalah==
,!=
,<
,<=
,>
, dan>=
.Tidak, ini bukan "ekspansi aritmatika" (yang dimulai dengan a
$
) sebagai$(( ))
. Ini didefinisikan sebagai "Perintah Majemuk" di man bash.Ya, ia mengikuti aturan yang sama (secara internal) dari "ekspansi aritmatika" tetapi tidak memiliki output, hanya nilai keluar. Bisa digunakan seperti ini:
Mengapa kita memiliki dua cara berbeda untuk membandingkan dua bilangan bulat?
Saya kira yang terakhir
(( ))
dikembangkan sebagai cara yang lebih sederhana untuk melakukan tes aritmatika. Ini hampir sama dengan$(( ))
tetapi tidak memiliki output.Mengapa dua? Yah sama seperti mengapa kita memiliki dua
printf
(eksternal dan builtin) atau empat tes (eksternaltest
, builtintest
,[
dan[[
). Itulah cara kerang tumbuh, memperbaiki beberapa area dalam satu tahun, meningkatkan beberapa lainnya di tahun berikutnya.Kapan menggunakan yang mana?
Itu pertanyaan yang sangat sulit karena seharusnya tidak ada perbedaan yang efektif. Tentu saja ada beberapa perbedaan dalam cara
[ ]
kerja dan(( ))
kerja secara internal, tetapi: mana yang lebih baik untuk membandingkan dua bilangan bulat? Siapa saja!Saat membandingkan dua bilangan bulat, dapatkah kedua metode ini selalu digunakan secara bergantian?
Untuk dua angka saya terpaksa mengatakan ya.
Tetapi untuk variabel, ekspansi, operasi matematika mungkin ada perbedaan utama yang harus menguntungkan satu atau yang lain. Saya tidak bisa mengatakan bahwa keduanya sama. Untuk satu,
(( ))
dapat melakukan beberapa operasi matematika secara berurutan:Jika ya, mengapa Bash memiliki dua metode daripada satu?
Jika keduanya membantu, mengapa tidak?
sumber
=
adalah tugas dan==
merupakan perbandingan dalam ekspansi aritmatika. Pertanyaannya mengutip dengan benar. Tapi jawabannya salah.Secara historis,
test
perintah itu ada terlebih dahulu (setidaknya sejauh Unix Seventh Edition pada 1979). Ini digunakan operator=
dan!=
untuk membandingkan string, dan-eq
,-ne
,-lt
, dll untuk membandingkan angka. Misalnya,test 0 = 00
itu salah, tetapitest 0 -eq 00
itu benar. Saya tidak tahu mengapa sintaks ini dipilih, tetapi mungkin untuk menghindari menggunakan<
dan>
, yang shell akan diuraikan sebagai operator pengalihan. Thetest
perintah mendapat sintaks lain beberapa tahun kemudian:[ … ]
setara dengantest …
.The
[[ … ]]
sintaks kondisional, dalam yang<
dan>
dapat digunakan sebagai operator tanpa mengutip, ditambahkan kemudian, di ksh. Itu tetap kompatibilitas dengan[ … ]
, jadi itu menggunakan operator yang sama, tetapi ditambahkan<
dan>
untuk membandingkan string (misalnya,[[ 9 > 10 ]]
tetapi[[ 9 -lt 10 ]]
). Untuk informasi lebih lanjut, lihat menggunakan braket tunggal atau ganda - bashEkspresi aritmatika juga datang lebih lambat dari
test
perintah, di kulit Korn , pada suatu waktu di tahun 1980-an. Mereka mengikuti sintaks bahasa C, yang sangat populer di kalangan Unix. Jadi mereka menggunakan operator C:==
untuk persamaan,<=
untuk kurang-atau-sama, dll.Unix Seventh Edition tidak memiliki ekspresi aritmatika, tetapi memang memiliki
expr
perintah , yang juga menerapkan sintaks mirip C untuk operasi integer, termasuk operator pembandingnya. Dalam skrip shell, karakter<
dan>
harus dikutip untuk melindunginya dari shell, misalnyaif expr 1 \< 2; …
setara denganif test 1 -lt 2; …
. Penambahan ekspresi aritmatika ke shell memanfaatkan sebagian besarexpr
usang, sehingga tidak terkenal hari ini.Dalam skrip sh, Anda biasanya akan menggunakan ekspresi aritmatika untuk menghitung nilai integer, dan
[ … ]
membandingkan integer.Dalam skrip ksh, bash, atau zsh, Anda dapat menggunakan
((…))
keduanya.The
[[ … ]]
Bentuk berguna jika Anda ingin menggunakan conditional melibatkan hal-hal lain selain bilangan bulat.sumber
Menurut halaman manual pengujian, = dan! = Digunakan untuk perbandingan string sedangkan ekspresi -eq, -gt, -lt, -ge, -le, dan -ne adalah perbandingan integer. Saya selalu mengikuti konvensi ini ketika menulis skrip shell dan selalu berhasil. Perlu diketahui bahwa jika Anda memiliki variabel dalam ekspresi, Anda mungkin perlu mengutip variabel dalam beberapa cara untuk menghindari melakukan perbandingan nol.
Di atas kertas, kami melakukan perbandingan string / angka tanpa banyak berpikir. Komputer di sisi lain tidak tahu apakah 987 adalah angka atau serangkaian karakter. Anda memerlukan operator yang berbeda untuk memberi tahu komputer apa yang harus dilakukan sehingga Anda mendapatkan hasil yang benar. Ada beberapa info tambahan di sini yang menjelaskan beberapa sejarah. Pada dasarnya, variabel tidak diketik dan tetap seperti itu untuk kompatibilitas historis.
sumber
=
dan!=
operator aritmatika, sedangkan halaman manualtest
hanya menunjukkan operator ekspresi kondisional.