Kabuk karşılaştırmalarında tek ve çift eşit işaretler (=) arasındaki fark nedir?


28

Bunun içindeki telleri karşılaştırmak ifiçin çift köşeli parantez kullanmamız gerektiğini okuyun . Bazı kitaplar karşılaştırmanın yapılabileceğini söylüyor =. Ama aynı zamanda da çalışıyor ==.

#!/bin/bash
a="hello"
b="world"
if [[ $a == $b ]];then
    echo "equal"
fi

Karşılaştırma arasında =ve ==arasında bir fark var mı ?


4
Burada bir yerde bir soru var mı? Eğer öyleyse, göremiyorum. =içindir [. ==içindir [[.
Chris Down,

@ChrisDown Bu kesinlikle doğru değil.
xdavidliu

@xdavidliu Detaylandırmak ister misiniz? Kesinlikle olduğu hiçbir anlayışa sahip POSIX'e göre gerçek ==kullanıyor olmalıdır yüzden, =ile (eşitlik) [ve ==ile (alıntı farkında olan semantik ile, desen eşleştirme) [[. Bkz help testvs help [[.
Chris Down

@ChrisDown belki "ne anlama geldiğini" yanlış anlıyorum. Eğer "için", "sadece işe yarar" anlamına gelirse, yorum [ foo == foo ] && echo fookesinlikle doğru olmaz, çünkü kesinlikle foobunun ==işe yaradığını gösterir [. Bununla birlikte, "ile" demek istiyorsan "ile kullanılması amaçlandıysa", o zaman itirazım daha az olur.
xdavidliu

@ xdavidliu "içindir" demek istediğin durumda "POSIX tarafından tanımlanır". Neyse taşınabilirliği eschewing eğer, sadece kullanmak - bash kolaylık olarak kabul etmek olur Çünkü, tavsiye anlamına gelmez [[tokenisation, kelime bölme, önemli ölçüde daha nüanslı bir anlayış vardır ilk etapta vb ...
Chris Down

Yanıtlar:


28

[[ $a == $b ]]karşılaştırma değil, kalıp eşleştirme. [[ $a == "$b" ]]Bayt-bayt eşitliği karşılaştırması yapmanız gerekir . (tarafından sunulan ) destekleyen herhangi bir kabuktaki ile =aynıdır .==[[...]]ksh

[[...]]standart shsözdizimi değil . [ Komut standarttır ve standart karşılaştırma operatörü yoktur =(bazı olsa [uygulamaları da tanımak ==).

Herhangi bir komutun herhangi bir tartışmasında olduğu gibi, değişkenlerin alıntılanması gerekir, yani:

[ "$a" = "$b" ]

Standart olarak sh, desen eşleştirmesi şu şekilde yapılır case:

case $a in
  ($b) ...
esac

Bütünlüğü sağlamak için, kabuk komut dosyalarında rastlayabileceğiniz eşitlik benzeri diğer operatörler:

  • [ "$a" -eq "$b" ]: [ondalık sayıyı karşılaştırmak için standart operatör. Bazı [uygulamalar sayılar etrafındaki boşluklara izin verirken, bazıları rastgele aritmetik ifadelere izin verir, ancak bu taşınabilir değildir. Portably, bunun için biri kullanabilirsiniz [ "$((a))" -eq "$((b))" ]. Ayrıca [ "$((a == b))" -ne 0 ]hangi standart eşdeğer olacağını da bakın (POSIXly dışında, davranış yalnızca tamsayı sabitleri içeriyorsa $ave belirtilirse $b):
  • ((a == b)), ksh'dan ve ayrıca zshve içinde bulunur bash, içinde depolanan aritmetik ifadenin değerlendirmesi ile $aaynı sayıyı verirse true değerini döndürür $b. Genelde sayıları karşılaştırmak için kullanılır. Aritmetik ifadelerin nasıl değerlendirildiğine ve hangi sayıların desteklendiğine (mesela bash ve ksh'nın bazı uygulama / sürümlerinin kayan noktaları desteklemediğini veya sayıları sekizlik olarak kabul edersiniz) arasında kabuklar arasında farklılıklar olduğunu unutmayın.

  • expr "$a" = "$b"Her iki işlenen de ondalık tam sayı olarak tanınırsa (bazıları sayının etrafında boşluklara izin verir) sayı karşılaştırması yapar, aksi halde iki dize işlecinin aynı sıralama düzenine sahip olup olmadığını denetler. Ayrıca değerleri için başarısız olur $aveya $bolan exproperatörler gibi (, substr...

  • awk 'BEGIN{exit !(ARGV[1] == ARGV[2])}' "$a" "$b": $ave eğer $bsayılar olarak tanınırlarsa (en azından ondalık tam sayı ve 1.2, -1.5e-4 gibi kayan nokta sayıları, öndeki boşluklar yok sayılır, bazıları onaltılık, sekizli veya tarafından tanınan herhangi bir şeyi tanır strtod()), sonra sayısal bir karşılaştırma yapılır. Aksi takdirde, uygulama bağlı olarak, ya bir bayt to-byte dize karşılaştırması, ya yönelik benzeri exprbir strcoll()karşılaştırma, bu olup olmadığıdır $ave $bsıralama aynı.

Ayrıca bakınız:


13

Bunlar bash eşdeğeridir:

[[ $x == "$y" ]]
[[ $x = "$y" ]]
[ "$x" == "$y" ]
[ "$x" = "$y" ]

İlk iki $ x değişkeninin alıntılanması gerekmez. Bash, içinde sözcük bölme ve dosya adı genişletme işlemini gerçekleştirir [ancak içinde değil [[:

$ x='a b'
$ [ -s $x ]
-bash: [: a: binary operator expected
$ [[ -s $x ]]
$ ls
$ [ a = * ]
-bash: [: a: unary operator expected
$ [[ a = * ]]
$ 

[[ $x = "$y" ]]dize karşılaştırmasıdır ancak [[ $x = $y ]]örüntü eşleme ifadesidir:

$ y='a*'; [[ aa = "$y" ]]; echo $?
1
$ y='a*'; [[ aa = $y ]]; echo $?
0

-eq sadece tamsayılarla kullanılmalıdır:

$ [[ x.x -eq x.x ]]
-bash: [[: x.x: syntax error: invalid arithmetic operator (error token is ".x")
$ x=9; [[ "x" -eq 9 ]]; echo $?
0

Ayrıca bakınız BashFAQ / 031: Test, [ve [[?] Arasındaki fark nedir? .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.