နားလည်ထားရမယ့် အချက်
Bash သည် variable တိုင်းကို default အနေနှင့် string တစ်ခုအဖြစ်သာ သတ်မှတ်ထားသဖြင့်၊ native number type ရှိသော language များတွင်ကဲ့သို့ arithmetic ကို အလိုအလျောက် အလုပ်လုပ်စေမည့်အစား ၎င်းအတွက် own dedicated context တွေ လိုအပ်သည်။ $(( expression )) က arithmetic expression ကို တွက်ချက်ပြီး ရလဒ် number ကို substitute လုပ်ပေးသဖြင့် ၎င်းကို variable တွင် သိမ်းနိုင်သလို $((a + b)) သို့မဟုတ် exponentiation အတွက် $((a ** 2)) ကဲ့သို့ တိုက်ရိုက် print ထုတ်နိုင်သည်။ (( expression )) ကလည်း underlying evaluation အတူတူပင် လုပ်ဆောင်သော်လည်း number ကို စွန့်ပစ်လိုက်ပြီး ရလဒ် nonzero (true) ဖြစ်သလား zero (false) ဖြစ်သလားပေါ်မူတည်၍ command ၏ exit status ကို သတ်မှတ်ပေးသည် — ၎င်းသည် if နှင့် while လိုအပ်သည့် အတိအကျပင်ဖြစ်ပြီး၊ ((a += 5)) ကဲ့သို့ compound assignment shortcut များ variable ကို in place mutate လုပ်နိုင်ခြင်းလည်း ဤနည်းအားဖြင့်ပင် ဖြစ်သည်။ let "b *= 2" ကဲ့သို့ ရှေးဟောင်း let command သည် (( )) ၏ dedicated form ထက် ရှေးကျပြီး ယနေ့တိုင် အလုပ်လုပ်နေသေးသော်လည်း (( )) syntax က ပို၍ ရှင်းလင်းပြီး consistent ဖြစ်သောကြောင့် script အသစ်များတွင် အသုံးပြုမှုနည်းသည်။ beginner များအတွက် ရှုပ်ထွေးဆုံးအချက်မှာ [[ ]] တွင် compare လုပ်နေသည့်အရာပေါ်မူတည်၍ လုံးဝကွဲပြားသော comparison operator family နှစ်ခုကို support လုပ်ခြင်းဖြစ်သည် — number များအတွက် -eq, -ne, -lt, -le, -gt, -ge နှင့် string များအတွက် ==, != — bash သည် family မှားယွင်းစွာ ရွေးချယ်မိလျှင် ဘယ်တော့မှ သတိပေးမည်မဟုတ်ပါ။ ရလဒ်က ရည်ရွယ်ထားသည့်အရာနှင့် ကွာဟနေပါစေ၊ ၎င်းသည် သင်တောင်းဆိုသော comparison — numeric ဖြစ်စေ lexicographic ဖြစ်စေ — ကို ရိုးရှင်းစွာ လုပ်ဆောင်ပေးလိုက်ရုံသာ ဖြစ်သည်။
လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
config file မှ numeric threshold တစ်ခုကို string အဖြစ် ဖတ်ပြီး alert ပို့ရန် ဆုံးဖြတ်ရန်အတွက် failed job count နှင့် နှိုင်းယှဉ်သော script တစ်ခုကို စဉ်းစားကြည့်ပါ — ဤ lesson ၏ code က ဤအမှားကို ဘယ်လောက်လွယ်ကူစွာ ကျူးလွန်နိုင်ကြောင်း အတိအကျ ပြသထားသည်။ x="10" နှင့် y="9" ဖြင့် numeric comparison [[ "$x" -gt "$y" ]] သည် x ပိုကြီးကြောင်း မှန်ကန်စွာ ဖော်ပြသည် — အကြောင်းမှာ -gt က bash ကို operand နှစ်ခုလုံးကို compare မလုပ်မီ integer အဖြစ် interpret လုပ်ရန် တွန်းအားပေးသောကြောင့်ဖြစ်သည်။ သို့သော် string operator > ကိုသုံးသော [[ "$x" > "$y" ]] ကမူ character တစ်ခုချင်းစီအလိုက် နှိုင်းယှဉ်ပေးသည် — character နှစ်ခု၏ ပထမဆုံး character ဖြစ်သော '1' နှင့် '9' ကို ကြည့်ပြီး၊ '1' က lexicographically '9' ထက် ရှေ့ဆုံးမှာ sort ဖြစ်နေသောကြောင့် x ကြီးသည်မဟုတ်ဟု ကောက်ချက်ချလိုက်သည် — numeric အမှန်တရား၏ ဆန့်ကျင်ဘက်ပင်ဖြစ်သည်။ ဤသည်မှာ alert logic ကို တိတ်တဆိတ် ချိုးဖျက်ပစ်သော bug အမျိုးအစားအတိအကျပင်ဖြစ်သည် — 9 ၏ threshold သည် error message တစ်ခုမျှ မပါဘဲ 10 ၏ count ထက် 'ကြီးသည်' ဟု ပေါ်လာနိုင်သည်၊ အကြောင်းမှာ bash ၏ အမြင်တွင် နှစ်ခုလုံးသည် string valid တစ်ခုစီသာ ဖြစ်နေသောကြောင့်ဖြစ်သည်။ ဤ lesson ၏ code သည် if အတွင်း arithmetic evaluate လုပ်ရန် (( a > b )) ကို၊ number များ compare လုပ်နေသည့်အခါတိုင်း [[ ]] အတွင်း -gt ကို သုံးခြင်းဖြင့် ဤပြဿနာကို လုံးဝ ရှောင်ရှားထားသည် — discipline ဆိုသည်မှာ quantity များ compare လုပ်နေသလား text compare လုပ်နေသလား ကိုယ့်ကိုယ်ကို အမြဲမေးပြီး operator family ကို အမှန်ရွေးချယ်ခြင်းဖြစ်သည်၊ အကြောင်းမှာ bash ကိုယ်တိုင်က ထိုအမှားကို ဖမ်းမပေးနိုင်သောကြောင့်ဖြစ်သည်။
အတူတူ စမ်းရေးကြည့်မယ်
#!/bin/bash
a=10
b=3
echo "Sum: $((a + b))"
echo "Quotient: $((a / b))"
echo "Remainder: $((a % b))"
echo "Power: $((a ** 2))"
((a += 5))
echo "a after += 5: $a"
let "b *= 2"
echo "b after *= 2: $b"
if (( a > b )); then
echo "a is numerically greater than b"
fi
x="10"
y="9"
if [[ "$x" -gt "$y" ]]; then
echo "Numeric compare: x is greater than y"
fi
if [[ "$x" > "$y" ]]; then
echo "String compare: x is greater than y"
else
echo "String compare: x is NOT greater than y"
fiဤ script ကို run လိုက်လျှင် အောက်ပါအတိုင်း output ရရှိမည်−
Sum: 13
Quotient: 3
Remainder: 1
Power: 100
a after += 5: 15
b after *= 2: 6
a is numerically greater than b
Numeric compare: x is greater than y
String compare: x is NOT greater than y၅ မိနစ် စမ်းကြည့်
"20" နှင့် "9" ကဲ့သို့ number နှစ်ခုကို string အနေနှင့် သိမ်းဆည်းသော script အသေးလေးတစ်ခု ရေးပါ။ ပထမ number က ဒုတိယ number ထက်ကြီးသလားဆိုတာကို numeric comparison နှင့် string comparison နှစ်မျိုးလုံးသုံးပြီး print ထုတ်ကာ ရလဒ်နှစ်ခု သဘောမတူညီကြောင်း ကြည့်ပါ။
သတိလေးတစ်ချက်
number နှစ်ခုကို နှိုင်းယှဉ်ရန် [[ ]] အတွင်း == ကိုသုံးခြင်း — ၎င်းသည် string comparison အနေနှင့်သာ အလုပ်လုပ်ပြီး "9" နှင့် "10" ကဲ့သို့ digit များစွာပါသော number များအတွက် မှားယွင်းသောအဖြေပေးသည်
valid integer မဟုတ်သော variable တစ်ခုတွင် -eq, -lt စသည်တို့ကို သုံးခြင်း — bash က runtime တွင် 'integer expression expected' error ကို ပြန်ပေးစေသည်
GNU Bash Manual: Shell Arithmetic — Bash / Shell Scripting