Bir bash betiğinde, koşullu “veya” ifadesini “if” ifadesinde kullanma


128

Bu soru benim önceki sorumun bir devamı . Bu sitedeki kullanıcılar nazikçe fordize değerleri üzerinde yinelenen bir bash döngüsünün nasıl yazılacağını belirlememe yardımcı oldu . Örneğin, bir döngü kontrol değişkeninin fnamedizeler üzerinde yinelendiğini varsayalım "a.txt" "b.txt" "c.txt". echo"Evet!" İstiyorum . ne zaman fnamedeğeri "a.txt"ya da "c.txt"ve echo"hayır!" aksi takdirde. Aşağıdaki bash kabuk betiğini denedim:

#!/bin/bash

for fname in "a.txt" "b.txt" "c.txt"
do
 echo $fname
 if [ "$fname" = "a.txt" ] | [ "$fname" = "c.txt" ]; then
 echo "yes!"
else
 echo "no!"
fi
done

Çıktıyı alıyorum:

a.txt

Hayır!

b.txt

Hayır!

c.txt

Evet!

Değer ifgöründüğünde ifadesi neden açıkça görünmüyor ? Yanlış mı kullandım ?fname"a.txt"|


3
Bash'te 'veya' işleci '||' (C tarzı).
Marius Cotofana

3
Ayrıca kullanabilirsiniz -oaynı mesafede [ ].
Thor

6
@Thor tercih ederim ||ve ayrı [ ]üzerinde -oçünkü sadece taşınabilirlik için [fazla 4 argümanları desteklemek için garanti edilmez. Tabii ki hedef dil ise bash, hiç kimse yine de kullanmamalı, [çünkü bash's' [[birçok yönden üstün.
jw013

2
@ jw013 Teşekkürler. Bu benim kullandığım gerektiğini anlamına mı if [[ "$fname" = "a.txt" ]] || [[ "$fname" = "c.txt" ]]ziyade if [ "$fname" = "a.txt" ] || [ "$fname" = "c.txt" ]?
Andrew

5
@Andrew Bu, sizin yaptığınız gibi shebang'ı ilan ettiğiniz gibi doğrudur bash. Bunun bir avantajı, [[kelime bölme yapmamasıdır (özel durum) bu yüzden [[ $unquoted_var = string ]]güvenlidir.
jw013

Yanıtlar:


226

Söylemek istiyorsanız ORçift ​​boru kullanın ( ||).

if [ "$fname" = "a.txt" ] || [ "$fname" = "c.txt" ]

(Kullanılan orijinal OP kodu |, herhangi bir sıradan boru çalışmasında olduğu gibi, sol tarafın çıktısını sağ tarafa doğru çekmekteydi.)


4
Ayrıca, ||standart bir "VEYA" mantığı yapmaz - kısa devre yapar ve ikinci komut yalnızca ilk başarısız olursa çalıştırılır.
holdenweb

13
@holdenweb Modern optimize dillerin çoğunun aynı şekilde çalıştığından eminim. ORİlk koşulu doğru olarak değerlendirirse, ikinci koşulu değerlendirmek için CPU çevrimi harcamanıza gerek yoktur .
bahamat

1
Bash'in beğendiğini düşündüm ==ama bu cevabı gördükten sonra aramaya karar verdim. Görünüşe göre, "kullanılabilir, ancak standart değil". Merak ediyorsanız bunu başkaları için buraya koyacağımı düşündüm: stackoverflow.com/a/2237103
harperville

Bu testadam sayfanın önerdiği de bu
cdosborn

2
Çift dirsek sınamalarını da kullanabilirsiniz - if [[ "$fname" = "a.txt" ]] || [[ "$fname" = "c.txt" ]](Ekstra işlevselliğe sahip olmak istiyorsanız veya bununla ilgili gerekirse [[ ]]).
HankCa
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.