Theory
n=n+1 સરવાળો કેમ કરતું નથી
Shell માં કિંમતો મૂળભૂત રીતે લખાણ હોય છે. એટલે તમે n=5 લખો અને પછી n=n+1 લખો, તો તમને 6 મળતું નથી, બલ્કે શબ્દશઃ 'n+1' નામની string મળે છે. Shell એ કશું ગણિત કર્યું નહીં, કારણ કે તમે એની માંગણી કરી જ નહોતી.
ખરેખર ગણતરી કરવા માટે તમારે shell નાં ગણિતનાં ઓજારોમાંથી એક વાપરવું પડે. એ બે છે: જૂનો expr command, અને આધુનિક $(( )) રૂપ. આ પાઠ બંને આવરી લે છે, અને એ એક મર્યાદા પણ જે બધાને ચોંકાવે છે: shell નું ગણિત ફક્ત પૂર્ણાંકોમાં જ ચાલે છે.
Theory
ગણતરી કરવાની બે રીત
expr એ જૂનો, બહારનો command છે. તમે expr 7 + 3 લખો છો, અને એ 10 છાપે છે. એને દરેક ભાગની આસપાસ જગ્યા જોઈએ છે, અને * એ wildcard હોવાથી ગુણાકારને \* તરીકે escape કરવો પડે છે, જે કડાકૂટભર્યું છે.
$(( )) એ shell ની અંદર જ બાંધેલું આધુનિક arithmetic expansion છે, અને એ જ પસંદ કરવા જેવું છે. તમે $(( 7 + 3 )) લખો છો અને એ 10 બની જાય છે, કશું escape કરવું પડતું નથી, અને એ સ્વચ્છ વંચાય છે. આંટાઓમાં તમે જોઈ ચૂક્યા છો એ સામાન્ય વધારાનો રૂઢ પ્રયોગ પણ એના પર જ ચાલે છે: i=$((i+1)). નવા scripts માં $(( )) ને પસંદ કરો; જૂના scripts માં expr મળે ત્યારે એને ઓળખી લો.
Practical
બંને રીતે ગણિત (ચકાસાયેલું)
$ 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
ફક્ત પૂર્ણાંક: 7 / 2 એટલે 3, 3.5 નહીં
Shell નું ગણિત ફક્ત પૂર્ણાંકોમાં જ ચાલે છે. એટલે $(( 7 / 2 )) નું પરિણામ 3 આવે છે, 3.5 નહીં, અને દશાંશવાળો ભાગ સીધો ફેંકી દેવાય છે (કપાઈ જાય છે). expr કે $(( )) માં દશાંશ છે જ નહીં.
જો તમને ખરેખર અપૂર્ણાંક જોઈએ (ધારો કે સરેરાશ કે ટકાવારી), તો shell એકલો એ કરી શકતો નથી; તમારે bc જેવું અલગ ઓજાર વાપરવું પડે (echo "scale=2; 7/2" | bc એ 3.50 આપે છે) અથવા awk. આ ભૂલી જવું અને $(( 7 / 2 )) માંથી 3.5 ની આશા રાખવી એ shell માં scripting કરતી વખતે થતાં સૌથી સામાન્ય આશ્ચર્યોમાંનું એક છે.
Quiz
Shell script માં echo $(( 7 / 2 )) શું છાપશે?
- 3.5, એટલે ચોક્કસ ભાગફળ
- 3, કારણ કે shell નું ગણિત ફક્ત પૂર્ણાંકોમાં ચાલે છે અને દશાંશવાળો ભાગ કાપી નાખે છે
- 4, એટલે ઉપર તરફ પૂર્ણાંક કરીને
- ભૂલ, કારણ કે ભાગાકારની છૂટ નથી
Show the answer
3, કારણ કે shell નું ગણિત ફક્ત પૂર્ણાંકોમાં ચાલે છે અને દશાંશવાળો ભાગ કાપી નાખે છે
Shell નું ગણિત ફક્ત પૂર્ણ સંખ્યાઓમાં જ ચાલે છે, એટલે $(( 7 / 2 )) પૂર્ણાંક ભાગફળ ગણે છે અને શેષ ફેંકી દે છે, જેમાંથી 3 મળે છે (3.5 નહીં). વિકલ્પ A દશાંશ હોવાનું માની લે છે, જેને shell નાં $(( )) અને expr ટેકો આપતાં જ નથી. વિકલ્પ C ખોટો છે: એ કાપી નાખે છે (અપૂર્ણાંક પડતો મૂકે છે), ઉપર તરફ પૂર્ણાંક કરતું નથી, એટલે 7/2 એટલે 3, અને 9/2 પણ 4 થાય, 5 નહીં. વિકલ્પ D ખોટો છે: ભાગાકારની પૂરેપૂરી છૂટ છે; ફક્ત એનું પરિણામ પૂર્ણાંક આવે છે. તમને ખરેખરી કિંમત 3.5 જોઈતી હોય તો bc જેવું અપૂર્ણાંક સંભાળતું ઓજાર વાપરવું પડે. સાર આ છે: shell ના ગણિતમાંથી પૂર્ણ સંખ્યાવાળા પરિણામની આશા રાખો, અને અપૂર્ણાંક જોઈએ ત્યારે bc તરફ હાથ લંબાવો.
Think first
Shell નું ગણિત મુદ્દલ ફક્ત પૂર્ણાંકોમાં કેમ છે?
મોટા ભાગની ભાષાઓ દશાંશ સહેલાઈથી સંભાળે છે. તો shell પોતાના અંદરના ગણિતને પૂર્ણ સંખ્યાઓ પૂરતું કેમ મર્યાદિત રાખે છે? વિચારીને પછી tap કરો.
Show the answer
કારણ કે shell નું કામ commands અને files ને ગોઠવવાનું છે, ભારે આંકડાકીય ગણતરીઓ કરવાનું નહીં, એટલે એની અંદરનું ગણિત નાનું અને સાદું રખાયું છે અને scripts ને ખરેખર જોઈતાં પૂર્ણ સંખ્યાવાળાં કામ પૂરતું જ છે. Shell scripts માં થતું લગભગ બધું ગણિત ગણવાનું અને ક્રમાંક આપવાનું જ હોય છે: આંટાની ગણતરી વધારવી, files ગણવી, લીટીનો ક્રમાંક કાઢવો, કેટલા પ્રયત્ન બાકી છે એ તપાસવું, અને એ બધું સ્વાભાવિક રીતે પૂર્ણ સંખ્યાઓ જ છે. Shell ની અંદર જ પૂરેપૂરું અપૂર્ણાંક ગણિત ટેકવવાથી જટિલતા અને ધારની સમસ્યાઓ (ચોકસાઈ, પૂર્ણાંકીકરણ, રજૂઆતનું સ્વરૂપ) ઉમેરાત, અને એ પણ એવી જરૂરિયાત માટે જે shell ની મુખ્ય ભૂમિકામાં ભાગ્યે જ ઊભી થાય છે. એટલે એની રચના કરનારાઓએ એને પૂર્ણાંક પૂરતું જ રાખ્યું અને ગંભીર કે અપૂર્ણાંક ગણિત એવાં ખાસ ઓજારો પર છોડ્યું જે એ કામ પહેલેથી સરસ કરે છે, એટલે કે ગમે તેટલી ચોકસાઈવાળા દશાંશ માટે bc, data પરની ગણતરીઓ માટે awk, અને એથી પણ સમૃદ્ધ કશા માટે Python. તમે વારંવાર મળતી એ જ Unix ની ફિલસૂફી અહીં પણ દેખાય છે: દરેક ઓજાર એક કામ સરસ કરે અને બાકીનું બીજાને સોંપી દે. Shell ગણે છે અને સંકલન કરે છે; તમને ખરેખરી સંખ્યાઓ જોઈએ ત્યારે તમે એ માટે જ બનેલા ગણકયંત્રમાં pipe કરી દો છો. આ સમજ્યા પછી તમે દશાંશ માટે shell સાથે ઝઘડશો નહીં, ખચકાયા વગર bc તરફ હાથ લંબાવશો, અને તમારા scripts સ્વચ્છ રહેશે.
Summary
Key takeaways
- Shell કિંમતોને મૂળભૂત રીતે લખાણ ગણે છે, એટલે n=n+1 સરવાળો કરતું નથી; ગણિતની માંગણી સ્પષ્ટ રીતે કરવી પડે છે.
- expr એ જૂનો બહારનો command છે: expr 7 + 3 એ 10 છાપે છે (જગ્યા જરૂરી છે, અને * ને escape કરવો પડે છે).
- $(( )) એ આધુનિક અને પસંદ કરવા જેવું arithmetic expansion છે: $(( 7 + 3 )) એટલે 10, જે વધુ સ્વચ્છ છે અને shell ની અંદર જ છે.
- આંટામાં વપરાતો વધારાનો રૂઢ પ્રયોગ i=$(( i + 1 )) આ જ વાપરે છે; % શેષ આપે છે ($(( 7 % 2 )) એટલે 1).
- Shell નું ગણિત ફક્ત પૂર્ણાંકોમાં છે: $(( 7 / 2 )) એટલે 3, 3.5 નહીં, અને અપૂર્ણાંક કપાઈ જાય છે.
- ખરેખરી (અપૂર્ણાંક) સંખ્યાઓ માટે bc કે awk જેવું અલગ ઓજાર વાપરો.
- યાદ રાખવાની કડી: પૂર્ણ સંખ્યાના ગણિત માટે $(( )); દશાંશ જોઈએ ત્યારે bc.