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:
let
Bash 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, bash
kullanmanız gereken ((...))
üzerinde aritmetik yapmak expr
veya let
okunabilirlik 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 ksh
ve 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.
expr
Modern mermilerde aritmetik kullanmanın bir nedeni yok .
POSIX, $((...))
genişletme operatörünü tanımlar . Yani tüm POSIX uyumlu mermilerde kullanabilirsiniz ( sh
tüm modern Unix severler, çizgi, bash, yash, mksh, zsh, posh, ksh ...).
a=$(( 3 * (2 + 1) ))
a=$((3*(2+1)))
ksh
Ayrı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 ksh
da 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.
let
ve ((...))
sunulduğunu ksh
, zsh
ve bash
. $((...))
Sözdizimi diğer kabukları taşınabilirliği gerekli olup olmadığını, tercih edilmelidir expr
sadece ö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 .
expr
harici 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, expr
her 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 expr
bunun 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, expr
birkaç dize işleme işlevi sunar. Bunlar da POSIX kabuklarının özellikleri ile kapsanıyor: bunlardan biri hariç: expr STRING : REGEXP
dizenin 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 - expr
klasik 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 expr
varolduğunu bilmenize gerek yoktur . Kabuk aritmetiği kullanın.
expr foo : '\(.\)'
ayrıca metin çıkarımı yapar. bash
'nin BASH_REMATCH
benzer bir şey başarır. Ayrıca, POSIX'in yapmadığı string karşılaştırması da yapar [
( sort
bunun 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.
expr
komut 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 +
.)
while
ve [[
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.