Bash অ্যারিথমেটিক করতে পারে, তবে শুধু ইন্টিজার দিয়ে। যদি ফ্লোটিং-পয়েন্ট গণিত করতে হয়, তাহলে বাইরের কোনো প্রোগ্রামের সাহায্য নিতে হবে (যেমন awk বা bc)।
অ্যারিথমেটিক অপারেটরগুলো ম্যানুয়ালে (প্রাধান্যের ক্রম অনুসারে) তালিকাভুক্ত আছে: শেল অ্যারিথমেটিক।
এর বাইরে, Bash কেবল কিছু নির্দিষ্ট জায়গাতেই অ্যারিথমেটিক করে (এগুলোকে অ্যারিথমেটিক "কনটেক্সট" বলা হয়)।
অ্যারিথমেটিক এক্সপ্যানশন দেখতে কমান্ড সাবস্টিটিউশন-এর মতো, তবে এখানে দ্বিগুণ বন্ধনী ব্যবহৃত হয়।
$(( expression ))
এই সিনট্যাক্সটি এক্সপ্রেশনটির মূল্যায়নের ফলাফলে প্রসারিত হয়। ফলাফলটি একটি ভ্যারিয়েবলে রেখে দিতে এটি সাধারণত ব্যবহৃত হয়:
x=$(( 3 + 4 ))
বন্ধনীর ভেতরে কতটা হোয়াইটস্পেস থাকবে সেটি আপনার ইচ্ছা। এটি স্টাইল ও পড়ার সুবিধার বিষয়।
x=$(( 3 + 4 ))
y=$((5+6))
আপনার বন্ধুত্বপূর্ণ লেখক বন্ধনীর ভেতরে অ্যারিথমেটিক এক্সপ্রেশনটি যেন বেশি দৃশ্যমান হয়, সেজন্য স্পেস যোগ করতে ভালোবাসেন।
অ্যারিথমেটিক কন্ডিশনাল দ্বিগুণ বন্ধনীর ভেতরে করা হয়, শুরুর $ ছাড়াই:
(( expression ))
এটি ফলাফলে প্রসারিত হয় না। তবে এটি একটি এক্সিট স্টেটাস তৈরি করে।
((-এর ভেতরে Bash, C ভাষার মতোই ট্রু/ফলসের একই অর্থ ব্যবহার করে: শূন্য মানে ফলস, শূন্য নয় মানে ট্রু।
Bash যেভাবে এক্সিট স্টেটাস মূল্যায়ন করে, এটি তার ঠিক উল্টো!
এই সিনট্যাক্সটি সাধারণত দুটি জায়গায় ব্যবহৃত হয়:
একটি if স্টেটমেন্ট বা একটি while লুপ-এর COMMAND অংশ হিসেবে।
if (( x == y - 1 )); then ...
while (( y > 0 )); do ...
একটি ভ্যারিয়েবলের মান বদলাতে স্বতন্ত্র কমান্ড হিসেবে।
(( x = x + 1 ))
echo "new value for x is $x"
set -e-এর সাথে মিলিয়ে এভাবে অ্যারিথমেটিক ব্যবহারে সাবধান থাকুন।
এক্সপ্রেশনটির ফলাফল শূন্য হলে এক্সিট স্টেটাস অশূন্য হবে এবং Bash বন্ধ হয়ে যাবে।
x=0
(( x++ ))
echo "you will see this"
set -e
x=0
(( x++ ))
echo "shell exits on the previous line; you won't see this"
++ অপারেটর নিয়ে আরও বিশদ আলোচনার জন্য Postincrement vs Preincrement প্রবন্ধটি দেখুন।
আরও কয়েকটি জায়গা আছে যেগুলো অ্যারিথমেটিক কনটেক্সট:
for (( i = 0; i < 10; i++ )); do
echo "$i"
done
সাংখ্যিক ইনডেক্সযুক্ত অ্যারের ইনডেক্স অংশ।
echo "The next element is ${array[x + 1]}"
# ................................^^^^^
অ্যারে নিয়ে আরও জানতে অ্যারে কনসেপ্ট ডকুমেন্টটি পড়ুন।
${var:offset:length} এক্সপ্যানশনের অফসেট ও দৈর্ঘ্য অংশ।
let "expresson" লিখার চেয়ে (( expression )) ব্যবহার করাই বেশি পছন্দনীয়।
অ্যারিথমেটিক কন্ডিশনাল গঠনটির মতো নয়, let এক্সপ্রেশন ফাইলনেম-এক্সপ্যানশন ও ওয়ার্ড-স্প্লিটিংয়ের অধীন, আর এতে কোটেশন দিতে হয়।ভ্যারিয়েবল অ্যাসাইনমেন্ট, যখন ভ্যারিয়েবলটির "ইন্টিজার অ্যাট্রিবিউট" থাকে।
# variable x does not have the integer attribute
x="3 + 4"
declare -p x # => declare -- x="3 + 4"
# variable y has the integer attribute
declare -i y
y="4 + 5"
declare -p y # => declare -i y="9"
লেখকের মতামত হলো, declare -i-এর ব্যবহার সীমিত।
এর মূল সুবিধা হলো "বেয়ার" অ্যারিথমেটিক (অ্যারিথমেটিক এক্সপ্রেশন সিনট্যাক্স ছাড়া) করা যায়।
এটি আপনার কোড পড়া লোকের বিভ্রান্তির কারণ হতে পারে, কারণ অ্যারিথমেটিক এক্সপ্রেশন প্রত্যাশিত নয় এমন জায়গায় মূল্যায়িত হয়।
অ্যারিথমেটিক কনটেক্সটের একটি দিক আছে যা পড়ার সুবিধা বাড়ায়।
height=10
width=20
area=$(( height * width ))
লক্ষ্য করেছেন কি, অ্যারিথমেটিক এক্সপ্রেশনে ভ্যারিয়েবলগুলোর আগে $ ডলার চিহ্ন নেই?
Bash আপনাকে এটা করতে দেয়।
এতে এক্সপ্রেশনগুলো অনেক সহজে পড়া যায়।
ম্যানুয়ালে বলা হয়েছে,
একটি এক্সপ্রেশনের ভেতরে শেল ভ্যারিয়েবলকে প্যারামিটার এক্সপ্যানশন সিনট্যাক্স ব্যবহার না করেই নাম দিয়ে উল্লেখ করা যায়।
এটি অ্যারের এলিমেন্টের ক্ষেত্রেও কাজ করে:
point1=(10 15) # these are (x, y) coordinates
point2=(20 7)
distance_squared=$(( (point1[0] - point2[0])**2 + (point1[1] - point2[1])**2 ))
কিন্তু অন্য প্যারামিটার এক্সপ্রেশনগুলোকে তাদের বিশেষ সিনট্যাক্স ব্যবহার করতে হয়। উদাহরণস্বরূপ, একটি স্ট্রিংয়ের দৈর্ঘ্য দ্বিগুণ করা:
s="hello world"
len=$(( ${#s} * 2 ))
আর পজিশনাল প্যারামিটারগুলোও তাই করতে হবে। যদি প্রথম দুটি পজিশনাল প্যারামিটার প্রস্থ ও উচ্চতা বোঝায়:
area=$(( $1 * $2 ))