Bash Nested Private Functions












0















I am trying to create a custom Mac Terminal command, start, In Terminal, my intent is to write $ start func1 subfunc myText, where func is a function in the start.sh file and subfunc is a function only in func that can only be called from in func. So $ start subfunc myText wouldn't be possible. I see that its possible to pass a function from another (Here), but only when both are in the outer scope of the start.sh file.



Basically:



start.sh:



function func(){
function subfunc(){
echo $1
}
}


and then in Terminal:
$ start func subfunc Hey prints Hey










share|improve this question




















  • 1





    I don't think bash has nested function scopes like this.

    – Barmar
    Nov 13 '18 at 21:51






  • 2





    What is it supposed to achieve? Even if it works (it doesn't), Anyone who can't do start subfunc myText can still do start func subfunc Hey do still call subfunc anyway. What problem are you trying to solve with this?

    – P.P.
    Nov 13 '18 at 21:58













  • This feels like similar functionality to like an aws console command? I don't think bash is the right place to write this though. If you did, I think you would need to catch those arguments to variables and then perform logic based on what is in those variables if [$command = "func"] if [ $subcommand = "subfunc"] sort of thing... IT may help if you explained what you are trying to achieve though since it's not clear from your very not-working code.

    – JNevill
    Nov 13 '18 at 22:06













  • Sorry, I haven't used bash before and couldn't find great documentation for this. I was trying to create a custom hierarchy of commands to do something like nodecontroller nodestart node1 start, or something with a hierarchy of commands like this.

    – Jasper Braun
    Nov 14 '18 at 1:31
















0















I am trying to create a custom Mac Terminal command, start, In Terminal, my intent is to write $ start func1 subfunc myText, where func is a function in the start.sh file and subfunc is a function only in func that can only be called from in func. So $ start subfunc myText wouldn't be possible. I see that its possible to pass a function from another (Here), but only when both are in the outer scope of the start.sh file.



Basically:



start.sh:



function func(){
function subfunc(){
echo $1
}
}


and then in Terminal:
$ start func subfunc Hey prints Hey










share|improve this question




















  • 1





    I don't think bash has nested function scopes like this.

    – Barmar
    Nov 13 '18 at 21:51






  • 2





    What is it supposed to achieve? Even if it works (it doesn't), Anyone who can't do start subfunc myText can still do start func subfunc Hey do still call subfunc anyway. What problem are you trying to solve with this?

    – P.P.
    Nov 13 '18 at 21:58













  • This feels like similar functionality to like an aws console command? I don't think bash is the right place to write this though. If you did, I think you would need to catch those arguments to variables and then perform logic based on what is in those variables if [$command = "func"] if [ $subcommand = "subfunc"] sort of thing... IT may help if you explained what you are trying to achieve though since it's not clear from your very not-working code.

    – JNevill
    Nov 13 '18 at 22:06













  • Sorry, I haven't used bash before and couldn't find great documentation for this. I was trying to create a custom hierarchy of commands to do something like nodecontroller nodestart node1 start, or something with a hierarchy of commands like this.

    – Jasper Braun
    Nov 14 '18 at 1:31














0












0








0








I am trying to create a custom Mac Terminal command, start, In Terminal, my intent is to write $ start func1 subfunc myText, where func is a function in the start.sh file and subfunc is a function only in func that can only be called from in func. So $ start subfunc myText wouldn't be possible. I see that its possible to pass a function from another (Here), but only when both are in the outer scope of the start.sh file.



Basically:



start.sh:



function func(){
function subfunc(){
echo $1
}
}


and then in Terminal:
$ start func subfunc Hey prints Hey










share|improve this question
















I am trying to create a custom Mac Terminal command, start, In Terminal, my intent is to write $ start func1 subfunc myText, where func is a function in the start.sh file and subfunc is a function only in func that can only be called from in func. So $ start subfunc myText wouldn't be possible. I see that its possible to pass a function from another (Here), but only when both are in the outer scope of the start.sh file.



Basically:



start.sh:



function func(){
function subfunc(){
echo $1
}
}


and then in Terminal:
$ start func subfunc Hey prints Hey







bash






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 '18 at 22:02









Ulrich Eckhardt

12.7k11737




12.7k11737










asked Nov 13 '18 at 21:36









Jasper BraunJasper Braun

12716




12716








  • 1





    I don't think bash has nested function scopes like this.

    – Barmar
    Nov 13 '18 at 21:51






  • 2





    What is it supposed to achieve? Even if it works (it doesn't), Anyone who can't do start subfunc myText can still do start func subfunc Hey do still call subfunc anyway. What problem are you trying to solve with this?

    – P.P.
    Nov 13 '18 at 21:58













  • This feels like similar functionality to like an aws console command? I don't think bash is the right place to write this though. If you did, I think you would need to catch those arguments to variables and then perform logic based on what is in those variables if [$command = "func"] if [ $subcommand = "subfunc"] sort of thing... IT may help if you explained what you are trying to achieve though since it's not clear from your very not-working code.

    – JNevill
    Nov 13 '18 at 22:06













  • Sorry, I haven't used bash before and couldn't find great documentation for this. I was trying to create a custom hierarchy of commands to do something like nodecontroller nodestart node1 start, or something with a hierarchy of commands like this.

    – Jasper Braun
    Nov 14 '18 at 1:31














  • 1





    I don't think bash has nested function scopes like this.

    – Barmar
    Nov 13 '18 at 21:51






  • 2





    What is it supposed to achieve? Even if it works (it doesn't), Anyone who can't do start subfunc myText can still do start func subfunc Hey do still call subfunc anyway. What problem are you trying to solve with this?

    – P.P.
    Nov 13 '18 at 21:58













  • This feels like similar functionality to like an aws console command? I don't think bash is the right place to write this though. If you did, I think you would need to catch those arguments to variables and then perform logic based on what is in those variables if [$command = "func"] if [ $subcommand = "subfunc"] sort of thing... IT may help if you explained what you are trying to achieve though since it's not clear from your very not-working code.

    – JNevill
    Nov 13 '18 at 22:06













  • Sorry, I haven't used bash before and couldn't find great documentation for this. I was trying to create a custom hierarchy of commands to do something like nodecontroller nodestart node1 start, or something with a hierarchy of commands like this.

    – Jasper Braun
    Nov 14 '18 at 1:31








1




1





I don't think bash has nested function scopes like this.

– Barmar
Nov 13 '18 at 21:51





I don't think bash has nested function scopes like this.

– Barmar
Nov 13 '18 at 21:51




2




2





What is it supposed to achieve? Even if it works (it doesn't), Anyone who can't do start subfunc myText can still do start func subfunc Hey do still call subfunc anyway. What problem are you trying to solve with this?

– P.P.
Nov 13 '18 at 21:58







What is it supposed to achieve? Even if it works (it doesn't), Anyone who can't do start subfunc myText can still do start func subfunc Hey do still call subfunc anyway. What problem are you trying to solve with this?

– P.P.
Nov 13 '18 at 21:58















This feels like similar functionality to like an aws console command? I don't think bash is the right place to write this though. If you did, I think you would need to catch those arguments to variables and then perform logic based on what is in those variables if [$command = "func"] if [ $subcommand = "subfunc"] sort of thing... IT may help if you explained what you are trying to achieve though since it's not clear from your very not-working code.

– JNevill
Nov 13 '18 at 22:06







This feels like similar functionality to like an aws console command? I don't think bash is the right place to write this though. If you did, I think you would need to catch those arguments to variables and then perform logic based on what is in those variables if [$command = "func"] if [ $subcommand = "subfunc"] sort of thing... IT may help if you explained what you are trying to achieve though since it's not clear from your very not-working code.

– JNevill
Nov 13 '18 at 22:06















Sorry, I haven't used bash before and couldn't find great documentation for this. I was trying to create a custom hierarchy of commands to do something like nodecontroller nodestart node1 start, or something with a hierarchy of commands like this.

– Jasper Braun
Nov 14 '18 at 1:31





Sorry, I haven't used bash before and couldn't find great documentation for this. I was trying to create a custom hierarchy of commands to do something like nodecontroller nodestart node1 start, or something with a hierarchy of commands like this.

– Jasper Braun
Nov 14 '18 at 1:31












2 Answers
2






active

oldest

votes


















2














You need to call the functions, not only declare them:



func() {
subfunc() {
echo "$1"
}
"$@"
}
"$@"


However functions have no scopes, so once you declare the function inside another function it overwrites the previous declaration. So I would advise so to make each function and sub-function name unique.



f() {
f() {
echo in
}
echo out
}

f // will print 'out'
f // will print 'in'


Note that using function name() {} is accepted, but not really valid. Use name() { }, as function name {} is not specified by posix.






share|improve this answer































    2














    You don't need nested functions for this. I think this is an argument parsing problem:



    #!/bin/bash

    start() {
    case $1 in
    func) shift; do_func "$@" ;;
    *) echo "unknown subcommand"; exit 1 ;;
    esac
    }

    do_func() {
    case $1 in
    subfunc) shift; do_subfunc "$@" ;;
    *) echo "unknown sub-subcommand"; exit 1 ;;
    esac
    }

    do_subfunc() {
    echo "$1"
    }

    start "$@"


    Then



    $ ./start func foo
    unknown sub-subcommand
    $ ./start func subfunc 'hello world'
    hello world





    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      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: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      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%2fstackoverflow.com%2fquestions%2f53289859%2fbash-nested-private-functions%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









      2














      You need to call the functions, not only declare them:



      func() {
      subfunc() {
      echo "$1"
      }
      "$@"
      }
      "$@"


      However functions have no scopes, so once you declare the function inside another function it overwrites the previous declaration. So I would advise so to make each function and sub-function name unique.



      f() {
      f() {
      echo in
      }
      echo out
      }

      f // will print 'out'
      f // will print 'in'


      Note that using function name() {} is accepted, but not really valid. Use name() { }, as function name {} is not specified by posix.






      share|improve this answer




























        2














        You need to call the functions, not only declare them:



        func() {
        subfunc() {
        echo "$1"
        }
        "$@"
        }
        "$@"


        However functions have no scopes, so once you declare the function inside another function it overwrites the previous declaration. So I would advise so to make each function and sub-function name unique.



        f() {
        f() {
        echo in
        }
        echo out
        }

        f // will print 'out'
        f // will print 'in'


        Note that using function name() {} is accepted, but not really valid. Use name() { }, as function name {} is not specified by posix.






        share|improve this answer


























          2












          2








          2







          You need to call the functions, not only declare them:



          func() {
          subfunc() {
          echo "$1"
          }
          "$@"
          }
          "$@"


          However functions have no scopes, so once you declare the function inside another function it overwrites the previous declaration. So I would advise so to make each function and sub-function name unique.



          f() {
          f() {
          echo in
          }
          echo out
          }

          f // will print 'out'
          f // will print 'in'


          Note that using function name() {} is accepted, but not really valid. Use name() { }, as function name {} is not specified by posix.






          share|improve this answer













          You need to call the functions, not only declare them:



          func() {
          subfunc() {
          echo "$1"
          }
          "$@"
          }
          "$@"


          However functions have no scopes, so once you declare the function inside another function it overwrites the previous declaration. So I would advise so to make each function and sub-function name unique.



          f() {
          f() {
          echo in
          }
          echo out
          }

          f // will print 'out'
          f // will print 'in'


          Note that using function name() {} is accepted, but not really valid. Use name() { }, as function name {} is not specified by posix.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 13 '18 at 22:46









          Kamil CukKamil Cuk

          10.4k1527




          10.4k1527

























              2














              You don't need nested functions for this. I think this is an argument parsing problem:



              #!/bin/bash

              start() {
              case $1 in
              func) shift; do_func "$@" ;;
              *) echo "unknown subcommand"; exit 1 ;;
              esac
              }

              do_func() {
              case $1 in
              subfunc) shift; do_subfunc "$@" ;;
              *) echo "unknown sub-subcommand"; exit 1 ;;
              esac
              }

              do_subfunc() {
              echo "$1"
              }

              start "$@"


              Then



              $ ./start func foo
              unknown sub-subcommand
              $ ./start func subfunc 'hello world'
              hello world





              share|improve this answer




























                2














                You don't need nested functions for this. I think this is an argument parsing problem:



                #!/bin/bash

                start() {
                case $1 in
                func) shift; do_func "$@" ;;
                *) echo "unknown subcommand"; exit 1 ;;
                esac
                }

                do_func() {
                case $1 in
                subfunc) shift; do_subfunc "$@" ;;
                *) echo "unknown sub-subcommand"; exit 1 ;;
                esac
                }

                do_subfunc() {
                echo "$1"
                }

                start "$@"


                Then



                $ ./start func foo
                unknown sub-subcommand
                $ ./start func subfunc 'hello world'
                hello world





                share|improve this answer


























                  2












                  2








                  2







                  You don't need nested functions for this. I think this is an argument parsing problem:



                  #!/bin/bash

                  start() {
                  case $1 in
                  func) shift; do_func "$@" ;;
                  *) echo "unknown subcommand"; exit 1 ;;
                  esac
                  }

                  do_func() {
                  case $1 in
                  subfunc) shift; do_subfunc "$@" ;;
                  *) echo "unknown sub-subcommand"; exit 1 ;;
                  esac
                  }

                  do_subfunc() {
                  echo "$1"
                  }

                  start "$@"


                  Then



                  $ ./start func foo
                  unknown sub-subcommand
                  $ ./start func subfunc 'hello world'
                  hello world





                  share|improve this answer













                  You don't need nested functions for this. I think this is an argument parsing problem:



                  #!/bin/bash

                  start() {
                  case $1 in
                  func) shift; do_func "$@" ;;
                  *) echo "unknown subcommand"; exit 1 ;;
                  esac
                  }

                  do_func() {
                  case $1 in
                  subfunc) shift; do_subfunc "$@" ;;
                  *) echo "unknown sub-subcommand"; exit 1 ;;
                  esac
                  }

                  do_subfunc() {
                  echo "$1"
                  }

                  start "$@"


                  Then



                  $ ./start func foo
                  unknown sub-subcommand
                  $ ./start func subfunc 'hello world'
                  hello world






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 13 '18 at 23:04









                  glenn jackmanglenn jackman

                  167k26145237




                  167k26145237






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • 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%2fstackoverflow.com%2fquestions%2f53289859%2fbash-nested-private-functions%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

                      Florida Star v. B. J. F.

                      Danny Elfman

                      Lugert, Oklahoma