Bash: dobel sama dengan -eq

47

Saya melakukan perbandingan integer di bash (mencoba melihat apakah pengguna berjalan sebagai root), dan saya menemukan dua cara berbeda untuk melakukannya:

Ganda sama dengan:

if [ $UID == 0 ]
then
fi

-eq

if [ $UID -eq 0 ]
then
fi

Saya mengerti bahwa tidak ada> = atau <= dalam bash, hanya -ge dan -le, jadi mengapa ada ==jika ada -eq?

Apakah ada perbedaan dalam cara membandingkan kedua belah pihak?

hajar
sumber
3
Perhatikan bahwa spasi di dalam tanda kurung diperlukan:, [ $UID -eq 0 ]tidak [ $UID -eq 0].
Gilles 'SO- berhenti bersikap jahat'

Jawaban:

50

==adalah bashalias khusus untuk =, yang melakukan perbandingan string (leksikal) alih-alih -eqperbandingan numerik. (Ini mundur dari Perl: operator gaya kata adalah numerik, yang simbolik leksikal.)

geekosaurus
sumber
Apakah itu berarti bahwa jika kedua belah pihak bilangan bulat, itu mengkonversi kedua sisi menjadi string dan kemudian membandingkannya?
beatgammit
5
Lebih tepatnya itu sebaliknya: segala sesuatu adalah string, -eqmengatakan bashuntuk menafsirkan string sebagai bilangan bulat (memproduksi 0tanpa peringatan jika string tidak numerik).
geekosaur
11
@jameson Untuk memberikan contoh: [ 01 -eq 1 ]tetapi [ 01 != 1 ].
Gilles 'SO- berhenti bersikap jahat'
3
Perhatikan bahwa sementara ==sebagai [operator adalah non-standar dan tidak boleh digunakan, itu tidak spesifik untuk bash . Ini diperkenalkan oleh ksh dan juga didukung oleh zsh (meskipun yang pertama =perlu dikutip), yash dan [utilitas GNU (dan semua utilitas tersebut diimplementasikan sebagai skrip ksh pada beberapa sistem) setidaknya).
Stéphane Chazelas
@geekosaur Saya mendapatkan peringatan dari bash v4.3.42 jika string saya tidak numerik: $ if [ "hello" -eq 0 ]; then echo true; fi bash: [: hello: ekspresi integer diharapkan
Andrew Bainbridge
13

Untuk menguraikan jawaban bollovan ...

Tidak ada >=atau <=operator perbandingan untuk string. Tapi Anda bisa menggunakannya dengan ((...))perintah aritmatika untuk membandingkan bilangan bulat.

Anda juga dapat menggunakan operator perbandingan string lainnya ( ==, !=, <, >, tapi tidak =) untuk membandingkan bilangan bulat jika Anda menggunakannya dalam ((...)).

Contohnya

  • Keduanya [[ 01 -eq 1 ]]dan (( 01 == 1 ))melakukan perbandingan integer. Keduanya benar.
  • Keduanya [[ 01 == 1 ]]dan [ 01 = 1 ]melakukan perbandingan string. Keduanya salah.
  • Keduanya (( 01 -eq 1 ))dan (( 01 = 1 ))akan mengembalikan kesalahan.

Catatan: Sintaks braket ganda [[...]]dan sintaks kurung ganda ((...))tidak didukung oleh semua shell.

toxalot
sumber
1
Perhatikan bahwa (kecuali untuk mksh/ zsh(kecuali dalam mode POSIX (meskipun itu bukan fitur POSIX)))), (( 010 == 10 ))akan kembali salah karena 010akan diperlakukan sebagai angka oktal (8 dalam desimal).
Stéphane Chazelas
Perhatikan bahwa sementara sebagian besar test/ [implementasi tidak memiliki >=/ <=operator ( yash's [memiliki meskipun), exprmemiliki operator tersebut, meskipun ia akan melakukan perbandingan aritmatika jika argumen diakui sebagai nomor ( expr 01 '>=' 1kembali benar, expr X01 '>=' X1kembali false).
Stéphane Chazelas
7

Jika Anda ingin melakukan perbandingan integer Anda akan lebih baik menggunakan (()), di mana Anda juga dapat menggunakan> = dll.

Contoh:

if (( $UID == 0 )); then
   echo "You are root"
else
   echo "You are not root"
fi
bollovan
sumber
Atau (( UID == 0 ))atau (( ! UID ))untuk hal itu. Catatan yang ((...))tidak standar ( kshfitur juga didukung oleh bashdan zshdengan variasi).
Stéphane Chazelas