DaemonForums  

Go Back   DaemonForums > Miscellaneous > Programming

Programming C, bash, Python, Perl, PHP, Java, you name it.

Reply
 
Thread Tools Display Modes
  #1   (View Single Post)  
Old 29th September 2008
spiderpig spiderpig is offline
Port Guard
 
Join Date: May 2008
Posts: 20
Thanked 0 Times in 0 Posts
Default incrementing within a shell script?

I know that the following:
Code:
#!/bin/sh
i=0
i=$(($i + 1))
echo $i
is the same as the following:
Code:
#!/bin/sh
i=0
i=$(expr $i + 1)
echo $i
My understanding is that a new shell is spawned to execute ($i + 1) or expr $i + 1, but why are the parentheses needed in ($i + 1)? The best answer I can figure is that the statement:
Code:
i=$($i + 1)
is syntactically wrong because somehow $i in the spawned shell is being interpreted as the name of some application which is to be run. Adding the inner set of parentheses somehow forces the shell to treat the argument ($i + 1) as an expression to be evaluated. I had convinced myself that this was a plausible answer for quite some time until I tried it manually at a shell prompt:
Code:
$ i=1
$ echo $i
1
$ sh ($i + 1)
sh: 1: No such file or directory
So why are the inner set of parentheses required in x=$(($i + 1))?

Thanks!
Reply With Quote
  #2   (View Single Post)  
Old 29th September 2008
TerryP's Avatar
TerryP TerryP is offline
Arp Constable
 
Join Date: May 2008
Location: USofA
Posts: 1,547
Thanked 112 Times in 104 Posts
Default

() executes a subshell
$FOO = get replace $FOO with value of FOO, so
$() executes a subshell and replaces $() with value of subshell

The `$' character is used to introduce parameter expansion, command substitution, or arithmetic evaluation.

Thus since (cmds) is like doing sh -c "cmds", $(cmds) has to substitute the value of cmds, hence $(cmds) evaluates to the output of 'cmds'. If $ triggers expansion/substitution, that makes a lot of sense right? To my understanding, in the old days: the only way to do simple arithmetic like was with expr. Then later $((expression)) was added to the language for convenience, and people could stop cursing if they missed a space (e.g. expr 2 +2) and had to retype the entire line again.



I can tell you this, shells/v7sh does not allow the $((expression)) syntax that modern /bin/sh's do. Maybe someone like DrJ could explain the history $(()) and expr, I've only used BSD for ~3 years... So I can't really say a lot that is concrete!
__________________
My Journal

Thou shalt check the array bounds of all strings (indeed, all arrays), for surely where thou typest ``foo'' someone someday shall type ``supercalifragilisticexpialidocious''.

Last edited by TerryP; 29th September 2008 at 06:56 AM. Reason: minor typo fix
Reply With Quote
  #3   (View Single Post)  
Old 29th September 2008
spiderpig spiderpig is offline
Port Guard
 
Join Date: May 2008
Posts: 20
Thanked 0 Times in 0 Posts
Default

Quote:
Originally Posted by TerryP View Post
Then later $((expression)) was added to the language for convenience, ...
You have not addressed how the nested set of parentheses are parsed. This is heart of my question which has not been answered.
Reply With Quote
  #4   (View Single Post)  
Old 29th September 2008
ephemera's Avatar
ephemera ephemera is offline
Knuth's homeboy
 
Join Date: Apr 2008
Posts: 537
Thanked 49 Times in 43 Posts
Default

$(command) does command substitution

$((expression)) does arithmetic expansion

please see the sh(1) man page.

i=5 ; j=$($i + 1) is not syntactically wrong. here the parameter expansion is done for the token $i then the command 5 is run with the arguments + and 1 and its standard o/p is assigned to $j. (obviously, there is no command by the name 5 on the system.)

i=5 ; j=$(($i + 1)) is what you want. arithmetic evaluation of the expression inside $((...)) is performed and the result 6 is assigned to j.

> how the nested set of parentheses are parsed?

observe the o/p of the following commands:

echo $((ls -l))

echo $((ls -l /)) # if you can tell why the error occurs then you have understood it :-)

echo $( (ls -l /)) # note the space used to seperate the tokens $( and (

Last edited by ephemera; 29th September 2008 at 05:07 PM.
Reply With Quote
  #5   (View Single Post)  
Old 29th September 2008
spiderpig spiderpig is offline
Port Guard
 
Join Date: May 2008
Posts: 20
Thanked 0 Times in 0 Posts
Default

Thanks, ephemera for answering my question! Where can this information be found? I haven't seen it anywhere.
Reply With Quote
  #6   (View Single Post)  
Old 29th September 2008
ephemera's Avatar
ephemera ephemera is offline
Knuth's homeboy
 
Join Date: Apr 2008
Posts: 537
Thanked 49 Times in 43 Posts
Default

> Where can this information be found?

its all there in the man page. do check it out.

also i think we are unnecessarly complicating it. its quite simple really: $(...) and $((...)) do two different jobs and there is no connection between them other than a lexical similiarity.
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
shell script with zenity bsdnewbie999 OpenBSD General 5 24th April 2009 02:37 AM
shell script-start another process bsdnewbie999 Programming 2 23rd April 2009 07:48 PM
shell script compare md5 sum bsdnewbie999 Programming 1 11th April 2009 02:20 PM
Shell Script. bsdnewbie999 Programming 21 15th July 2008 07:54 AM
shell script with input c0mrade Programming 5 13th July 2008 04:33 AM


All times are GMT. The time now is 09:09 PM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content copyright © 2007-2010, the authors
Daemon image copyright ©1988, Marshall Kirk McKusick