Pass a function arguments?

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











up vote
0
down vote

favorite












How would you make a function that gets arguments?



function arg_example 
arg "c" # This is imaginary but it would return 'true' if it found the argument -c.
did_find_arg=$? # Get the previous function (arg)'s output.

if [$did_find_arg == 'true']; then
echo "Yes!"
else
echo "Not found."
fi


# Testing
arg_example # "Not found."
arg_example -c # "Yes!"
arg_example -k # "Not found."


Also, how would you find the value of a key-value function, eg --name:



function hello 
echo "Hello, $--name!"



EDIT: I know how to use $1 and $2, but I'd like to know how to get optional things like -v or --version.










share|improve this question



















  • 1




    That's where you want to use getopts (remember to reset OPTIND and/or make is local for shells that support local scope)
    – Stéphane Chazelas
    Jan 26 '15 at 14:10







  • 1




    Take a look at getopts
    – PM 2Ring
    Jan 26 '15 at 14:11










  • I'll take a look.
    – Aqua the SeaWing
    Jan 26 '15 at 14:16






  • 1




    Don't forget that you need to have spaces around [ and ] in the if statements.
    – Barmar
    Jan 26 '15 at 22:15














up vote
0
down vote

favorite












How would you make a function that gets arguments?



function arg_example 
arg "c" # This is imaginary but it would return 'true' if it found the argument -c.
did_find_arg=$? # Get the previous function (arg)'s output.

if [$did_find_arg == 'true']; then
echo "Yes!"
else
echo "Not found."
fi


# Testing
arg_example # "Not found."
arg_example -c # "Yes!"
arg_example -k # "Not found."


Also, how would you find the value of a key-value function, eg --name:



function hello 
echo "Hello, $--name!"



EDIT: I know how to use $1 and $2, but I'd like to know how to get optional things like -v or --version.










share|improve this question



















  • 1




    That's where you want to use getopts (remember to reset OPTIND and/or make is local for shells that support local scope)
    – Stéphane Chazelas
    Jan 26 '15 at 14:10







  • 1




    Take a look at getopts
    – PM 2Ring
    Jan 26 '15 at 14:11










  • I'll take a look.
    – Aqua the SeaWing
    Jan 26 '15 at 14:16






  • 1




    Don't forget that you need to have spaces around [ and ] in the if statements.
    – Barmar
    Jan 26 '15 at 22:15












up vote
0
down vote

favorite









up vote
0
down vote

favorite











How would you make a function that gets arguments?



function arg_example 
arg "c" # This is imaginary but it would return 'true' if it found the argument -c.
did_find_arg=$? # Get the previous function (arg)'s output.

if [$did_find_arg == 'true']; then
echo "Yes!"
else
echo "Not found."
fi


# Testing
arg_example # "Not found."
arg_example -c # "Yes!"
arg_example -k # "Not found."


Also, how would you find the value of a key-value function, eg --name:



function hello 
echo "Hello, $--name!"



EDIT: I know how to use $1 and $2, but I'd like to know how to get optional things like -v or --version.










share|improve this question















How would you make a function that gets arguments?



function arg_example 
arg "c" # This is imaginary but it would return 'true' if it found the argument -c.
did_find_arg=$? # Get the previous function (arg)'s output.

if [$did_find_arg == 'true']; then
echo "Yes!"
else
echo "Not found."
fi


# Testing
arg_example # "Not found."
arg_example -c # "Yes!"
arg_example -k # "Not found."


Also, how would you find the value of a key-value function, eg --name:



function hello 
echo "Hello, $--name!"



EDIT: I know how to use $1 and $2, but I'd like to know how to get optional things like -v or --version.







shell function arguments






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 26 '15 at 20:28









Gilles

523k12610441576




523k12610441576










asked Jan 26 '15 at 14:04









Aqua the SeaWing

565




565







  • 1




    That's where you want to use getopts (remember to reset OPTIND and/or make is local for shells that support local scope)
    – Stéphane Chazelas
    Jan 26 '15 at 14:10







  • 1




    Take a look at getopts
    – PM 2Ring
    Jan 26 '15 at 14:11










  • I'll take a look.
    – Aqua the SeaWing
    Jan 26 '15 at 14:16






  • 1




    Don't forget that you need to have spaces around [ and ] in the if statements.
    – Barmar
    Jan 26 '15 at 22:15












  • 1




    That's where you want to use getopts (remember to reset OPTIND and/or make is local for shells that support local scope)
    – Stéphane Chazelas
    Jan 26 '15 at 14:10







  • 1




    Take a look at getopts
    – PM 2Ring
    Jan 26 '15 at 14:11










  • I'll take a look.
    – Aqua the SeaWing
    Jan 26 '15 at 14:16






  • 1




    Don't forget that you need to have spaces around [ and ] in the if statements.
    – Barmar
    Jan 26 '15 at 22:15







1




1




That's where you want to use getopts (remember to reset OPTIND and/or make is local for shells that support local scope)
– Stéphane Chazelas
Jan 26 '15 at 14:10





That's where you want to use getopts (remember to reset OPTIND and/or make is local for shells that support local scope)
– Stéphane Chazelas
Jan 26 '15 at 14:10





1




1




Take a look at getopts
– PM 2Ring
Jan 26 '15 at 14:11




Take a look at getopts
– PM 2Ring
Jan 26 '15 at 14:11












I'll take a look.
– Aqua the SeaWing
Jan 26 '15 at 14:16




I'll take a look.
– Aqua the SeaWing
Jan 26 '15 at 14:16




1




1




Don't forget that you need to have spaces around [ and ] in the if statements.
– Barmar
Jan 26 '15 at 22:15




Don't forget that you need to have spaces around [ and ] in the if statements.
– Barmar
Jan 26 '15 at 22:15










2 Answers
2






active

oldest

votes

















up vote
1
down vote













Processing the command line of a function may be done with getopts in exactly the same way as processing the command line for a script. The only thing to watch out for is that OPTIND will have to be reset to 1 or made local to the function:



#!/bin/bash

myfunc ()
local OPTIND
local do_c=0
local do_k=0
local opt

while getopts 'ck' opt; do
case $opt in
c) do_c=1 ;;
k) do_k=1 ;;
*) echo 'Error in command line parsing' >&2
return 1
esac
done
shift "$(( OPTIND - 1 ))"

if [ "$do_c" -eq 1 ]; then
echo 'Yes!'
else
echo 'Not found'
fi


myfunc
myfunc -c
myfunc -k
myfunc -a


The above script produces:



Not found
Yes!
Not found
script.sh: illegal option -- a
Error in command line parsing


Related:



  • bash function arguments strange behaviour





share|improve this answer





























    up vote
    0
    down vote













    Very simple named argument extractor for Bash:



    #!/bin/bash

    getargs()

    local out=""
    for argname in "$@"; do
    out="$outlocal $argname=$1; shift;"
    done
    printf "%s" "$out"


    testfun()

    eval $(getargs a b c)
    printf "a = %s, b = %s, c = %sn" "$a" "$b" "$c"


    testfun "$@"


    Since we want the arguments to be local variables in the dynamic scope of the function testfun, getargs cannot be a function call. Rather, getargs is a tiny compiler which translates an argument specification like a b c into shell syntax, generating the code which we would otherwise manually add in order to get the positional argument into local variables.



    For instance, the output of



    getargs a b c


    is the source code:



    local a=$1; shift;local b=$1; shift;local c=$1; shift


    when we eval that, it does what it looks like it does. In the context of the caller, it gets the first three positional arguments into a, b and c, shifting them out of the argument list.



    Now we could take this to the next level and add "bells and whistles".



    For starters, the generated code could check that there actually are exactly three arguments and diagnose.



    We could support optional arguments: getargs a b : c (or whatever) could mean that a and b are required, but c is optional. We could also support trailing arguments: getargs a b : c . d could generate code which gets the first two arguments (which are required) into locals a and b. Then if a third argument is present, it goes into c. Any arguments after that go into d, which is a Bash array.



    I will leave that as an exercise.



    Too bad that the shell doesn't have a macro-expansion time. The big downside of this is that the code is generated each time the function is called, even though it is completely static.



    You could write some sort of preprocessor (e.g. in Awk) to transform some sort of named function syntactic sugar into regular shell code.






    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',
      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%2f181129%2fpass-a-function-arguments%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      1
      down vote













      Processing the command line of a function may be done with getopts in exactly the same way as processing the command line for a script. The only thing to watch out for is that OPTIND will have to be reset to 1 or made local to the function:



      #!/bin/bash

      myfunc ()
      local OPTIND
      local do_c=0
      local do_k=0
      local opt

      while getopts 'ck' opt; do
      case $opt in
      c) do_c=1 ;;
      k) do_k=1 ;;
      *) echo 'Error in command line parsing' >&2
      return 1
      esac
      done
      shift "$(( OPTIND - 1 ))"

      if [ "$do_c" -eq 1 ]; then
      echo 'Yes!'
      else
      echo 'Not found'
      fi


      myfunc
      myfunc -c
      myfunc -k
      myfunc -a


      The above script produces:



      Not found
      Yes!
      Not found
      script.sh: illegal option -- a
      Error in command line parsing


      Related:



      • bash function arguments strange behaviour





      share|improve this answer


























        up vote
        1
        down vote













        Processing the command line of a function may be done with getopts in exactly the same way as processing the command line for a script. The only thing to watch out for is that OPTIND will have to be reset to 1 or made local to the function:



        #!/bin/bash

        myfunc ()
        local OPTIND
        local do_c=0
        local do_k=0
        local opt

        while getopts 'ck' opt; do
        case $opt in
        c) do_c=1 ;;
        k) do_k=1 ;;
        *) echo 'Error in command line parsing' >&2
        return 1
        esac
        done
        shift "$(( OPTIND - 1 ))"

        if [ "$do_c" -eq 1 ]; then
        echo 'Yes!'
        else
        echo 'Not found'
        fi


        myfunc
        myfunc -c
        myfunc -k
        myfunc -a


        The above script produces:



        Not found
        Yes!
        Not found
        script.sh: illegal option -- a
        Error in command line parsing


        Related:



        • bash function arguments strange behaviour





        share|improve this answer
























          up vote
          1
          down vote










          up vote
          1
          down vote









          Processing the command line of a function may be done with getopts in exactly the same way as processing the command line for a script. The only thing to watch out for is that OPTIND will have to be reset to 1 or made local to the function:



          #!/bin/bash

          myfunc ()
          local OPTIND
          local do_c=0
          local do_k=0
          local opt

          while getopts 'ck' opt; do
          case $opt in
          c) do_c=1 ;;
          k) do_k=1 ;;
          *) echo 'Error in command line parsing' >&2
          return 1
          esac
          done
          shift "$(( OPTIND - 1 ))"

          if [ "$do_c" -eq 1 ]; then
          echo 'Yes!'
          else
          echo 'Not found'
          fi


          myfunc
          myfunc -c
          myfunc -k
          myfunc -a


          The above script produces:



          Not found
          Yes!
          Not found
          script.sh: illegal option -- a
          Error in command line parsing


          Related:



          • bash function arguments strange behaviour





          share|improve this answer














          Processing the command line of a function may be done with getopts in exactly the same way as processing the command line for a script. The only thing to watch out for is that OPTIND will have to be reset to 1 or made local to the function:



          #!/bin/bash

          myfunc ()
          local OPTIND
          local do_c=0
          local do_k=0
          local opt

          while getopts 'ck' opt; do
          case $opt in
          c) do_c=1 ;;
          k) do_k=1 ;;
          *) echo 'Error in command line parsing' >&2
          return 1
          esac
          done
          shift "$(( OPTIND - 1 ))"

          if [ "$do_c" -eq 1 ]; then
          echo 'Yes!'
          else
          echo 'Not found'
          fi


          myfunc
          myfunc -c
          myfunc -k
          myfunc -a


          The above script produces:



          Not found
          Yes!
          Not found
          script.sh: illegal option -- a
          Error in command line parsing


          Related:



          • bash function arguments strange behaviour






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 25 at 17:30

























          answered Nov 25 at 10:45









          Kusalananda

          118k16223361




          118k16223361






















              up vote
              0
              down vote













              Very simple named argument extractor for Bash:



              #!/bin/bash

              getargs()

              local out=""
              for argname in "$@"; do
              out="$outlocal $argname=$1; shift;"
              done
              printf "%s" "$out"


              testfun()

              eval $(getargs a b c)
              printf "a = %s, b = %s, c = %sn" "$a" "$b" "$c"


              testfun "$@"


              Since we want the arguments to be local variables in the dynamic scope of the function testfun, getargs cannot be a function call. Rather, getargs is a tiny compiler which translates an argument specification like a b c into shell syntax, generating the code which we would otherwise manually add in order to get the positional argument into local variables.



              For instance, the output of



              getargs a b c


              is the source code:



              local a=$1; shift;local b=$1; shift;local c=$1; shift


              when we eval that, it does what it looks like it does. In the context of the caller, it gets the first three positional arguments into a, b and c, shifting them out of the argument list.



              Now we could take this to the next level and add "bells and whistles".



              For starters, the generated code could check that there actually are exactly three arguments and diagnose.



              We could support optional arguments: getargs a b : c (or whatever) could mean that a and b are required, but c is optional. We could also support trailing arguments: getargs a b : c . d could generate code which gets the first two arguments (which are required) into locals a and b. Then if a third argument is present, it goes into c. Any arguments after that go into d, which is a Bash array.



              I will leave that as an exercise.



              Too bad that the shell doesn't have a macro-expansion time. The big downside of this is that the code is generated each time the function is called, even though it is completely static.



              You could write some sort of preprocessor (e.g. in Awk) to transform some sort of named function syntactic sugar into regular shell code.






              share|improve this answer
























                up vote
                0
                down vote













                Very simple named argument extractor for Bash:



                #!/bin/bash

                getargs()

                local out=""
                for argname in "$@"; do
                out="$outlocal $argname=$1; shift;"
                done
                printf "%s" "$out"


                testfun()

                eval $(getargs a b c)
                printf "a = %s, b = %s, c = %sn" "$a" "$b" "$c"


                testfun "$@"


                Since we want the arguments to be local variables in the dynamic scope of the function testfun, getargs cannot be a function call. Rather, getargs is a tiny compiler which translates an argument specification like a b c into shell syntax, generating the code which we would otherwise manually add in order to get the positional argument into local variables.



                For instance, the output of



                getargs a b c


                is the source code:



                local a=$1; shift;local b=$1; shift;local c=$1; shift


                when we eval that, it does what it looks like it does. In the context of the caller, it gets the first three positional arguments into a, b and c, shifting them out of the argument list.



                Now we could take this to the next level and add "bells and whistles".



                For starters, the generated code could check that there actually are exactly three arguments and diagnose.



                We could support optional arguments: getargs a b : c (or whatever) could mean that a and b are required, but c is optional. We could also support trailing arguments: getargs a b : c . d could generate code which gets the first two arguments (which are required) into locals a and b. Then if a third argument is present, it goes into c. Any arguments after that go into d, which is a Bash array.



                I will leave that as an exercise.



                Too bad that the shell doesn't have a macro-expansion time. The big downside of this is that the code is generated each time the function is called, even though it is completely static.



                You could write some sort of preprocessor (e.g. in Awk) to transform some sort of named function syntactic sugar into regular shell code.






                share|improve this answer






















                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  Very simple named argument extractor for Bash:



                  #!/bin/bash

                  getargs()

                  local out=""
                  for argname in "$@"; do
                  out="$outlocal $argname=$1; shift;"
                  done
                  printf "%s" "$out"


                  testfun()

                  eval $(getargs a b c)
                  printf "a = %s, b = %s, c = %sn" "$a" "$b" "$c"


                  testfun "$@"


                  Since we want the arguments to be local variables in the dynamic scope of the function testfun, getargs cannot be a function call. Rather, getargs is a tiny compiler which translates an argument specification like a b c into shell syntax, generating the code which we would otherwise manually add in order to get the positional argument into local variables.



                  For instance, the output of



                  getargs a b c


                  is the source code:



                  local a=$1; shift;local b=$1; shift;local c=$1; shift


                  when we eval that, it does what it looks like it does. In the context of the caller, it gets the first three positional arguments into a, b and c, shifting them out of the argument list.



                  Now we could take this to the next level and add "bells and whistles".



                  For starters, the generated code could check that there actually are exactly three arguments and diagnose.



                  We could support optional arguments: getargs a b : c (or whatever) could mean that a and b are required, but c is optional. We could also support trailing arguments: getargs a b : c . d could generate code which gets the first two arguments (which are required) into locals a and b. Then if a third argument is present, it goes into c. Any arguments after that go into d, which is a Bash array.



                  I will leave that as an exercise.



                  Too bad that the shell doesn't have a macro-expansion time. The big downside of this is that the code is generated each time the function is called, even though it is completely static.



                  You could write some sort of preprocessor (e.g. in Awk) to transform some sort of named function syntactic sugar into regular shell code.






                  share|improve this answer












                  Very simple named argument extractor for Bash:



                  #!/bin/bash

                  getargs()

                  local out=""
                  for argname in "$@"; do
                  out="$outlocal $argname=$1; shift;"
                  done
                  printf "%s" "$out"


                  testfun()

                  eval $(getargs a b c)
                  printf "a = %s, b = %s, c = %sn" "$a" "$b" "$c"


                  testfun "$@"


                  Since we want the arguments to be local variables in the dynamic scope of the function testfun, getargs cannot be a function call. Rather, getargs is a tiny compiler which translates an argument specification like a b c into shell syntax, generating the code which we would otherwise manually add in order to get the positional argument into local variables.



                  For instance, the output of



                  getargs a b c


                  is the source code:



                  local a=$1; shift;local b=$1; shift;local c=$1; shift


                  when we eval that, it does what it looks like it does. In the context of the caller, it gets the first three positional arguments into a, b and c, shifting them out of the argument list.



                  Now we could take this to the next level and add "bells and whistles".



                  For starters, the generated code could check that there actually are exactly three arguments and diagnose.



                  We could support optional arguments: getargs a b : c (or whatever) could mean that a and b are required, but c is optional. We could also support trailing arguments: getargs a b : c . d could generate code which gets the first two arguments (which are required) into locals a and b. Then if a third argument is present, it goes into c. Any arguments after that go into d, which is a Bash array.



                  I will leave that as an exercise.



                  Too bad that the shell doesn't have a macro-expansion time. The big downside of this is that the code is generated each time the function is called, even though it is completely static.



                  You could write some sort of preprocessor (e.g. in Awk) to transform some sort of named function syntactic sugar into regular shell code.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jul 24 '17 at 20:17









                  Kaz

                  4,49311431




                  4,49311431



























                      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.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • 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%2f181129%2fpass-a-function-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

                      How to check contact read email or not when send email to Individual?

                      Bahrain

                      Postfix configuration issue with fips on centos 7; mailgun relay