LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-19-2011, 08:28 PM   #1
jack_green
Member
 
Registered: Jul 2011
Posts: 73

Rep: Reputation: Disabled
shell script needs help


hello, guys. i am new to linux shell script. i have a problem about math scripting. how to write a shell script " 1x1+2x2+3x3+...+100x100= " . and can i use shift command in shell script to have this "1+3+5+7+...+99" work?

thanks for any help
 
Old 11-19-2011, 10:41 PM   #2
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
There are many shells; which one are you using? Why would you want to use shift for this?

Shells are usually limited to integer math. For example, Bash can do
Code:
sum=0; for (( i=1; i<=100; i++ )); do sum=$((sum + i*i)) ; done ; echo $sum
and
Code:
sum=0; for (( i=1; i<=100; i+=2 )); do sum=$((sum + i)) ; done ; echo $sum
In general, it is better to use something like awk or bc to do the math instead. In this case, bc is the most suitable candidate, as it is an arbitrary-precision programmable calculator. For example, try
Code:
echo 'sum=0; for (i=1; i<=100; i++) sum += i*i; print sum, "\n"' | bc
and
Code:
echo 'sum=0; for (i=1; i<=100; i+=2) sum += i; print sum, "\n"' | bc
See man 1 bc for details.
 
Old 11-19-2011, 10:52 PM   #3
jack_green
Member
 
Registered: Jul 2011
Posts: 73

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by Nominal Animal View Post
There are many shells; which one are you using? Why would you want to use shift for this?

Shells are usually limited to integer math. For example, Bash can do
Code:
sum=0; for (( i=1; i<=100; i++ )); do sum=$((sum + i*i)) ; done ; echo $sum
and
Code:
sum=0; for (( i=1; i<=100; i+=2 )); do sum=$((sum + i)) ; done ; echo $sum
In general, it is better to use something like awk or bc to do the math instead. In this case, bc is the most suitable candidate, as it is an arbitrary-precision programmable calculator. For example, try
Code:
echo 'sum=0; for (i=1; i<=100; i++) sum += i*i; print sum, "\n"' | bc
and
Code:
echo 'sum=0; for (i=1; i<=100; i+=2) sum += i; print sum, "\n"' | bc
See man 1 bc for details.


thanks so much. i use bash shell as my default shell. i just wanna know more about linux shell scripts. but you did not answer my second question : could i use shift command on this test ?

Last edited by jack_green; 11-19-2011 at 10:54 PM.
 
Old 11-19-2011, 11:59 PM   #4
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
Yes, there is a way you can calculate the sums in a way that utilizes the shift built-in. It involves a function (or a separate script if the shell does not support functions -- Bash does), which sums its arguments (or squares of its arguments), and echoes the results.

shift is useful in looping over all arguments in a while loop, although one could use a for loop over the arguments as well.

To get the result, you would need to call the function with all summands as arguments, but the seq utility is useful for that.

The solution using shift is almost a dozen lines of Bash. I cannot imagine why you would want to do it that way -- unless this is homework.

Is this homework?
 
Old 11-20-2011, 12:26 AM   #5
jack_green
Member
 
Registered: Jul 2011
Posts: 73

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by Nominal Animal View Post
Yes, there is a way you can calculate the sums in a way that utilizes the shift built-in. It involves a function (or a separate script if the shell does not support functions -- Bash does), which sums its arguments (or squares of its arguments), and echoes the results.

shift is useful in looping over all arguments in a while loop, although one could use a for loop over the arguments as well.

To get the result, you would need to call the function with all summands as arguments, but the seq utility is useful for that.

The solution using shift is almost a dozen lines of Bash. I cannot imagine why you would want to do it that way -- unless this is homework.

Is this homework?

sorry, it's not my homework . i just happened to heard that shift can use for looping , but i don't understand how to use it.
it said that VAR=1,VAR=2,VAR=3... after "shift", it should be VAR1=2,VAR2=3..... but how to use the position parameter for looping . i am a totally shell script beginner.
 
Old 11-20-2011, 01:23 AM   #6
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
Consider this Bash code:
Code:
sumargs () {
    local sum=0
    while [ $# -gt 0 ]; do
        sum=$(( sum + $1 ))
        shift 1
    done
    echo $sum
}

sqrargs () {
    local sum=0
    while [ $# -gt 0 ]; do
        sum=$(( sum + $1 * $1 ))
        shift 1
    done
    echo $sum
}

sqrargs $(seq 1 100)

sumargs $(seq 1 2 100)
$# evaluates the number of positional parameters -- command-line parameters to a script, or parameters if in a function. First one is $1, second $2 and so on. shift N will discard the first N parameters, and rename the leftovers starting from one ($1). It only works for positional parameters, not for variables in general.

The while loops above can be read as "as long as there are more than zero positional parameters, do ..., then discard the first positional parameter shifting the rest one place down." This results in $1 cycling through each parameter given to the function.

seq first last would output each integer number from first to last, inclusive.
seq first step last outputs first , first+step , first+step+step , and so on, up to and including last.

The $(...) is equivalent to backticks, and evaluates to the output of ... . Thus, the output from the seq is given to the function as positional parameters.

While Bash functions can return a number, it is limited to a very small range, usually between 0 and 255, inclusive, with 0 meaning success/true, and all others failure/false. (Nonzero values always indicate an error code, although the meaning of each code tends to be program-specific. There are lists and conventions, but nothing universal.)

Therefore the function really needs to output the result. I used echo. If I wanted to format the output, I'd use for example printf '%d\n' $sum instead.
 
1 members found this post helpful.
Old 11-20-2011, 08:08 AM   #7
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
To provide (hopefully) a clear and simple explanation:

Every command you enter consists of the command-name and zero or more arguments following it.

In shell scripting, the name of the command itself is stored in the special parameter $0, and the arguments following it in $1, $2, $3, etc.

The shift built-in command simply moves the contents of the parameters down the list. When executed, the contents of $1 are deleted and $2 moves over to become $1, $3 becomes $2, etc. ($0 remains unaffected). A number can also optionally be given so that it shifts multiple steps at once.

So depending on what you want to do, it is possible to use shift as a kind of looping device, but it's far from the most usual option, as it's both limited and destructive to your data. Your shell provides much better ways to iterate through multiple inputs.

Here are a few useful bash scripting references for you to study. I particularly recommend the first as a good introduction into the basics:

http://mywiki.wooledge.org/BashGuide
http://www.linuxcommand.org/index.php
http://mywiki.wooledge.org/BashFAQ
http://mywiki.wooledge.org/BashPitfalls
http://tldp.org/LDP/Bash-Beginners-G...tml/index.html
http://www.tldp.org/LDP/abs/html/index.html
http://www.gnu.org/software/bash/manual/bashref.html
http://wiki.bash-hackers.org/start
 
Old 11-20-2011, 06:36 PM   #8
jack_green
Member
 
Registered: Jul 2011
Posts: 73

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by Nominal Animal View Post
Consider this Bash code:
Code:
sumargs () {
    local sum=0
    while [ $# -gt 0 ]; do
        sum=$(( sum + $1 ))
        shift 1
    done
    echo $sum
}

sqrargs () {
    local sum=0
    while [ $# -gt 0 ]; do
        sum=$(( sum + $1 * $1 ))
        shift 1
    done
    echo $sum
}

sqrargs $(seq 1 100)

sumargs $(seq 1 2 100)
$# evaluates the number of positional parameters -- command-line parameters to a script, or parameters if in a function. First one is $1, second $2 and so on. shift N will discard the first N parameters, and rename the leftovers starting from one ($1). It only works for positional parameters, not for variables in general.

The while loops above can be read as "as long as there are more than zero positional parameters, do ..., then discard the first positional parameter shifting the rest one place down." This results in $1 cycling through each parameter given to the function.

seq first last would output each integer number from first to last, inclusive.
seq first step last outputs first , first+step , first+step+step , and so on, up to and including last.

The $(...) is equivalent to backticks, and evaluates to the output of ... . Thus, the output from the seq is given to the function as positional parameters.

While Bash functions can return a number, it is limited to a very small range, usually between 0 and 255, inclusive, with 0 meaning success/true, and all others failure/false. (Nonzero values always indicate an error code, although the meaning of each code tends to be program-specific. There are lists and conventions, but nothing universal.)

Therefore the function really needs to output the result. I used echo. If I wanted to format the output, I'd use for example printf '%d\n' $sum instead.


thanks so much.
 
  


Reply



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 Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Shell Script running in another shell script and then exit dreamervlk Linux - General 3 09-16-2011 06:40 AM
Executing a Shell script with 654 permissions inside another shell script. changusee2k Linux - Newbie 2 06-07-2011 07:58 PM
help with execute mulitple shell script within shell script ufmale Programming 6 09-13-2008 12:21 AM
shell script problem, want to use shell script auto update IP~! singying304 Programming 4 11-29-2005 05:32 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:24 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration