Theory
n=n+1 Add क्यों नहीं करता
Shell में, values default रूप से text होते हैं। तो अगर आप n=5 लिखें और फिर n=n+1, आपको 6 नहीं मिलता, आपको literal string 'n+1' मिलता है। Shell ने कोई arithmetic नहीं किया, क्योंकि आपने इसे नहीं पूछा।
Actually compute करने के लिए, आपको shell के arithmetic tools में से एक इस्तेमाल करना होगा। दो हैं: पुराना expr command, और modern $(( )) form। यह lesson दोनों cover करता है, और वह एक limitation जो हर किसी को surprise करती है: shell arithmetic सिर्फ़ whole numbers में है।
Theory
Compute करने के दो तरीके
expr एक पुराना, external command है। आप expr 7 + 3 लिखते हैं, और यह 10 print करता है। इसे हर part के around spaces चाहिए, और चूँकि * एक wildcard है, आपको multiplication को \* की तरह escape करना पड़ता है, जो fiddly है।
$(( )) shell के अंदर built-in modern arithmetic expansion है, और preferred choice है। आप $(( 7 + 3 )) लिखते हैं और यह 10 बन जाता है, कोई escaping नहीं चाहिए, और यह cleanly पढ़ता है। यह वह common increment idiom भी power करता है जो आपने loops में पहले ही देखा है: i=$((i+1))। नए scripts में $(( )) को prefer कीजिए; इसे पुरानों में मिलने पर expr को पहचानिए।
Practical
दोनों तरीकों से Arithmetic (verified)
$ expr 7 + 3 # older command
10
$ echo $(( 7 + 3 )) # modern, preferred
10
$ echo $(( 7 % 2 )) # modulo (remainder)
1
# The increment idiom used in loops:
$ i=1
$ i=$(( i + 1 ))
$ echo $i
2Watch out
Integer Only: 7 / 2, 3.5 नहीं, 3 है
Shell arithmetic सिर्फ़ whole numbers में काम करता है। तो $(( 7 / 2 )) 3 है, 3.5 नहीं, fractional part को बस फेंक दिया जाता है (truncate)। expr या $(( )) में बिल्कुल कोई decimals नहीं हैं।
अगर आपको genuinely fractions चाहिए (कहिए, एक average या percentage), shell इसे अकेले नहीं कर सकता; आप एक separate tool जैसे bc (echo "scale=2; 7/2" | bc 3.50 देता है) या awk इस्तेमाल करते हैं। इसे भूलना और $(( 7 / 2 )) से 3.5 expect करना shell-scripting की सबसे common surprises में से एक है।
Quiz
एक shell script में, echo $(( 7 / 2 )) क्या print करता है?
- 3.5, exact quotient
- 3, क्योंकि shell arithmetic integer only है और fractional part truncate कर देता है
- 4, round up करते हुए
- एक error, क्योंकि division allowed नहीं है
Show the answer
3, क्योंकि shell arithmetic integer only है और fractional part truncate कर देता है
Shell arithmetic सिर्फ़ whole numbers में काम करता है, तो $(( 7 / 2 )) integer quotient compute करता है और remainder discard कर देता है, 3.5 नहीं 3 देते हुए। Option A decimals assume करता है, जिन्हें shell का $(( )) और expr बिल्कुल support नहीं करते। Option C ग़लत है: यह truncate करता है (fraction drop करता है), round नहीं करता, तो 7/2, 3 है, और यहाँ तक कि 9/2 भी 4 होगा, 5 नहीं। Option D ग़लत है: division बिल्कुल allowed है; यह बस एक integer result देता है। अगर आपको real value 3.5 चाहिए, आपको bc जैसा एक floating-point tool इस्तेमाल करना होगा। Takeaway: shell maths से whole-number results expect कीजिए, और fractions चाहिए होने पर bc की तरफ़ reach कीजिए।
Think first
Shell Arithmetic पहली जगह में Integer-Only क्यों है?
ज़्यादातर languages decimals आसानी से handle करती हैं। Shell अपनी built-in maths को whole numbers तक क्यों restrict करता है? फिर tap कीजिए।
Show the answer
क्योंकि shell का job commands और files को orchestrate करना है, heavy number-crunching नहीं, तो इसका built-in arithmetic छोटा और simple रखा गया है, उन whole-number tasks को cover करते हुए जो scripts actually चाहती हैं। Shell scripts में लगभग सारी arithmetic counting और indexing है: एक loop counter increment करना, files count करना, एक line number compute करना, कितने attempts बचे हैं check करना, और ये naturally whole numbers हैं। Shell के अंदर full floating-point maths support करना उस need के लिए complexity और edge cases (precision, rounding, formatting) add करेगा जो shell के core role में शायद ही कभी arise होती है। तो designers ने इसे integer-only रखा और serious या fractional maths को specialised tools के लिए छोड़ दिया जो इसे पहले से अच्छी तरह करते हैं, arbitrary-precision decimals के लिए bc, data पर calculations के लिए awk, richer किसी भी चीज़ के लिए Python। यह same Unix philosophy reflect करता है जिसे आप बार-बार मिलते हैं: हर tool एक चीज़ अच्छी तरह करता है और बाकी hand off कर देता है। Shell count और coordinate करता है; जब आपको real numbers चाहिए, आप उनके लिए built एक calculator को pipe करते हैं। यह जानते हुए, आप decimals के लिए shell से नहीं लड़ेंगे, आप बिना hesitation bc की तरफ़ reach करेंगे, और आपकी scripts clean रहेंगी।
Summary
Key takeaways
- Shell default रूप से values को text की तरह treat करता है, तो n=n+1 add नहीं करता; आपको explicitly arithmetic पूछना पड़ता है।
- expr पुराना external command है: expr 7 + 3, 10 print करता है (spaces चाहिए, * escape होना चाहिए)।
- $(( )) modern, preferred arithmetic expansion है: $(( 7 + 3 )), 10 है, cleaner और built in।
- Loop increment idiom i=$(( i + 1 )) इसी को इस्तेमाल करता है; % remainder देता है ($(( 7 % 2 )), 1 है)।
- Shell arithmetic integer only है: $(( 7 / 2 )), 3.5 नहीं, 3 है, fraction truncate हो जाता है।
- Real (fractional) numbers के लिए, bc या awk जैसा एक separate tool इस्तेमाल कीजिए।
- Memory hook: whole-number maths के लिए $(( )); decimals चाहिए होने पर bc।