How do I create a bash script that sums any number of command line arguments?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








5















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

















5















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













5












5








5


1






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
















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.







bash shell-script arithmetic






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 5 '13 at 23:16









Gilles

548k13011131631




548k13011131631










asked Nov 5 '13 at 6:26









JohnJohn

96491925




96491925












  • 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

















  • 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
















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





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










3 Answers
3






active

oldest

votes


















14














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).



Some awk implementations like GNU awk when POSIXLY_CORRECT is in the environment also support hexadecimals including with binary exponent notations. Or with --non-decimal-data, it understands octals and hexadecimals:



$ POSIXLY_CORRECT=1 ./sum 0xap3 0xa
90 # (0xa * 2^3) + 0xa
$ awk --non-decimal-data -f ./sum 010
8





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



















8














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
































    7














    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







    • 1





      @John typically if you want to process the first argument differently you first copy it to something else and then shift all the rest of the arguments with first=$1;shift

      – icarus
      Nov 19 '16 at 17:45











    Your Answer








    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "106"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f98907%2fhow-do-i-create-a-bash-script-that-sums-any-number-of-command-line-arguments%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    14














    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).



    Some awk implementations like GNU awk when POSIXLY_CORRECT is in the environment also support hexadecimals including with binary exponent notations. Or with --non-decimal-data, it understands octals and hexadecimals:



    $ POSIXLY_CORRECT=1 ./sum 0xap3 0xa
    90 # (0xa * 2^3) + 0xa
    $ awk --non-decimal-data -f ./sum 010
    8





    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
















    14














    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).



    Some awk implementations like GNU awk when POSIXLY_CORRECT is in the environment also support hexadecimals including with binary exponent notations. Or with --non-decimal-data, it understands octals and hexadecimals:



    $ POSIXLY_CORRECT=1 ./sum 0xap3 0xa
    90 # (0xa * 2^3) + 0xa
    $ awk --non-decimal-data -f ./sum 010
    8





    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














    14












    14








    14







    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).



    Some awk implementations like GNU awk when POSIXLY_CORRECT is in the environment also support hexadecimals including with binary exponent notations. Or with --non-decimal-data, it understands octals and hexadecimals:



    $ POSIXLY_CORRECT=1 ./sum 0xap3 0xa
    90 # (0xa * 2^3) + 0xa
    $ awk --non-decimal-data -f ./sum 010
    8





    share|improve this answer















    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).



    Some awk implementations like GNU awk when POSIXLY_CORRECT is in the environment also support hexadecimals including with binary exponent notations. Or with --non-decimal-data, it understands octals and hexadecimals:



    $ POSIXLY_CORRECT=1 ./sum 0xap3 0xa
    90 # (0xa * 2^3) + 0xa
    $ awk --non-decimal-data -f ./sum 010
    8






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Mar 16 at 9:38

























    answered Nov 5 '13 at 9:51









    Stéphane ChazelasStéphane Chazelas

    314k57594953




    314k57594953












    • 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


















    • 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

















    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






    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














    8














    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





























      8














      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



























        8












        8








        8







        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















        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














        share|improve this answer



        share|improve this answer








        edited Nov 5 '13 at 8:25









        slm

        256k71544690




        256k71544690










        answered Nov 5 '13 at 7:25









        ricirici

        7,6372732




        7,6372732





















            7














            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







            • 1





              @John typically if you want to process the first argument differently you first copy it to something else and then shift all the rest of the arguments with first=$1;shift

              – icarus
              Nov 19 '16 at 17:45















            7














            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







            • 1





              @John typically if you want to process the first argument differently you first copy it to something else and then shift all the rest of the arguments with first=$1;shift

              – icarus
              Nov 19 '16 at 17:45













            7












            7








            7







            You can use the following bash function:



            sum() 
            local sum=0
            for arg in "$@"; do
            (( sum += arg ))
            done
            echo $sum






            share|improve this answer













            You can use the following bash function:



            sum() 
            local sum=0
            for arg in "$@"; do
            (( sum += arg ))
            done
            echo $sum







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 5 '13 at 6:46









            Radu RădeanuRadu Rădeanu

            1,05311239




            1,05311239












            • 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







            • 1





              @John typically if you want to process the first argument differently you first copy it to something else and then shift all the rest of the arguments with first=$1;shift

              – icarus
              Nov 19 '16 at 17:45

















            • 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







            • 1





              @John typically if you want to process the first argument differently you first copy it to something else and then shift all the rest of the arguments with first=$1;shift

              – icarus
              Nov 19 '16 at 17:45
















            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





            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




            4





            $# is the number of args

            – rici
            Nov 5 '13 at 7:19





            $# 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





            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




            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






            @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





            1




            1





            @John typically if you want to process the first argument differently you first copy it to something else and then shift all the rest of the arguments with first=$1;shift

            – icarus
            Nov 19 '16 at 17:45





            @John typically if you want to process the first argument differently you first copy it to something else and then shift all the rest of the arguments with first=$1;shift

            – icarus
            Nov 19 '16 at 17:45

















            draft saved

            draft discarded
















































            Thanks for contributing an answer to Unix & Linux Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f98907%2fhow-do-i-create-a-bash-script-that-sums-any-number-of-command-line-arguments%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown






            Popular posts from this blog

            Peggy Mitchell

            Palaiologos

            The Forum (Inglewood, California)