&& ve || 'in kafa karıştırıcı kullanımı operatörler


93

Bir aracılığıyla Aşırıyordu /etc/rc.d/init.d/sendmaildosyası (bu çok seyrek kullanılan olduğunu biliyorum ama bir sınav için çalışıyorum) ve ben hakkında biraz karışık oldum &&ve ||operatörler. Aşağıdaki ifadelerde nerede kullanılabileceklerini okudum:

if [ test1 ] && [ test2 ]; then
     echo "both tests are true"
elif [ test1 ] || [ test2 ]; then
     echo "one test is true"
fi

Ancak, bu komut dosyası gibi tek satırlı ifadeleri gösterir:

[ -z "$SMQUEUE" ] && SMQUEUE="QUEUE"
[ -f /usr/sbin/sendmail ] || exit 0

Bunlar &&ve ||operatörleri testlere dayanarak verilen yanıtları ortaya çıkarmak için kullanıyor gibi görünüyor , ancak bu operatörlerin bu özel kullanımı ile ilgili belgeleme yapamıyorum. Bunların bu belirli bağlamda ne yaptığını açıklayan var mı?

Yanıtlar:


141

Sağ tarafı &&yalnızca sol tarafın çıkış durumu sıfır ise değerlendirilecektir (yani doğru). ||bunun tersi: Sağ taraf ancak sol taraf çıkış durumu sıfır değilse (yani yanlış) değerlendirilir.

[ ... ]Dönüş değeri olan bir program olarak düşünebilirsiniz . Eğer içindeki test true olarak değerlendirilirse, sıfır döndürür; aksi takdirde sıfır döndürür.

Örnekler:

$ false && echo howdy!

$ true && echo howdy!
howdy!
$ true || echo howdy!

$ false || echo howdy!
howdy!

Ekstra notlar:

Bunu yaparsanız which [, bunun [gerçekten bir programa işaret ettiğini görebilirsiniz ! Aslında, aslında senaryolarda çalışan değil aslında; type [Neyin kaçtığını görmek için kaç. Programı kullanmayı denemek wan ise sadece bu yüzden gibi tam yol vermek: /bin/[ 1 = 1.


6
"X veya Y" yi gördüğünüzde, X'i test edersiniz. Eğer doğruysa, zaten "X veya Y" nin cevabını biliyorsunuzdur (doğru), bu nedenle Y'yi test etmeniz gerekmez. "X veya Y" ye cevap verin, Y'yi test etmeniz gerekir. "X ve Y" yi gördüğünüzde X'i test edersiniz. Yanlışsa, "X ve Y" nin cevabını zaten biliyorsunuzdur (yanlış), yani Y'yi test etmenize gerek yok, eğer X doğruysa, "X ve Y" nin doğru olup olmadığını görmek için Y'yi test etmeniz gerekir.
David Schwartz

2
"Sol taraf sıfıra dönerse" yerine "sol taraf komutunun çıkış durumu sıfırsa" yazardım. Çıkış ve çıkış durumlarının her ikisi de "dönüş değerleri" olarak kabul edilebileceği için "return" 'i biraz belirsiz buluyorum
glenn jackman

Sadece siz "olabilir düşünün [ ... ] o birçok durumda, bir program olarak" olduğunu . Genellikle dosyada /bin/[veya /usr/bin/[.
LS,

5
C programcıları bu kafa karıştırıcı bulacaktır. 0 yanlış demek ... Kabuk yazarken 0 doğru demektir ... Üflemeli.
Calmarius

Söz edebileceğiniz başka biri testyerine ifya [. Ve if [ve if testserpiştirilmiş gibi görünüyor [ve testhiçbir belirgin durup dururken ile. Fedora x86_64'teki satıcı kütüphaneleri için config.sitetest gibi, bazen de ortaya çıkıyor .

59

İşte benim hile sayfam:

  • "A; B" A'nın ardından B'nin, A'nın başarısından bağımsız olarak
  • "A && B" A başarılı olursa B Koşusu
  • "A || B" Eğer A başarısız olursa B çalıştır.
  • "A &" Arka planda A çalıştır.

Çalışma JavaScript’inde gösterilen bazı ilginç lambda matematik paralellikleri var (değişkenleri sırayla tanımlayın); "(aka true) sol": (a => b => a). "Doğru (aka false)": (a => b => b). "A; B" "sonra" (a => b => (() => b())(a())). "A && B" "eğer başkası yoksa (ne zaman)" (a => b => a()(() => right)(b)). "A || B" ", eğer yoksa (olmadıkça)" (a => b => a()(b)(() => right)). "a && b || c" "ifThenElse" (a => b => c => (unless(when(a)(b))(c))()).
Dmitry,

1
bash'da solun analog 0 / boş dize, sağ analogun başka her şey olduğunu unutmayın.
Dmitry

28

@ Shawn-j-Goff'un yukarıdan cevabını genişletmek, &&mantıklı bir AND ve ||mantıklı bir VEYA'dır.

Gelişmiş Bash Komut Dosyası Kılavuzunun bu bölümüne bakın . Aşağıdaki gibi kullanıcı referansı için bağlantı içeriğinden bazıları.

&& VE

if [ $condition1 ] && [ $condition2 ]
#  Same as:  if [ $condition1 -a $condition2 ]
#  Returns true if both condition1 and condition2 hold true...

if [[ $condition1 && $condition2 ]]    # Also works.
#  Note that && operator not permitted inside brackets
#+ of [ ... ] construct.

|| VEYA

if [ $condition1 ] || [ $condition2 ]
# Same as:  if [ $condition1 -o $condition2 ]
# Returns true if either condition1 or condition2 holds true...

if [[ $condition1 || $condition2 ]]    # Also works.
#  Note that || operator not permitted inside brackets
#+ of a [ ... ] construct.

11

Deneyimlerime göre && ve || if ifadesini tek bir satıra indirgemek için.

Diyelim ki /root/Sample.txt adlı bir dosya arıyoruz, sonra geleneksel yineleme aşağıdaki gibi olacaktır:

if [ -f /root/Sample.txt ]
then
    echo "file found"
else
    echo "file not found"
fi

Bu 6 satır tek bir satıra indirgenebilir:

[[ -f /root/Sample.txt ]] && echo "file found" || echo "file not found"

Değişkenleri ayarlamak veya dosyaları oluşturmak için birkaç yinelemeyi çalıştırırken, hayat daha kolaydır ve tek satırlı bir komut dosyası kullanılarak işlev daha kolay görünür, bunun tek dezavantajı tek bir yinelemeden birden fazla komut uygulamak biraz zor hale gelmesidir. fonksiyonları kullanabilirsiniz.


Bu havalı. Bana objc kodunu hatırlatıyor (a == b)? Val = 1: val = 2;
GeneCode

"&" İle arka planda bir işlemi çalıştırmak istediğimde bu komutu nasıl kullanabilirim? Sözdizimi hatası alıyorum./someScript.sh & && echo 'ok' || echo 'ko'
Katie,

4

"Kısa kesim" kavramı var.

Ne zaman (expr1 && expr2)değerlendirilirse - expr2sadece exp1"true" olarak değerlendirilirse değerlendirilir. Bunun sebebi hem expr1AND'in expr2gerçek olması için (expr1 && expr2)doğru olması gerektiğidir. Eğer expr1"false" expr2olarak değerlendirilirse değerlendirilmez (kısa yol), çünkü (expr1 && expr2)zaten "flase".

Aşağıdakini deneyin - dosyanın F1var olduğunu ve dosyanın F2bulunmadığını varsayalım :

( [ -s F1 ] && echo "File Exists" )  # will print "File Exists" - no short cut
( [ -s F2 ] && echo "File Exists" )  # will NOT print "File Exists" - short cut

Benzer şekilde ||(veya) - ancak kısa kesim tersine çevrilir.


5
Mantık genellikle "kısa devre" olarak adlandırılır. Kullanılan "kısa kesim" ibaresini hiç görmedim. Referans bulmakta yardımcı olmak için bundan söz ediyorum.
LS,

-1

Shawn J. Goff'un cevabındaki örnekler doğrudur, ancak açıklama bunun tersidir. Lütfen kontrol edin:

&& nın sağ tarafı, yalnızca sol tarafın çıkış durumu NONZERO ise değerlendirilecektir. || bunun tersi: sol tarafın çıkış durumu SIFIR ise, sağ tarafı değerlendirir.


3
Sen kabukları için farkındayız sıfır çıkış kodu olarak değerlendirilirse gerçek ve böylece sıfırdan farklı sol tarafındaki çıkış kodu &&geri dönmek için bütün ifadede sonuçları yanlış ?
countermode

1
Birisi düzenlemelerinizi onaylamadı çünkü bu sizin cevabınız değildi. Eğer bir cevabın yanlış olduğunu düşünüyorsanız, onu reddetmeli ve muhtemelen yorum bırakmalısınız; Bir değişiklik gerektirdiğini düşünüyorsanız, yorum bırakmalısınız. Düzenlemek, cevabın anlamını değiştirmeyen gramer, format ve yazım hatalarını düzeltmek içindir.
techraf

1
@countermode Üzgünüm, haklısınız, düşündüm ki Linux'da sıfır = yanlış ve sıfır = doğru (C ve diğer birçok dil / ortam / platformda olduğu gibi). Yanlış anlama için özür dilerim.
Try2Help
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.