Bash function with `getopts` only works the first time it's run












7















I defined the function f in Bash based on the example here (under "An option with an argument"):



f () {
while getopts ":a:" opt; do
case $opt in
a)
echo "-a was triggered, Parameter: $OPTARG" >&2
;;
?)
echo "Invalid option: -$OPTARG" >&2
return 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
return 1
;;
esac
done
}


Whereas they use a script, I directly define the function in the shell.



When I first launch Bash and define the function, everything works: f -a 123 prints -a was triggered, Parameter: 123. But when I run the exact same line a second time, nothing is printed.



What's causing this behavior? It happens in Bash 3.2 and 4.3, but it works fine in Zsh 5.1. This is surprising because the example was supposed to be for Bash, not for Zsh.










share|improve this question





























    7















    I defined the function f in Bash based on the example here (under "An option with an argument"):



    f () {
    while getopts ":a:" opt; do
    case $opt in
    a)
    echo "-a was triggered, Parameter: $OPTARG" >&2
    ;;
    ?)
    echo "Invalid option: -$OPTARG" >&2
    return 1
    ;;
    :)
    echo "Option -$OPTARG requires an argument." >&2
    return 1
    ;;
    esac
    done
    }


    Whereas they use a script, I directly define the function in the shell.



    When I first launch Bash and define the function, everything works: f -a 123 prints -a was triggered, Parameter: 123. But when I run the exact same line a second time, nothing is printed.



    What's causing this behavior? It happens in Bash 3.2 and 4.3, but it works fine in Zsh 5.1. This is surprising because the example was supposed to be for Bash, not for Zsh.










    share|improve this question



























      7












      7








      7


      0






      I defined the function f in Bash based on the example here (under "An option with an argument"):



      f () {
      while getopts ":a:" opt; do
      case $opt in
      a)
      echo "-a was triggered, Parameter: $OPTARG" >&2
      ;;
      ?)
      echo "Invalid option: -$OPTARG" >&2
      return 1
      ;;
      :)
      echo "Option -$OPTARG requires an argument." >&2
      return 1
      ;;
      esac
      done
      }


      Whereas they use a script, I directly define the function in the shell.



      When I first launch Bash and define the function, everything works: f -a 123 prints -a was triggered, Parameter: 123. But when I run the exact same line a second time, nothing is printed.



      What's causing this behavior? It happens in Bash 3.2 and 4.3, but it works fine in Zsh 5.1. This is surprising because the example was supposed to be for Bash, not for Zsh.










      share|improve this question
















      I defined the function f in Bash based on the example here (under "An option with an argument"):



      f () {
      while getopts ":a:" opt; do
      case $opt in
      a)
      echo "-a was triggered, Parameter: $OPTARG" >&2
      ;;
      ?)
      echo "Invalid option: -$OPTARG" >&2
      return 1
      ;;
      :)
      echo "Option -$OPTARG requires an argument." >&2
      return 1
      ;;
      esac
      done
      }


      Whereas they use a script, I directly define the function in the shell.



      When I first launch Bash and define the function, everything works: f -a 123 prints -a was triggered, Parameter: 123. But when I run the exact same line a second time, nothing is printed.



      What's causing this behavior? It happens in Bash 3.2 and 4.3, but it works fine in Zsh 5.1. This is surprising because the example was supposed to be for Bash, not for Zsh.







      bash function getopts






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 2 hours ago









      codeforester

      378317




      378317










      asked Oct 3 '15 at 17:36









      shadowtalkershadowtalker

      458517




      458517






















          4 Answers
          4






          active

          oldest

          votes


















          12














          bash getopts use an environment variable OPTIND to keep track the last option argument processed. The fact that OPTIND was not automatically reset each time you called getopts in the same shell session, only when the shell was invoked. So from second time you called getopts with the same arguments in the same session, OPTIND wasn't changed, getopts thought it had done the job and do nothing.



          You can reset OPTIND manually to make it work:



          $ OPTIND=1
          $ f -a 123
          -a was triggered, Parameter: 123


          or just put the function into a script and call the script multiple times.





          zsh getopts is slightly different. OPTIND was normally reset to 1 each time upon exit from shell function.






          share|improve this answer


























          • I'm pedantically accepting this answer because it's slightly more complete than the other one

            – shadowtalker
            Oct 3 '15 at 18:04











          • Sir, I can sleep now thanks to you.

            – juniorgarcia
            Jan 14 '17 at 18:12











          • Added unset opt OPTARG OPTIND before every while getopts... call and it now works flawlessly. Thanks :)

            – Deep
            Oct 6 '18 at 9:41



















          6














          It is a god habit to declare local variables in any function. If you declare $opt, $OPTARG and $OPTIND then getopts will work any times you call the function. Local variables are discarded after the function finished.



          #!/bin/bash
          function some_func {
          declare opt
          declare OPTARG
          declare OPTIND

          while getopts ":a:" opt; do
          echo $opt is $OPTARG
          done
          }





          share|improve this answer



















          • 1





            Just declaring didn't work for me. I had to put unset opt OPTARG OPTIND before the while getopts... statement such that the value of each of these variables was unset. If I didn't do this and just did the declare, since in the given bash session where I had already used getopts once the OPTIND was present, it remained unchanged

            – Deep
            Oct 6 '18 at 9:40



















          2














          You need to set OPTIND=1 at the start of function f. By default it is 1, but then gets incremented as your args are parsed. When you call getopts again it carries on where it left off. You can see this if your 2nd call is:



          f -a 123 -a 999


          when it will print the 999.






          share|improve this answer
























          • Of course! Coming from R and Python I always get tripped up by scoping in the shell. Will it work if I declare local OPTIND inside the function before getopts is called?

            – shadowtalker
            Oct 3 '15 at 18:03






          • 1





            should do, good solution.

            – meuh
            Oct 3 '15 at 18:06



















          1














          When getopt is called it keep track of processed options by the variable OPTIND.



          Try the following:



          #!/bin/bash

          f () {
          printf "Intro OPTIND: %dn" "$OPTIND"
          while getopts ":a:b:" opt; do
          printf "Current OPTIND: %dn" "$OPTIND"
          case $opt in
          a)
          echo "-a was triggered, Parameter: $OPTARG" >&2
          ;;
          b)
          echo "-b was triggered, Parameter: $OPTARG" >&2
          ;;
          esac
          done
          printf "Exit OPTIND: %dn" "$OPTIND"
          }

          echo "Run #1"
          f "$@"
          echo "Run #2"
          f "$@"


          Yield:



          ./test -a foo -b bar
          Run #1
          Intro OPTIND: 1
          Current OPTIND: 3
          -a was triggered, Parameter: foo
          Current OPTIND: 5
          -b was triggered, Parameter: bar
          Exit OPTIND: 5
          Run #2
          Intro OPTIND: 5
          Exit OPTIND: 5


          As such you could do something like:



          OPTIND=1


          at start of the function. Or the, depending on situation, and usually better:



          local OPTIND




          If OPTIND was not used, as the function is implemented, the while loop would go forever. One can also use it to resume processing of arguments, after fail or what ever, call a different function if x or y and it will resume where previous left off etc.






          share|improve this answer

























            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%2f233728%2fbash-function-with-getopts-only-works-the-first-time-its-run%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            4 Answers
            4






            active

            oldest

            votes








            4 Answers
            4






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            12














            bash getopts use an environment variable OPTIND to keep track the last option argument processed. The fact that OPTIND was not automatically reset each time you called getopts in the same shell session, only when the shell was invoked. So from second time you called getopts with the same arguments in the same session, OPTIND wasn't changed, getopts thought it had done the job and do nothing.



            You can reset OPTIND manually to make it work:



            $ OPTIND=1
            $ f -a 123
            -a was triggered, Parameter: 123


            or just put the function into a script and call the script multiple times.





            zsh getopts is slightly different. OPTIND was normally reset to 1 each time upon exit from shell function.






            share|improve this answer


























            • I'm pedantically accepting this answer because it's slightly more complete than the other one

              – shadowtalker
              Oct 3 '15 at 18:04











            • Sir, I can sleep now thanks to you.

              – juniorgarcia
              Jan 14 '17 at 18:12











            • Added unset opt OPTARG OPTIND before every while getopts... call and it now works flawlessly. Thanks :)

              – Deep
              Oct 6 '18 at 9:41
















            12














            bash getopts use an environment variable OPTIND to keep track the last option argument processed. The fact that OPTIND was not automatically reset each time you called getopts in the same shell session, only when the shell was invoked. So from second time you called getopts with the same arguments in the same session, OPTIND wasn't changed, getopts thought it had done the job and do nothing.



            You can reset OPTIND manually to make it work:



            $ OPTIND=1
            $ f -a 123
            -a was triggered, Parameter: 123


            or just put the function into a script and call the script multiple times.





            zsh getopts is slightly different. OPTIND was normally reset to 1 each time upon exit from shell function.






            share|improve this answer


























            • I'm pedantically accepting this answer because it's slightly more complete than the other one

              – shadowtalker
              Oct 3 '15 at 18:04











            • Sir, I can sleep now thanks to you.

              – juniorgarcia
              Jan 14 '17 at 18:12











            • Added unset opt OPTARG OPTIND before every while getopts... call and it now works flawlessly. Thanks :)

              – Deep
              Oct 6 '18 at 9:41














            12












            12








            12







            bash getopts use an environment variable OPTIND to keep track the last option argument processed. The fact that OPTIND was not automatically reset each time you called getopts in the same shell session, only when the shell was invoked. So from second time you called getopts with the same arguments in the same session, OPTIND wasn't changed, getopts thought it had done the job and do nothing.



            You can reset OPTIND manually to make it work:



            $ OPTIND=1
            $ f -a 123
            -a was triggered, Parameter: 123


            or just put the function into a script and call the script multiple times.





            zsh getopts is slightly different. OPTIND was normally reset to 1 each time upon exit from shell function.






            share|improve this answer















            bash getopts use an environment variable OPTIND to keep track the last option argument processed. The fact that OPTIND was not automatically reset each time you called getopts in the same shell session, only when the shell was invoked. So from second time you called getopts with the same arguments in the same session, OPTIND wasn't changed, getopts thought it had done the job and do nothing.



            You can reset OPTIND manually to make it work:



            $ OPTIND=1
            $ f -a 123
            -a was triggered, Parameter: 123


            or just put the function into a script and call the script multiple times.





            zsh getopts is slightly different. OPTIND was normally reset to 1 each time upon exit from shell function.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Oct 3 '15 at 18:12

























            answered Oct 3 '15 at 18:03









            cuonglmcuonglm

            105k25207307




            105k25207307













            • I'm pedantically accepting this answer because it's slightly more complete than the other one

              – shadowtalker
              Oct 3 '15 at 18:04











            • Sir, I can sleep now thanks to you.

              – juniorgarcia
              Jan 14 '17 at 18:12











            • Added unset opt OPTARG OPTIND before every while getopts... call and it now works flawlessly. Thanks :)

              – Deep
              Oct 6 '18 at 9:41



















            • I'm pedantically accepting this answer because it's slightly more complete than the other one

              – shadowtalker
              Oct 3 '15 at 18:04











            • Sir, I can sleep now thanks to you.

              – juniorgarcia
              Jan 14 '17 at 18:12











            • Added unset opt OPTARG OPTIND before every while getopts... call and it now works flawlessly. Thanks :)

              – Deep
              Oct 6 '18 at 9:41

















            I'm pedantically accepting this answer because it's slightly more complete than the other one

            – shadowtalker
            Oct 3 '15 at 18:04





            I'm pedantically accepting this answer because it's slightly more complete than the other one

            – shadowtalker
            Oct 3 '15 at 18:04













            Sir, I can sleep now thanks to you.

            – juniorgarcia
            Jan 14 '17 at 18:12





            Sir, I can sleep now thanks to you.

            – juniorgarcia
            Jan 14 '17 at 18:12













            Added unset opt OPTARG OPTIND before every while getopts... call and it now works flawlessly. Thanks :)

            – Deep
            Oct 6 '18 at 9:41





            Added unset opt OPTARG OPTIND before every while getopts... call and it now works flawlessly. Thanks :)

            – Deep
            Oct 6 '18 at 9:41













            6














            It is a god habit to declare local variables in any function. If you declare $opt, $OPTARG and $OPTIND then getopts will work any times you call the function. Local variables are discarded after the function finished.



            #!/bin/bash
            function some_func {
            declare opt
            declare OPTARG
            declare OPTIND

            while getopts ":a:" opt; do
            echo $opt is $OPTARG
            done
            }





            share|improve this answer



















            • 1





              Just declaring didn't work for me. I had to put unset opt OPTARG OPTIND before the while getopts... statement such that the value of each of these variables was unset. If I didn't do this and just did the declare, since in the given bash session where I had already used getopts once the OPTIND was present, it remained unchanged

              – Deep
              Oct 6 '18 at 9:40
















            6














            It is a god habit to declare local variables in any function. If you declare $opt, $OPTARG and $OPTIND then getopts will work any times you call the function. Local variables are discarded after the function finished.



            #!/bin/bash
            function some_func {
            declare opt
            declare OPTARG
            declare OPTIND

            while getopts ":a:" opt; do
            echo $opt is $OPTARG
            done
            }





            share|improve this answer



















            • 1





              Just declaring didn't work for me. I had to put unset opt OPTARG OPTIND before the while getopts... statement such that the value of each of these variables was unset. If I didn't do this and just did the declare, since in the given bash session where I had already used getopts once the OPTIND was present, it remained unchanged

              – Deep
              Oct 6 '18 at 9:40














            6












            6








            6







            It is a god habit to declare local variables in any function. If you declare $opt, $OPTARG and $OPTIND then getopts will work any times you call the function. Local variables are discarded after the function finished.



            #!/bin/bash
            function some_func {
            declare opt
            declare OPTARG
            declare OPTIND

            while getopts ":a:" opt; do
            echo $opt is $OPTARG
            done
            }





            share|improve this answer













            It is a god habit to declare local variables in any function. If you declare $opt, $OPTARG and $OPTIND then getopts will work any times you call the function. Local variables are discarded after the function finished.



            #!/bin/bash
            function some_func {
            declare opt
            declare OPTARG
            declare OPTIND

            while getopts ":a:" opt; do
            echo $opt is $OPTARG
            done
            }






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Dec 8 '17 at 13:13









            ThomassoThomasso

            6111




            6111








            • 1





              Just declaring didn't work for me. I had to put unset opt OPTARG OPTIND before the while getopts... statement such that the value of each of these variables was unset. If I didn't do this and just did the declare, since in the given bash session where I had already used getopts once the OPTIND was present, it remained unchanged

              – Deep
              Oct 6 '18 at 9:40














            • 1





              Just declaring didn't work for me. I had to put unset opt OPTARG OPTIND before the while getopts... statement such that the value of each of these variables was unset. If I didn't do this and just did the declare, since in the given bash session where I had already used getopts once the OPTIND was present, it remained unchanged

              – Deep
              Oct 6 '18 at 9:40








            1




            1





            Just declaring didn't work for me. I had to put unset opt OPTARG OPTIND before the while getopts... statement such that the value of each of these variables was unset. If I didn't do this and just did the declare, since in the given bash session where I had already used getopts once the OPTIND was present, it remained unchanged

            – Deep
            Oct 6 '18 at 9:40





            Just declaring didn't work for me. I had to put unset opt OPTARG OPTIND before the while getopts... statement such that the value of each of these variables was unset. If I didn't do this and just did the declare, since in the given bash session where I had already used getopts once the OPTIND was present, it remained unchanged

            – Deep
            Oct 6 '18 at 9:40











            2














            You need to set OPTIND=1 at the start of function f. By default it is 1, but then gets incremented as your args are parsed. When you call getopts again it carries on where it left off. You can see this if your 2nd call is:



            f -a 123 -a 999


            when it will print the 999.






            share|improve this answer
























            • Of course! Coming from R and Python I always get tripped up by scoping in the shell. Will it work if I declare local OPTIND inside the function before getopts is called?

              – shadowtalker
              Oct 3 '15 at 18:03






            • 1





              should do, good solution.

              – meuh
              Oct 3 '15 at 18:06
















            2














            You need to set OPTIND=1 at the start of function f. By default it is 1, but then gets incremented as your args are parsed. When you call getopts again it carries on where it left off. You can see this if your 2nd call is:



            f -a 123 -a 999


            when it will print the 999.






            share|improve this answer
























            • Of course! Coming from R and Python I always get tripped up by scoping in the shell. Will it work if I declare local OPTIND inside the function before getopts is called?

              – shadowtalker
              Oct 3 '15 at 18:03






            • 1





              should do, good solution.

              – meuh
              Oct 3 '15 at 18:06














            2












            2








            2







            You need to set OPTIND=1 at the start of function f. By default it is 1, but then gets incremented as your args are parsed. When you call getopts again it carries on where it left off. You can see this if your 2nd call is:



            f -a 123 -a 999


            when it will print the 999.






            share|improve this answer













            You need to set OPTIND=1 at the start of function f. By default it is 1, but then gets incremented as your args are parsed. When you call getopts again it carries on where it left off. You can see this if your 2nd call is:



            f -a 123 -a 999


            when it will print the 999.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Oct 3 '15 at 18:01









            meuhmeuh

            32.4k12054




            32.4k12054













            • Of course! Coming from R and Python I always get tripped up by scoping in the shell. Will it work if I declare local OPTIND inside the function before getopts is called?

              – shadowtalker
              Oct 3 '15 at 18:03






            • 1





              should do, good solution.

              – meuh
              Oct 3 '15 at 18:06



















            • Of course! Coming from R and Python I always get tripped up by scoping in the shell. Will it work if I declare local OPTIND inside the function before getopts is called?

              – shadowtalker
              Oct 3 '15 at 18:03






            • 1





              should do, good solution.

              – meuh
              Oct 3 '15 at 18:06

















            Of course! Coming from R and Python I always get tripped up by scoping in the shell. Will it work if I declare local OPTIND inside the function before getopts is called?

            – shadowtalker
            Oct 3 '15 at 18:03





            Of course! Coming from R and Python I always get tripped up by scoping in the shell. Will it work if I declare local OPTIND inside the function before getopts is called?

            – shadowtalker
            Oct 3 '15 at 18:03




            1




            1





            should do, good solution.

            – meuh
            Oct 3 '15 at 18:06





            should do, good solution.

            – meuh
            Oct 3 '15 at 18:06











            1














            When getopt is called it keep track of processed options by the variable OPTIND.



            Try the following:



            #!/bin/bash

            f () {
            printf "Intro OPTIND: %dn" "$OPTIND"
            while getopts ":a:b:" opt; do
            printf "Current OPTIND: %dn" "$OPTIND"
            case $opt in
            a)
            echo "-a was triggered, Parameter: $OPTARG" >&2
            ;;
            b)
            echo "-b was triggered, Parameter: $OPTARG" >&2
            ;;
            esac
            done
            printf "Exit OPTIND: %dn" "$OPTIND"
            }

            echo "Run #1"
            f "$@"
            echo "Run #2"
            f "$@"


            Yield:



            ./test -a foo -b bar
            Run #1
            Intro OPTIND: 1
            Current OPTIND: 3
            -a was triggered, Parameter: foo
            Current OPTIND: 5
            -b was triggered, Parameter: bar
            Exit OPTIND: 5
            Run #2
            Intro OPTIND: 5
            Exit OPTIND: 5


            As such you could do something like:



            OPTIND=1


            at start of the function. Or the, depending on situation, and usually better:



            local OPTIND




            If OPTIND was not used, as the function is implemented, the while loop would go forever. One can also use it to resume processing of arguments, after fail or what ever, call a different function if x or y and it will resume where previous left off etc.






            share|improve this answer






























              1














              When getopt is called it keep track of processed options by the variable OPTIND.



              Try the following:



              #!/bin/bash

              f () {
              printf "Intro OPTIND: %dn" "$OPTIND"
              while getopts ":a:b:" opt; do
              printf "Current OPTIND: %dn" "$OPTIND"
              case $opt in
              a)
              echo "-a was triggered, Parameter: $OPTARG" >&2
              ;;
              b)
              echo "-b was triggered, Parameter: $OPTARG" >&2
              ;;
              esac
              done
              printf "Exit OPTIND: %dn" "$OPTIND"
              }

              echo "Run #1"
              f "$@"
              echo "Run #2"
              f "$@"


              Yield:



              ./test -a foo -b bar
              Run #1
              Intro OPTIND: 1
              Current OPTIND: 3
              -a was triggered, Parameter: foo
              Current OPTIND: 5
              -b was triggered, Parameter: bar
              Exit OPTIND: 5
              Run #2
              Intro OPTIND: 5
              Exit OPTIND: 5


              As such you could do something like:



              OPTIND=1


              at start of the function. Or the, depending on situation, and usually better:



              local OPTIND




              If OPTIND was not used, as the function is implemented, the while loop would go forever. One can also use it to resume processing of arguments, after fail or what ever, call a different function if x or y and it will resume where previous left off etc.






              share|improve this answer




























                1












                1








                1







                When getopt is called it keep track of processed options by the variable OPTIND.



                Try the following:



                #!/bin/bash

                f () {
                printf "Intro OPTIND: %dn" "$OPTIND"
                while getopts ":a:b:" opt; do
                printf "Current OPTIND: %dn" "$OPTIND"
                case $opt in
                a)
                echo "-a was triggered, Parameter: $OPTARG" >&2
                ;;
                b)
                echo "-b was triggered, Parameter: $OPTARG" >&2
                ;;
                esac
                done
                printf "Exit OPTIND: %dn" "$OPTIND"
                }

                echo "Run #1"
                f "$@"
                echo "Run #2"
                f "$@"


                Yield:



                ./test -a foo -b bar
                Run #1
                Intro OPTIND: 1
                Current OPTIND: 3
                -a was triggered, Parameter: foo
                Current OPTIND: 5
                -b was triggered, Parameter: bar
                Exit OPTIND: 5
                Run #2
                Intro OPTIND: 5
                Exit OPTIND: 5


                As such you could do something like:



                OPTIND=1


                at start of the function. Or the, depending on situation, and usually better:



                local OPTIND




                If OPTIND was not used, as the function is implemented, the while loop would go forever. One can also use it to resume processing of arguments, after fail or what ever, call a different function if x or y and it will resume where previous left off etc.






                share|improve this answer















                When getopt is called it keep track of processed options by the variable OPTIND.



                Try the following:



                #!/bin/bash

                f () {
                printf "Intro OPTIND: %dn" "$OPTIND"
                while getopts ":a:b:" opt; do
                printf "Current OPTIND: %dn" "$OPTIND"
                case $opt in
                a)
                echo "-a was triggered, Parameter: $OPTARG" >&2
                ;;
                b)
                echo "-b was triggered, Parameter: $OPTARG" >&2
                ;;
                esac
                done
                printf "Exit OPTIND: %dn" "$OPTIND"
                }

                echo "Run #1"
                f "$@"
                echo "Run #2"
                f "$@"


                Yield:



                ./test -a foo -b bar
                Run #1
                Intro OPTIND: 1
                Current OPTIND: 3
                -a was triggered, Parameter: foo
                Current OPTIND: 5
                -b was triggered, Parameter: bar
                Exit OPTIND: 5
                Run #2
                Intro OPTIND: 5
                Exit OPTIND: 5


                As such you could do something like:



                OPTIND=1


                at start of the function. Or the, depending on situation, and usually better:



                local OPTIND




                If OPTIND was not used, as the function is implemented, the while loop would go forever. One can also use it to resume processing of arguments, after fail or what ever, call a different function if x or y and it will resume where previous left off etc.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Oct 3 '15 at 18:49

























                answered Oct 3 '15 at 18:05









                RuniumRunium

                18.7k43060




                18.7k43060






























                    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%2f233728%2fbash-function-with-getopts-only-works-the-first-time-its-run%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

                    Histoire des bourses de valeurs

                    Why is there Russian traffic in my log files?

                    Rename multiple files to decrement number in file name?