Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

How would I create a bash script that the user can use to sum any amount of command line arguments? For example, say my script is called sum:

sum 3

3

sum 3 5

8

sum 9 8 21

38

And so on.. I realize that I will have to loop through the command line arguments and increment them to the total, but I am not really sure how to do that. I am not sure how to reference say the 2nd command line argument to a specific variable or how to get the number of total command line arguments.

share|improve this question
    
The native bash feature won't handle floating point values (eg: 3.5). For that you'd need to use a program such as awk, python, dc, bc or perl. See @rici's answer. –  NVRAM Nov 5 '13 at 17:12
add comment

3 Answers

No need for bash, plain sh will do as well:

#! /bin/sh - 
IFS=+; echo "$(($*))"

$* in POSIX shells, expands to the list of positional parameters (in this case, the arguments to the script) separated by the first character of $IFS (or space if $IFS is unset or nothing if $IFS is empty). $((...)) is the shell internal arithmetic expansion operator (note that it supports decimal, octal and hexadecimal numbers)

If you need floating point support, that's where you'll need a different shell like ksh93 or zsh (not bash as bash only supports integer arithmetic), though you could also use awk:

#! /usr/bin/awk -f
BEGIN {t=0; for (i in ARGV) t+=ARGV[i]; print t}

That will use double type numbers as implemented by your system. The input numbers must be decimal floating point or engineering notation in the English style (floating point delimiter is the period character regardless of the locale).

share|improve this answer
    
clever. But I really hope you are not confusing him ^^ It seems he's learning shell scripting basics, and you throw him IFS manipulation ^^ It's always good to know, but probably a bit too early for him... Or provide explanations such as IFS=+ means afterward the "$*" will expand to "all the arguments separated by a '+'", hence the $((computation)) will be replaced with the sum of all arguments –  Olivier Dulac Nov 5 '13 at 10:13
    
+1 Really nice trick. –  helpermethod Nov 5 '13 at 10:18
add comment

A non-looping variant:

{ printf %d+ "$@"; echo 0; } | bc

Example

Put the above in a script file, sum.

#!/bin/bash

{ printf %d+ "$@"; echo 0; } | bc

Run it like so:

$ ./sum 4
4
$ ./sum 4 4 5
13
share|improve this answer
add comment

You can use the following bash function:

sum() {
    local sum=0
    for arg in "$@"; do
        (( sum += arg ))
    done   
    echo $sum
}
share|improve this answer
    
As a side question, is there a way to determine how many args are in the command line without looping? –  John Nov 5 '13 at 7:13
4  
$# is the number of args –  rici Nov 5 '13 at 7:19
    
Thank you, perfect. One last question I forgot to clarify.. is there any way I can detect if it is like the very first argument? So say it is the very first argument, I can do something special with it. For example, as a random example, if the very first argument is a 7, I echo that the very first argument is a 7. –  John Nov 5 '13 at 7:47
2  
@John $1 is the first argument, $2 is the second argument, and so on. The variable $0 is the script's name. The total number of arguments is stored in $#. The variables $@ and $* return all the arguments. See also: how-to.wikia.com/wiki/… –  Radu Rădeanu Nov 5 '13 at 8:04
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.