expr Parantez gibi gözükmüyor (matematikte operatörün önceliğini açıklamak için kullanılıyor):
expr 3 * (2 + 1)
bash: syntax error near unexpected token `('
Operatör önceliği bash olarak nasıl ifade edilir?
expr Parantez gibi gözükmüyor (matematikte operatörün önceliğini açıklamak için kullanılıyor):
expr 3 * (2 + 1)
bash: syntax error near unexpected token `('
Operatör önceliği bash olarak nasıl ifade edilir?
Yanıtlar:
letBash yerleşikini kullanmanın başka bir yolu :
$ let a="3 * (2 + 1)"
$ printf '%s\n' "$a"
9
Not
As @ Stéphane Chazelas işaret de, bashkullanmanız gereken ((...))üzerinde aritmetik yapmak exprveya letokunabilirlik için.
Taşınabilirlik için, @Bernhard answer$((...)) gibi kullanın .
let. Bundan daha standart veya taşınabilir değildir (( a = 3 * (2 + 1) ))(her ikisi de gelir kshve sadece ksh, bash ve zsh olarak bulunur) ve daha az okunaklı veya alıntı kolaydır. a=$((3 * (2 + 1)))Taşınabilir olmak için kullanın .
((a = 3 * (2 + 1) )), biri taşınabilirlik için a=$((3 * (2 + 1)))), bu yüzden size veya cevabınıza karşı bir not değil, seçili cevap olmasına karşı bir not değil. ve en skorer.
a=1 $[a+2]ya da kullandım a=1 b=2 $[a+b]. Sebepleri bu sözdiziminden sakınmak mı?
Bunun yerine aritmetik genişlemeyi kullanabilirsiniz.
echo "$(( 3 * ( 2 + 1 ) ))"
9
Benim düşünceme göre, bu kullanmaktan daha hoş görünüyor expr.
itibaren man bash
Aritmetik Genişleme Aritmetik genişleme, bir aritmetik ifadenin değerlendirilmesine ve sonucun değiştirilmesine olanak sağlar. Aritmetik genişleme formatı şudur:
$((expression))İfade, çift tırnak içine alınmış gibi ele alınır, ancak parantez içindeki çift tırnak işareti özel olarak ele alınmaz. İfadedeki tüm simgeler, parametre genişletme, dize genişletme, komut değiştirme ve alıntı kaldırma işleminden geçer. Aritmetik genişlemeler iç içe geçmiş olabilir.
Değerlendirme, ARİTMETİK DEĞERLENDİRME altında aşağıda listelenen kurallara göre yapılır. İfade geçersizse bash, başarısızlık olduğunu belirten bir ileti yazdırır ve ikame yapılmaz.
exprModern mermilerde aritmetik kullanmanın bir nedeni yok .
POSIX, $((...))genişletme operatörünü tanımlar . Yani tüm POSIX uyumlu mermilerde kullanabilirsiniz ( shtüm modern Unix severler, çizgi, bash, yash, mksh, zsh, posh, ksh ...).
a=$(( 3 * (2 + 1) ))
a=$((3*(2+1)))
kshAyrıca let, aynı aritmetik ifadenin türünden geçen, bir şeye genişlemeyen ancak ifadenin 0'a dönüp gitmediğine bağlı olarak bir çıkış durumu döndürür expr:
if let 'a = 3 * (2 + 1)'; then
echo "$a is non-zero"
fi
Bununla birlikte, alıntılar garip ve çok okunaklı olmadığından expr(elbette ki aynı ölçüde değil ), alternatif bir form kshda ortaya koydu ((...)):
if (( a = 3 * (2 + 1) )) && (( 3 > 1 )); then
echo "$a is non-zero and 3 > 1"
fi
((a+=2))
çok daha okunaklı olan ve bunun yerine kullanılması gereken.
letve ((...))sunulduğunu ksh, zshve bash. $((...))Sözdizimi diğer kabukları taşınabilirliği gerekli olup olmadığını, tercih edilmelidir exprsadece önceden POSIX Bourne gibi kabuklar (tipik olarak Bourne kabuk veya Almquist kabuğun ilk versiyonları) için gereklidir.
Bourne dışı cephesinde, yerleşik aritmetik işleci olan birkaç kabuk vardır:
csh/ tcsh(aslında yerleşik aritmetik değerlendirmeli ilk Unix kabuğu):
@ a = 3 * (2 + 1)akanga(dayanarak rc)
a = $:'3 * (2 + 1)'Tarihsel bir not olarak, 1989'da usenet'te yayınlanan Almquist kabuğunun orijinal versiyonunun bir yerleşimi vardı expr(aslında birleşti test), ancak daha sonra kaldırıldı.
: $((a = a*2))?
$((...))zsh, ksh93 veya yash gibi kayan noktaları destekleyen bir kabuğa ihtiyacınız olacak .
exprharici bir komuttur, özel bir kabuk sözdizimi değildir. Bu nedenle, exprözel karakterler kabuğu görmek istiyorsanız , bunları alıntı yaparak kabuk ayrıştırmalarına karşı korumanız gerekir. Ayrıca, exprher numaraya ve operatöre ayrı bir parametre olarak geçilmesi gerekir. Böylece:
expr 3 \* \( 2 + 1 \)
1970'lerden veya 1980'lerden kalma bir antik unix sistemi üzerinde çalışmadığınız sürece, kullanmanız için çok az neden vardır expr. Eski günlerde, mermilerin aritmetik işlem yapması için yerleşik bir yolu yoktu ve exprbunun yerine yardımcı programı aramanız gerekiyordu . Tüm POSIX mermileri, aritmetik genişleme sözdizimi ile yerleşik aritmetik özelliklerine sahiptir .
echo "$((3 * (2 + 1)))"
Yapı $((…)), aritmetik ifadenin sonucuna genişler (ondalıkta yazılır). Bash, çoğu kabuk gibi, sadece tamsayı aritmetik modulo 2 64'i (ya da bash'ın eski sürümleri için ve 32-bit makinelerde diğer bazı kabukları için modulo 2 32 ) destekler.
Bash ödevler yapmak veya bir ifadenin 0 olup olmadığını test etmek, ancak sonucu umursamamak istediğinizde ek bir kolaylık sözdizimi sunar . Bu yapı aynı zamanda ksh ve zsh da mevcuttur, fakat düz sh de değildir.
((x = 3 * (2+1)))
echo "$x"
if ((x > 3)); then …
Tamsayı aritmetiğine ek olarak, exprbirkaç dize işleme işlevi sunar. Bunlar da POSIX kabuklarının özellikleri ile kapsanıyor: bunlardan biri hariç: expr STRING : REGEXPdizenin belirtilen regexp ile eşleşip eşleşmediğini test eder. Bir POSIX kabuğu bunu harici araçlar olmadan yapamaz, ancak bash ile yapabilir [[ STRING =~ REGEXP ]]( farklı bir regexp sözdizimi ile - exprklasik bir araçtır ve BRE'yi kullanır, bash ERE'yi kullanır).
20 yıllık sistemlerde çalışan komut dosyalarını sürdürmüyorsanız, bunun exprvarolduğunu bilmenize gerek yoktur . Kabuk aritmetiği kullanın.
expr foo : '\(.\)'ayrıca metin çıkarımı yapar. bash'nin BASH_REMATCHbenzer bir şey başarır. Ayrıca, POSIX'in yapmadığı string karşılaştırması da yapar [( sortbunun için nasıl kullanılacağını hayal edebilmesine rağmen ).
Parantezleri tırnak işaretleri ile kullanın:
expr 3 '*' '(' 2 '+' 1 ')'
9
Tırnaklar bash'ın parantezi bash sözdizimi olarak yorumlamasını önler.
exprkomut satırındaki belirteçlerin boşluklarla ayrılması gerektiğidir; yani; örneğin, expr 3 "*" "(2" "+" "1)" işe yaramayacak . (Ayrıca, BTW, muhtemelen alıntı yapmak gerekmez +.)
whileve [[bunlar sözdizimidir. Anahtar kelimeler olsalardı, komut argümanlarında olduğu gibi yorumlanmayacaktı. Alıntıların ayrıştırmaması, ancak bunun yerine bir string değişkeni görmesi için tırnaklara ihtiyacınız var.