expr tampaknya tidak menyukai tanda kurung (digunakan dalam matematika untuk prioritas operator eksplisit):
expr 3 * (2 + 1)
bash: syntax error near unexpected token `('
Bagaimana cara mengekspresikan prioritas operator dalam bash?
expr tampaknya tidak menyukai tanda kurung (digunakan dalam matematika untuk prioritas operator eksplisit):
expr 3 * (2 + 1)
bash: syntax error near unexpected token `('
Bagaimana cara mengekspresikan prioritas operator dalam bash?
Jawaban:
Cara lain untuk menggunakan letbash builtin:
$ let a="3 * (2 + 1)"
$ printf '%s\n' "$a"
9
Catatan
Seperti yang ditunjukkan oleh @ Stéphane Chazelas , bashAnda harus menggunakannya ((...))untuk melakukan aritmatika expratau letuntuk keterbacaan.
Untuk portabilitas, gunakan jawaban$((...)) seperti @Bernhard .
let. Ini tidak lebih standar atau portabel daripada (( a = 3 * (2 + 1) ))(keduanya berasal dari kshdan hanya tersedia dalam ksh, bash dan zsh) dan kurang mudah dibaca atau mudah dikutip. Gunakan a=$((3 * (2 + 1)))untuk menjadi portabel.
((a = 3 * (2 + 1) )), satu untuk portabilitas a=$((3 * (2 + 1)))), jadi itu bukan catatan terhadap Anda atau jawaban Anda tetapi menentangnya menjadi jawaban yang dipilih dan pencetak gol terbanyak.
a=1 $[a+2]atau a=1 b=2 $[a+b]. Apakah alasan mereka menghindari sintaksis itu?
Anda dapat menggunakan ekspansi aritmatika saja.
echo "$(( 3 * ( 2 + 1 ) ))"
9
Menurut pendapat pribadi saya, ini terlihat sedikit lebih bagus daripada menggunakan expr.
Dari man bash
Ekspansi Aritmatika Ekspansi aritmatika memungkinkan evaluasi ekspresi aritmatika dan substitusi hasilnya. Format untuk ekspansi aritmatika adalah:
$((expression))Ekspresi diperlakukan seolah-olah itu dalam tanda kutip ganda, tetapi tanda kutip ganda di dalam tanda kurung tidak diperlakukan secara khusus. Semua token dalam ekspresi mengalami ekspansi parameter, ekspansi string, penggantian perintah, dan penghapusan kutipan. Ekspansi aritmatika mungkin bersarang.
Evaluasi dilakukan sesuai dengan aturan yang tercantum di bawah ini di bawah EVALUASI ARITHMETIC. Jika ekspresi tidak valid, bash mencetak pesan yang menunjukkan kegagalan dan tidak ada substitusi yang terjadi.
Tidak ada alasan untuk menggunakan expraritmatika di kulit modern.
POSIX mendefinisikan $((...))operator ekspansi. Jadi Anda dapat menggunakannya di semua shell yang sesuai dengan POSIX (yang paling shdisukai Unix, dash, bash, yash, mksh, zsh, posh, ksh ...).
a=$(( 3 * (2 + 1) ))
a=$((3*(2+1)))
kshjuga memperkenalkan letbuiltin yang dilewatkan dengan jenis ekspresi aritmatika yang sama, tidak berkembang menjadi sesuatu tetapi mengembalikan status keluar berdasarkan apakah ekspresi diselesaikan ke 0 atau tidak, seperti di expr:
if let 'a = 3 * (2 + 1)'; then
echo "$a is non-zero"
fi
Namun, karena kutipan membuatnya canggung dan tidak terlalu terbaca (tidak pada tingkat yang sama seperti exprtentu saja), kshjuga memperkenalkan ((...))bentuk alternatif:
if (( a = 3 * (2 + 1) )) && (( 3 > 1 )); then
echo "$a is non-zero and 3 > 1"
fi
((a+=2))
yang jauh lebih mudah dibaca dan harus digunakan sebagai gantinya.
letdan ((...))hanya tersedia di ksh, zshdan bash. The $((...))sintaks harus disukai jika portabilitas untuk kerang lainnya diperlukan, exprhanya diperlukan untuk kerang pre-POSIX Bourne-seperti (biasanya Bourne shell atau versi awal dari Almquist shell).
Di bagian depan non-Bourne, ada beberapa cangkang dengan operator aritmatika bawaan:
csh/ tcsh(sebenarnya shell Unix pertama dengan built-in evaluasi aritmatika):
@ a = 3 * (2 + 1)akanga(berdasarkan rc)
a = $:'3 * (2 + 1)'sebagai catatan sejarah, versi asli dari shell Almquist, seperti yang diposting di usenet pada tahun 1989 memiliki exprbuiltin (sebenarnya digabung dengan test), tetapi dihapus kemudian.
: $((a = a*2))?
$((...))seperti zsh, ksh93 atau yash.
expradalah perintah eksternal, itu bukan sintaks shell khusus. Oleh karena itu, jika Anda ingin exprmelihat karakter khusus shell, Anda perlu melindungi mereka dari penguraian shell dengan mengutipnya. Selain itu, exprperlu setiap nomor dan operator untuk dilewatkan sebagai parameter terpisah. Jadi:
expr 3 \* \( 2 + 1 \)
Kecuali jika Anda mengerjakan sistem unix antik dari tahun 1970-an atau 1980-an, hanya ada sedikit alasan untuk menggunakannya expr. Di masa lalu, shell tidak memiliki cara bawaan untuk melakukan aritmatika, dan Anda harus memanggil exprutilitas sebagai gantinya. Semua cangkang POSIX memiliki aritmatika bawaan melalui sintaksis ekspansi aritmatika .
echo "$((3 * (2 + 1)))"
Konstruk $((…))memperluas ke hasil ekspresi aritmatika (ditulis dalam desimal). Bash, seperti kebanyakan shell, hanya mendukung bilangan bulat modulo 2 64 (atau modulo 2 32 untuk versi bash yang lebih lama dan beberapa shell lainnya pada mesin 32-bit).
Bash menawarkan sintaks kenyamanan tambahan ketika Anda ingin melakukan tugas atau untuk menguji apakah ekspresi 0 tetapi tidak peduli dengan hasilnya. Konstruk ini juga ada di ksh dan zsh tetapi tidak di sh polos.
((x = 3 * (2+1)))
echo "$x"
if ((x > 3)); then …
Selain aritmatika integer, exprmenawarkan beberapa fungsi manipulasi string. Ini juga digolongkan oleh fitur-fitur shell POSIX, kecuali untuk satu: expr STRING : REGEXPmenguji apakah string cocok dengan regexp yang ditentukan. Shell POSIX tidak dapat melakukan ini tanpa alat eksternal, tetapi bash can dengan [[ STRING =~ REGEXP ]](dengan sintaksis regexp yang berbeda - expradalah alat klasik dan menggunakan BRE, bash menggunakan ERE).
Kecuali jika Anda mengelola skrip yang berjalan pada sistem berusia 20 tahun, Anda tidak perlu tahu itu exprpernah ada. Gunakan aritmatika shell.
expr foo : '\(.\)'juga melakukan ekstraksi teks. bash's BASH_REMATCHmencapai sesuatu yang serupa. Ia juga melakukan perbandingan string, yang POSIX [tidak lakukan (walaupun orang bisa membayangkan cara untuk menggunakannya sort).
Gunakan tanda kurung dengan tanda kutip:
expr 3 '*' '(' 2 '+' 1 ')'
9
Kutipan mencegah bash menafsirkan kurung sebagai sintaks bash.
exprbaris perintah harus dipisahkan oleh spasi; begitu; misalnya, expr 3 "*" "(2" "+" "1)" tidak akan berfungsi . (Juga, BTW, Anda mungkin tidak perlu mengutipnya +.)
whiledan [[, itu adalah sintaks. Jika mereka adalah kata kunci, mereka tidak akan ditafsirkan seperti itu dalam argumen perintah. Anda membutuhkan tanda kutip agar bash tidak menguraikannya tetapi sebaliknya melihat string literal.