Arithmetic Operations (expr, $(( )))

Shell हर चीज़ को text की तरह treat करता है, तो maths करने के लिए आपको explicitly पूछना पड़ता है: पुराना expr command या modern dollar-double-parenthesis form, और दोनों सिर्फ़ whole numbers में काम करते हैं, तो 7 divided by 2, 3.5 नहीं, 3 होता है।

10 min read · 7 cards · 2 checks

Read in: English · हिन्दी · ગુજરાતી


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
2

Watch 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 करता है?

  1. 3.5, exact quotient
  2. 3, क्योंकि shell arithmetic integer only है और fractional part truncate कर देता है
  3. 4, round up करते हुए
  4. एक 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।

Study this properly

This page is the lesson to read. In Gri-Learn the same topic is a graded deck: the self-checks are scored and your weak topics are tracked. Free to start.

Start this topic

Already have an account? Sign in

More from Shell Scripting in Linux

Gri-Learn · syllabus-mapped B.C.A. lessons in English, Hindi and Gujarati

Arithmetic Operations (expr, $(( ))) · Linux Operating System (LOS) (Minor-04) · Gri-Learn