&&
Ve ||
operatörler vardır değil if-then-else için satır içi değiştirmeler kesin. Dikkatli kullanılsalar da aynı şeyi başarabilirler.
Tek bir test basit ve açıktır ...
[[ A == A ]] && echo TRUE # TRUE
[[ A == B ]] && echo TRUE #
[[ A == A ]] || echo FALSE #
[[ A == B ]] || echo FALSE # FALSE
Ancak, birden çok test eklemeye çalışmak beklenmedik sonuçlar doğurabilir ...
[[ A == A ]] && echo TRUE || echo FALSE # TRUE (as expected)
[[ A == B ]] && echo TRUE || echo FALSE # FALSE (as expected)
[[ A == A ]] || echo FALSE && echo TRUE # TRUE (as expected)
[[ A == B ]] || echo FALSE && echo TRUE # FALSE TRUE (huh?)
Neden YANLIŞ hem edilir ve DOĞRU yankılandı?
Burada oluyor biz fark ettik ki &&
ve ||
koşullu sınama ayraç içindeki farklı hareket operatörleri aşırı yüklü [[ ]]
onlar AND yapmak ve OR (koşullu yürütme) liste burada var daha.
Bash manpage'den (düzenlenmiş) ...
Listeler
Bir liste, operatörlerden biri tarafından ayrılan bir veya daha fazla boru hattının bir dizisidir;, &, && veya option ve isteğe bağlı olarak;, &, veya. Bu listeden operatörler, && ve ││ eşit önceliğe sahiptir; ve &, eşit önceliğe sahip.
Komutları sınırlandırmak için noktalı virgül yerine bir veya daha fazla yeni satır dizisi bir listede görünebilir.
Bir komut kontrol operatörü & tarafından sonlandırılırsa, kabuk komutu bir alt kabukta arka planda yürütür. Kabuk komutun bitmesini beklemez ve dönüş durumu 0'dır. Komutlar a; sırayla yürütülür; kabuk, her komutun sırayla sonlandırılmasını bekler. Dönüş durumu, yürütülen son komutun çıkış durumudur.
AND ve VEYA listeleri, sırasıyla && ve ││ kontrol operatörleri tarafından ayrılan daha fazla boru hattından birinin sekanslarıdır. AND ve VEYA listeleri sol ilişkilendirmeyle yürütülür.
Bir AND listesi var ...
command1 && command2
Command2, eğer komut1 ise sıfır çıkış durumunu döndürürse çalıştırılır.
Bir OR listesi var ...
command1 ││ command2
Command2, eğer sadece command1 sıfır olmayan bir çıkış durumu verirse çalıştırılır.
AND ve OR listelerinin dönüş durumu, listedeki son komutun çıkış durumudur.
Son örneğimize dönersek ...
[[ A == B ]] || echo FALSE && echo TRUE
[[ A == B ]] is false
|| Does NOT mean OR! It means...
'execute next command if last command return code(rc) was false'
echo FALSE The 'echo' command rc is always true
(i.e. it successfully echoed the word "FALSE")
&& Execute next command if last command rc was true
echo TRUE Since the 'echo FALSE' rc was true, then echo "TRUE"
Tamam. Eğer bu doğruysa, son örneğin yanındaki niçin bir şey yansıtıyor?
[[ A == A ]] || echo FALSE && echo TRUE
[[ A == A ]] is true
|| execute next command if last command rc was false.
echo FALSE Since last rc was true, shouldn't it have stopped before this?
Nope. Instead, it skips the 'echo FALSE', does not even try to
execute it, and continues looking for a `&&` clause.
&& ... which it finds here
echo TRUE ... so, since `[[ A == A ]]` is true, then it echos "TRUE"
Birden fazla &&
veya ||
bir komut listesinde kullanılırken mantık hata riski oldukça yüksektir.
öneriler
Bir tek &&
veya ||
bir komut listesinde beklendiği gibi çalışır, bu yüzden oldukça güvenlidir. Başka bir maddeye gerek duymadığınız bir durumsa, aşağıdaki gibi bir şeyin izlenmesi daha açık olabilir (küme parantezlerinin son 2 komutu gruplaması gerekir) ...
[[ $1 == --help ]] && { echo "$HELP"; exit; }
Birincisi &&
ve ||
sonuncusu hariç her komutun bir test olduğu operatörler (örneğin [[ ]]
, parantezlerin içi ), son operatörün beklendiği gibi davranması dışında genellikle aynı şekilde güvenlidir. Son operatör daha çok a then
veya else
cümle gibi davranır .
&&
ve||
kabuk operatörlericmd1 && cmd2 || cmd3
aynı önceliğe sahipken,&&
giriş((...))
ve çıkış[[...]]
önceliği||
(((a || b && c))
is((a || (b && c)))
). Aynı şey-a
/-o
intest
/[
andfind
ve&
/|
in için de geçerlidirexpr
.