shell functions and variables with the same name












4















From Bash Manual:




Note that shell functions and variables with the same name may result in multiple identically-named entries in the environment
passed to the shell’s children. Care should be taken in cases where
this may cause a problem.




How can bash distinguish "shell functions and variables with the
same name" ?



$  func () { return 3; }; func=4; declare -p func; declare -f func;
declare -- func="4"
func ()
{
return 3
}


When does "multiple identically-named entries in the environment
passed to the shell’s children" happen?



What "care" should be taken for what problem?










share|improve this question





























    4















    From Bash Manual:




    Note that shell functions and variables with the same name may result in multiple identically-named entries in the environment
    passed to the shell’s children. Care should be taken in cases where
    this may cause a problem.




    How can bash distinguish "shell functions and variables with the
    same name" ?



    $  func () { return 3; }; func=4; declare -p func; declare -f func;
    declare -- func="4"
    func ()
    {
    return 3
    }


    When does "multiple identically-named entries in the environment
    passed to the shell’s children" happen?



    What "care" should be taken for what problem?










    share|improve this question



























      4












      4








      4


      2






      From Bash Manual:




      Note that shell functions and variables with the same name may result in multiple identically-named entries in the environment
      passed to the shell’s children. Care should be taken in cases where
      this may cause a problem.




      How can bash distinguish "shell functions and variables with the
      same name" ?



      $  func () { return 3; }; func=4; declare -p func; declare -f func;
      declare -- func="4"
      func ()
      {
      return 3
      }


      When does "multiple identically-named entries in the environment
      passed to the shell’s children" happen?



      What "care" should be taken for what problem?










      share|improve this question
















      From Bash Manual:




      Note that shell functions and variables with the same name may result in multiple identically-named entries in the environment
      passed to the shell’s children. Care should be taken in cases where
      this may cause a problem.




      How can bash distinguish "shell functions and variables with the
      same name" ?



      $  func () { return 3; }; func=4; declare -p func; declare -f func;
      declare -- func="4"
      func ()
      {
      return 3
      }


      When does "multiple identically-named entries in the environment
      passed to the shell’s children" happen?



      What "care" should be taken for what problem?







      bash environment-variables function






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Mar 5 at 22:28









      codeforester

      380317




      380317










      asked Jul 30 '17 at 0:41









      TimTim

      28.3k78269490




      28.3k78269490






















          2 Answers
          2






          active

          oldest

          votes


















          4














          The general story: separate namespaces



          Generally shells distinguish between variables and functions because they're used in different contexts. In a nutshell, a name is a variable name if it appears after a $, or as an argument to builtins such as export (without -f) and unset (without -f). A name is a function name if it appears as a command (after alias expansion) or as an argument to export -f, unset -f, etc.



          Variables can be exported to the environment. The name of the environment variable is the same as the shell variable (and the values are the same too).



          With older bash: confusion due to function export



          Bash, unlike most other shells, can also export functions to the environment. Since there's no type indication in the environment, there's no way to recognize whether an entry in the environment is a function or not, other than by analyzing the name or the value of the environment variable.



          Older versions of bash stored a function in the environment using the function's name as the name, and something that looks like the function definition as the function's value. For example:



          bash-4.1$ foobar () { echo foobar; }
          bash-4.1$ export -f foobar
          bash-4.1$ env |grep -A1 foobar
          foobar=() { echo foobar
          }
          bash-4.1$


          Note that there's no way to distinguish a function whose code is { echo foobar; } from a variable whose value is () { echo foobar␤} (where is a newline character). This turned out to be a bad design decision.



          Sometimes shell scripts get invoked with environment variables whose value is under control of a potentially hostile entity. CGI scripts, for example. Bash's function export/import feature allowed injecting functions that way. For example executing the script



          #!/bin/bash
          ls


          from a remote request is safe as long as the environment doesn't contain variables with a certain name (such as PATH). But if the request can set the environment variable ls to () { cat /etc/passwd; } then bash would happily execute cat /etc/passwd since that's the body of the ls function.



          With newer bash: confusion mostly alleviated



          This security vulnerability was discovered by Stéphane Chazelas as one of the aspects of the Shellshock bug. In post-Shellshock versions of bash, exported functions are identified by their name rather than by their content.



          bash-4.3$ foobar () { echo foobar; }
          bash-4.3$ export -f foobar
          bash-4.3$ env |grep -A1 foobar
          BASH_FUNC_foobar%%=() { echo foobar
          }


          There is no security issue now because names like BASH_FUNC_foobar%% are not commonly used as command names, and can be filtered out by interfaces that allow passing environment variables. It's technically possible to have a % character in the name of an environment variable (that's what makes modern bash's exported functions work), but normally people don't do this because shells don't accept % in the name of a variable.



          The sentence in the bash manual refers to the old (pre-Shellshock) behavior. It should be updated or removed. With modern bash versions, there is no ambiguity in the environment if you assume that environment variables won't have a name ending in %%.






          share|improve this answer


























          • @Tim Holy bold overflow! You really need to learn a full paragraph where half the text isn't bolded.

            – Gilles
            Aug 5 '17 at 10:59











          • "Variables can be exported to the environment. The name of the environment variable is the same as the shell variable (and the values are the same too)." When a shell variable is exported to the environment, is it only to assign the export attribute of the shell variable, and the shell variable and its corresponding environment variable are the same object instead of different copies? By "the name of the environment variable is the same as the shell variable (and the values are the same too)", do you mean the shell variable and its corresponding environment variable are separate copies?

            – Tim
            Aug 5 '17 at 11:06













          • I really think that my reorganization of your reply make it more readable to me.

            – Tim
            Aug 5 '17 at 11:08



















          2














          A similar thing happens in Emacs Lisp. It has two namespaces, one for functions and one for variables. If you dereference a symbol in function context ((var)) it will call the function, if you defreference it in variable context (var i.e. without the brackets) it will give you the variable. For example:



          (defun myvar (myvar)
          "adds 3 to MYVAR"
          (+ 3 myvar))
          (setq myvar 7)
          (message (myvar myvar))


          Will execute the function myvar with the argument 7 which is the dereference of the variable myvar.



          This can become very confusing if you are not used to it.



          After looking at your question and making the tests for bash I'm surprised that it presents the same behaviour. Translating the ELisp from above into bash:



          [grochmal@phoenix ~]$ myvar () { echo $(($1+3)); }
          [grochmal@phoenix ~]$ myvar=7
          [grochmal@phoenix ~]$ myvar $myvar
          10


          Bash is a little less confusing in this than ELisp because you need the $ to mark the variable. Still, this may look like a declare of a single name containing two things. See:



          [grochmal@phoenix ~]$ declare -p myvar
          declare -x myvar="7"
          [grochmal@phoenix ~]$ declare -f myvar
          myvar ()
          {
          echo $(($1+3))
          }


          (P.S. Once you get used to the existence of two namespaces, e.g. you program in ELisp for a while, this stops becoming confusing)






          share|improve this answer



















          • 1





            You've completely missed the case the manual refers to, which is when variables are communicated through the environment. In all fairness, that case no longer applies to modern versions of bash (post-Shellshock), which encode functions differently. But even so the reference to Lisp is hard to follow even for people who are familiar with Lisp. It would be much better to explain this in an autonomous way.

            – Gilles
            Jul 30 '17 at 22:54











          • @Gilles - It is not that I missed it, I simply did not know it :) . I missed that part of Shellshock altogether and then attempted to test this on a post-shellshock bash only. I actually need to thank you for clearing that up.

            – grochmal
            Jul 31 '17 at 9:41












          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%2f382660%2fshell-functions-and-variables-with-the-same-name%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









          4














          The general story: separate namespaces



          Generally shells distinguish between variables and functions because they're used in different contexts. In a nutshell, a name is a variable name if it appears after a $, or as an argument to builtins such as export (without -f) and unset (without -f). A name is a function name if it appears as a command (after alias expansion) or as an argument to export -f, unset -f, etc.



          Variables can be exported to the environment. The name of the environment variable is the same as the shell variable (and the values are the same too).



          With older bash: confusion due to function export



          Bash, unlike most other shells, can also export functions to the environment. Since there's no type indication in the environment, there's no way to recognize whether an entry in the environment is a function or not, other than by analyzing the name or the value of the environment variable.



          Older versions of bash stored a function in the environment using the function's name as the name, and something that looks like the function definition as the function's value. For example:



          bash-4.1$ foobar () { echo foobar; }
          bash-4.1$ export -f foobar
          bash-4.1$ env |grep -A1 foobar
          foobar=() { echo foobar
          }
          bash-4.1$


          Note that there's no way to distinguish a function whose code is { echo foobar; } from a variable whose value is () { echo foobar␤} (where is a newline character). This turned out to be a bad design decision.



          Sometimes shell scripts get invoked with environment variables whose value is under control of a potentially hostile entity. CGI scripts, for example. Bash's function export/import feature allowed injecting functions that way. For example executing the script



          #!/bin/bash
          ls


          from a remote request is safe as long as the environment doesn't contain variables with a certain name (such as PATH). But if the request can set the environment variable ls to () { cat /etc/passwd; } then bash would happily execute cat /etc/passwd since that's the body of the ls function.



          With newer bash: confusion mostly alleviated



          This security vulnerability was discovered by Stéphane Chazelas as one of the aspects of the Shellshock bug. In post-Shellshock versions of bash, exported functions are identified by their name rather than by their content.



          bash-4.3$ foobar () { echo foobar; }
          bash-4.3$ export -f foobar
          bash-4.3$ env |grep -A1 foobar
          BASH_FUNC_foobar%%=() { echo foobar
          }


          There is no security issue now because names like BASH_FUNC_foobar%% are not commonly used as command names, and can be filtered out by interfaces that allow passing environment variables. It's technically possible to have a % character in the name of an environment variable (that's what makes modern bash's exported functions work), but normally people don't do this because shells don't accept % in the name of a variable.



          The sentence in the bash manual refers to the old (pre-Shellshock) behavior. It should be updated or removed. With modern bash versions, there is no ambiguity in the environment if you assume that environment variables won't have a name ending in %%.






          share|improve this answer


























          • @Tim Holy bold overflow! You really need to learn a full paragraph where half the text isn't bolded.

            – Gilles
            Aug 5 '17 at 10:59











          • "Variables can be exported to the environment. The name of the environment variable is the same as the shell variable (and the values are the same too)." When a shell variable is exported to the environment, is it only to assign the export attribute of the shell variable, and the shell variable and its corresponding environment variable are the same object instead of different copies? By "the name of the environment variable is the same as the shell variable (and the values are the same too)", do you mean the shell variable and its corresponding environment variable are separate copies?

            – Tim
            Aug 5 '17 at 11:06













          • I really think that my reorganization of your reply make it more readable to me.

            – Tim
            Aug 5 '17 at 11:08
















          4














          The general story: separate namespaces



          Generally shells distinguish between variables and functions because they're used in different contexts. In a nutshell, a name is a variable name if it appears after a $, or as an argument to builtins such as export (without -f) and unset (without -f). A name is a function name if it appears as a command (after alias expansion) or as an argument to export -f, unset -f, etc.



          Variables can be exported to the environment. The name of the environment variable is the same as the shell variable (and the values are the same too).



          With older bash: confusion due to function export



          Bash, unlike most other shells, can also export functions to the environment. Since there's no type indication in the environment, there's no way to recognize whether an entry in the environment is a function or not, other than by analyzing the name or the value of the environment variable.



          Older versions of bash stored a function in the environment using the function's name as the name, and something that looks like the function definition as the function's value. For example:



          bash-4.1$ foobar () { echo foobar; }
          bash-4.1$ export -f foobar
          bash-4.1$ env |grep -A1 foobar
          foobar=() { echo foobar
          }
          bash-4.1$


          Note that there's no way to distinguish a function whose code is { echo foobar; } from a variable whose value is () { echo foobar␤} (where is a newline character). This turned out to be a bad design decision.



          Sometimes shell scripts get invoked with environment variables whose value is under control of a potentially hostile entity. CGI scripts, for example. Bash's function export/import feature allowed injecting functions that way. For example executing the script



          #!/bin/bash
          ls


          from a remote request is safe as long as the environment doesn't contain variables with a certain name (such as PATH). But if the request can set the environment variable ls to () { cat /etc/passwd; } then bash would happily execute cat /etc/passwd since that's the body of the ls function.



          With newer bash: confusion mostly alleviated



          This security vulnerability was discovered by Stéphane Chazelas as one of the aspects of the Shellshock bug. In post-Shellshock versions of bash, exported functions are identified by their name rather than by their content.



          bash-4.3$ foobar () { echo foobar; }
          bash-4.3$ export -f foobar
          bash-4.3$ env |grep -A1 foobar
          BASH_FUNC_foobar%%=() { echo foobar
          }


          There is no security issue now because names like BASH_FUNC_foobar%% are not commonly used as command names, and can be filtered out by interfaces that allow passing environment variables. It's technically possible to have a % character in the name of an environment variable (that's what makes modern bash's exported functions work), but normally people don't do this because shells don't accept % in the name of a variable.



          The sentence in the bash manual refers to the old (pre-Shellshock) behavior. It should be updated or removed. With modern bash versions, there is no ambiguity in the environment if you assume that environment variables won't have a name ending in %%.






          share|improve this answer


























          • @Tim Holy bold overflow! You really need to learn a full paragraph where half the text isn't bolded.

            – Gilles
            Aug 5 '17 at 10:59











          • "Variables can be exported to the environment. The name of the environment variable is the same as the shell variable (and the values are the same too)." When a shell variable is exported to the environment, is it only to assign the export attribute of the shell variable, and the shell variable and its corresponding environment variable are the same object instead of different copies? By "the name of the environment variable is the same as the shell variable (and the values are the same too)", do you mean the shell variable and its corresponding environment variable are separate copies?

            – Tim
            Aug 5 '17 at 11:06













          • I really think that my reorganization of your reply make it more readable to me.

            – Tim
            Aug 5 '17 at 11:08














          4












          4








          4







          The general story: separate namespaces



          Generally shells distinguish between variables and functions because they're used in different contexts. In a nutshell, a name is a variable name if it appears after a $, or as an argument to builtins such as export (without -f) and unset (without -f). A name is a function name if it appears as a command (after alias expansion) or as an argument to export -f, unset -f, etc.



          Variables can be exported to the environment. The name of the environment variable is the same as the shell variable (and the values are the same too).



          With older bash: confusion due to function export



          Bash, unlike most other shells, can also export functions to the environment. Since there's no type indication in the environment, there's no way to recognize whether an entry in the environment is a function or not, other than by analyzing the name or the value of the environment variable.



          Older versions of bash stored a function in the environment using the function's name as the name, and something that looks like the function definition as the function's value. For example:



          bash-4.1$ foobar () { echo foobar; }
          bash-4.1$ export -f foobar
          bash-4.1$ env |grep -A1 foobar
          foobar=() { echo foobar
          }
          bash-4.1$


          Note that there's no way to distinguish a function whose code is { echo foobar; } from a variable whose value is () { echo foobar␤} (where is a newline character). This turned out to be a bad design decision.



          Sometimes shell scripts get invoked with environment variables whose value is under control of a potentially hostile entity. CGI scripts, for example. Bash's function export/import feature allowed injecting functions that way. For example executing the script



          #!/bin/bash
          ls


          from a remote request is safe as long as the environment doesn't contain variables with a certain name (such as PATH). But if the request can set the environment variable ls to () { cat /etc/passwd; } then bash would happily execute cat /etc/passwd since that's the body of the ls function.



          With newer bash: confusion mostly alleviated



          This security vulnerability was discovered by Stéphane Chazelas as one of the aspects of the Shellshock bug. In post-Shellshock versions of bash, exported functions are identified by their name rather than by their content.



          bash-4.3$ foobar () { echo foobar; }
          bash-4.3$ export -f foobar
          bash-4.3$ env |grep -A1 foobar
          BASH_FUNC_foobar%%=() { echo foobar
          }


          There is no security issue now because names like BASH_FUNC_foobar%% are not commonly used as command names, and can be filtered out by interfaces that allow passing environment variables. It's technically possible to have a % character in the name of an environment variable (that's what makes modern bash's exported functions work), but normally people don't do this because shells don't accept % in the name of a variable.



          The sentence in the bash manual refers to the old (pre-Shellshock) behavior. It should be updated or removed. With modern bash versions, there is no ambiguity in the environment if you assume that environment variables won't have a name ending in %%.






          share|improve this answer















          The general story: separate namespaces



          Generally shells distinguish between variables and functions because they're used in different contexts. In a nutshell, a name is a variable name if it appears after a $, or as an argument to builtins such as export (without -f) and unset (without -f). A name is a function name if it appears as a command (after alias expansion) or as an argument to export -f, unset -f, etc.



          Variables can be exported to the environment. The name of the environment variable is the same as the shell variable (and the values are the same too).



          With older bash: confusion due to function export



          Bash, unlike most other shells, can also export functions to the environment. Since there's no type indication in the environment, there's no way to recognize whether an entry in the environment is a function or not, other than by analyzing the name or the value of the environment variable.



          Older versions of bash stored a function in the environment using the function's name as the name, and something that looks like the function definition as the function's value. For example:



          bash-4.1$ foobar () { echo foobar; }
          bash-4.1$ export -f foobar
          bash-4.1$ env |grep -A1 foobar
          foobar=() { echo foobar
          }
          bash-4.1$


          Note that there's no way to distinguish a function whose code is { echo foobar; } from a variable whose value is () { echo foobar␤} (where is a newline character). This turned out to be a bad design decision.



          Sometimes shell scripts get invoked with environment variables whose value is under control of a potentially hostile entity. CGI scripts, for example. Bash's function export/import feature allowed injecting functions that way. For example executing the script



          #!/bin/bash
          ls


          from a remote request is safe as long as the environment doesn't contain variables with a certain name (such as PATH). But if the request can set the environment variable ls to () { cat /etc/passwd; } then bash would happily execute cat /etc/passwd since that's the body of the ls function.



          With newer bash: confusion mostly alleviated



          This security vulnerability was discovered by Stéphane Chazelas as one of the aspects of the Shellshock bug. In post-Shellshock versions of bash, exported functions are identified by their name rather than by their content.



          bash-4.3$ foobar () { echo foobar; }
          bash-4.3$ export -f foobar
          bash-4.3$ env |grep -A1 foobar
          BASH_FUNC_foobar%%=() { echo foobar
          }


          There is no security issue now because names like BASH_FUNC_foobar%% are not commonly used as command names, and can be filtered out by interfaces that allow passing environment variables. It's technically possible to have a % character in the name of an environment variable (that's what makes modern bash's exported functions work), but normally people don't do this because shells don't accept % in the name of a variable.



          The sentence in the bash manual refers to the old (pre-Shellshock) behavior. It should be updated or removed. With modern bash versions, there is no ambiguity in the environment if you assume that environment variables won't have a name ending in %%.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Aug 5 '17 at 10:58

























          answered Jul 31 '17 at 0:37









          GillesGilles

          545k12811071622




          545k12811071622













          • @Tim Holy bold overflow! You really need to learn a full paragraph where half the text isn't bolded.

            – Gilles
            Aug 5 '17 at 10:59











          • "Variables can be exported to the environment. The name of the environment variable is the same as the shell variable (and the values are the same too)." When a shell variable is exported to the environment, is it only to assign the export attribute of the shell variable, and the shell variable and its corresponding environment variable are the same object instead of different copies? By "the name of the environment variable is the same as the shell variable (and the values are the same too)", do you mean the shell variable and its corresponding environment variable are separate copies?

            – Tim
            Aug 5 '17 at 11:06













          • I really think that my reorganization of your reply make it more readable to me.

            – Tim
            Aug 5 '17 at 11:08



















          • @Tim Holy bold overflow! You really need to learn a full paragraph where half the text isn't bolded.

            – Gilles
            Aug 5 '17 at 10:59











          • "Variables can be exported to the environment. The name of the environment variable is the same as the shell variable (and the values are the same too)." When a shell variable is exported to the environment, is it only to assign the export attribute of the shell variable, and the shell variable and its corresponding environment variable are the same object instead of different copies? By "the name of the environment variable is the same as the shell variable (and the values are the same too)", do you mean the shell variable and its corresponding environment variable are separate copies?

            – Tim
            Aug 5 '17 at 11:06













          • I really think that my reorganization of your reply make it more readable to me.

            – Tim
            Aug 5 '17 at 11:08

















          @Tim Holy bold overflow! You really need to learn a full paragraph where half the text isn't bolded.

          – Gilles
          Aug 5 '17 at 10:59





          @Tim Holy bold overflow! You really need to learn a full paragraph where half the text isn't bolded.

          – Gilles
          Aug 5 '17 at 10:59













          "Variables can be exported to the environment. The name of the environment variable is the same as the shell variable (and the values are the same too)." When a shell variable is exported to the environment, is it only to assign the export attribute of the shell variable, and the shell variable and its corresponding environment variable are the same object instead of different copies? By "the name of the environment variable is the same as the shell variable (and the values are the same too)", do you mean the shell variable and its corresponding environment variable are separate copies?

          – Tim
          Aug 5 '17 at 11:06







          "Variables can be exported to the environment. The name of the environment variable is the same as the shell variable (and the values are the same too)." When a shell variable is exported to the environment, is it only to assign the export attribute of the shell variable, and the shell variable and its corresponding environment variable are the same object instead of different copies? By "the name of the environment variable is the same as the shell variable (and the values are the same too)", do you mean the shell variable and its corresponding environment variable are separate copies?

          – Tim
          Aug 5 '17 at 11:06















          I really think that my reorganization of your reply make it more readable to me.

          – Tim
          Aug 5 '17 at 11:08





          I really think that my reorganization of your reply make it more readable to me.

          – Tim
          Aug 5 '17 at 11:08













          2














          A similar thing happens in Emacs Lisp. It has two namespaces, one for functions and one for variables. If you dereference a symbol in function context ((var)) it will call the function, if you defreference it in variable context (var i.e. without the brackets) it will give you the variable. For example:



          (defun myvar (myvar)
          "adds 3 to MYVAR"
          (+ 3 myvar))
          (setq myvar 7)
          (message (myvar myvar))


          Will execute the function myvar with the argument 7 which is the dereference of the variable myvar.



          This can become very confusing if you are not used to it.



          After looking at your question and making the tests for bash I'm surprised that it presents the same behaviour. Translating the ELisp from above into bash:



          [grochmal@phoenix ~]$ myvar () { echo $(($1+3)); }
          [grochmal@phoenix ~]$ myvar=7
          [grochmal@phoenix ~]$ myvar $myvar
          10


          Bash is a little less confusing in this than ELisp because you need the $ to mark the variable. Still, this may look like a declare of a single name containing two things. See:



          [grochmal@phoenix ~]$ declare -p myvar
          declare -x myvar="7"
          [grochmal@phoenix ~]$ declare -f myvar
          myvar ()
          {
          echo $(($1+3))
          }


          (P.S. Once you get used to the existence of two namespaces, e.g. you program in ELisp for a while, this stops becoming confusing)






          share|improve this answer



















          • 1





            You've completely missed the case the manual refers to, which is when variables are communicated through the environment. In all fairness, that case no longer applies to modern versions of bash (post-Shellshock), which encode functions differently. But even so the reference to Lisp is hard to follow even for people who are familiar with Lisp. It would be much better to explain this in an autonomous way.

            – Gilles
            Jul 30 '17 at 22:54











          • @Gilles - It is not that I missed it, I simply did not know it :) . I missed that part of Shellshock altogether and then attempted to test this on a post-shellshock bash only. I actually need to thank you for clearing that up.

            – grochmal
            Jul 31 '17 at 9:41
















          2














          A similar thing happens in Emacs Lisp. It has two namespaces, one for functions and one for variables. If you dereference a symbol in function context ((var)) it will call the function, if you defreference it in variable context (var i.e. without the brackets) it will give you the variable. For example:



          (defun myvar (myvar)
          "adds 3 to MYVAR"
          (+ 3 myvar))
          (setq myvar 7)
          (message (myvar myvar))


          Will execute the function myvar with the argument 7 which is the dereference of the variable myvar.



          This can become very confusing if you are not used to it.



          After looking at your question and making the tests for bash I'm surprised that it presents the same behaviour. Translating the ELisp from above into bash:



          [grochmal@phoenix ~]$ myvar () { echo $(($1+3)); }
          [grochmal@phoenix ~]$ myvar=7
          [grochmal@phoenix ~]$ myvar $myvar
          10


          Bash is a little less confusing in this than ELisp because you need the $ to mark the variable. Still, this may look like a declare of a single name containing two things. See:



          [grochmal@phoenix ~]$ declare -p myvar
          declare -x myvar="7"
          [grochmal@phoenix ~]$ declare -f myvar
          myvar ()
          {
          echo $(($1+3))
          }


          (P.S. Once you get used to the existence of two namespaces, e.g. you program in ELisp for a while, this stops becoming confusing)






          share|improve this answer



















          • 1





            You've completely missed the case the manual refers to, which is when variables are communicated through the environment. In all fairness, that case no longer applies to modern versions of bash (post-Shellshock), which encode functions differently. But even so the reference to Lisp is hard to follow even for people who are familiar with Lisp. It would be much better to explain this in an autonomous way.

            – Gilles
            Jul 30 '17 at 22:54











          • @Gilles - It is not that I missed it, I simply did not know it :) . I missed that part of Shellshock altogether and then attempted to test this on a post-shellshock bash only. I actually need to thank you for clearing that up.

            – grochmal
            Jul 31 '17 at 9:41














          2












          2








          2







          A similar thing happens in Emacs Lisp. It has two namespaces, one for functions and one for variables. If you dereference a symbol in function context ((var)) it will call the function, if you defreference it in variable context (var i.e. without the brackets) it will give you the variable. For example:



          (defun myvar (myvar)
          "adds 3 to MYVAR"
          (+ 3 myvar))
          (setq myvar 7)
          (message (myvar myvar))


          Will execute the function myvar with the argument 7 which is the dereference of the variable myvar.



          This can become very confusing if you are not used to it.



          After looking at your question and making the tests for bash I'm surprised that it presents the same behaviour. Translating the ELisp from above into bash:



          [grochmal@phoenix ~]$ myvar () { echo $(($1+3)); }
          [grochmal@phoenix ~]$ myvar=7
          [grochmal@phoenix ~]$ myvar $myvar
          10


          Bash is a little less confusing in this than ELisp because you need the $ to mark the variable. Still, this may look like a declare of a single name containing two things. See:



          [grochmal@phoenix ~]$ declare -p myvar
          declare -x myvar="7"
          [grochmal@phoenix ~]$ declare -f myvar
          myvar ()
          {
          echo $(($1+3))
          }


          (P.S. Once you get used to the existence of two namespaces, e.g. you program in ELisp for a while, this stops becoming confusing)






          share|improve this answer













          A similar thing happens in Emacs Lisp. It has two namespaces, one for functions and one for variables. If you dereference a symbol in function context ((var)) it will call the function, if you defreference it in variable context (var i.e. without the brackets) it will give you the variable. For example:



          (defun myvar (myvar)
          "adds 3 to MYVAR"
          (+ 3 myvar))
          (setq myvar 7)
          (message (myvar myvar))


          Will execute the function myvar with the argument 7 which is the dereference of the variable myvar.



          This can become very confusing if you are not used to it.



          After looking at your question and making the tests for bash I'm surprised that it presents the same behaviour. Translating the ELisp from above into bash:



          [grochmal@phoenix ~]$ myvar () { echo $(($1+3)); }
          [grochmal@phoenix ~]$ myvar=7
          [grochmal@phoenix ~]$ myvar $myvar
          10


          Bash is a little less confusing in this than ELisp because you need the $ to mark the variable. Still, this may look like a declare of a single name containing two things. See:



          [grochmal@phoenix ~]$ declare -p myvar
          declare -x myvar="7"
          [grochmal@phoenix ~]$ declare -f myvar
          myvar ()
          {
          echo $(($1+3))
          }


          (P.S. Once you get used to the existence of two namespaces, e.g. you program in ELisp for a while, this stops becoming confusing)







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jul 30 '17 at 1:26









          grochmalgrochmal

          5,92131647




          5,92131647








          • 1





            You've completely missed the case the manual refers to, which is when variables are communicated through the environment. In all fairness, that case no longer applies to modern versions of bash (post-Shellshock), which encode functions differently. But even so the reference to Lisp is hard to follow even for people who are familiar with Lisp. It would be much better to explain this in an autonomous way.

            – Gilles
            Jul 30 '17 at 22:54











          • @Gilles - It is not that I missed it, I simply did not know it :) . I missed that part of Shellshock altogether and then attempted to test this on a post-shellshock bash only. I actually need to thank you for clearing that up.

            – grochmal
            Jul 31 '17 at 9:41














          • 1





            You've completely missed the case the manual refers to, which is when variables are communicated through the environment. In all fairness, that case no longer applies to modern versions of bash (post-Shellshock), which encode functions differently. But even so the reference to Lisp is hard to follow even for people who are familiar with Lisp. It would be much better to explain this in an autonomous way.

            – Gilles
            Jul 30 '17 at 22:54











          • @Gilles - It is not that I missed it, I simply did not know it :) . I missed that part of Shellshock altogether and then attempted to test this on a post-shellshock bash only. I actually need to thank you for clearing that up.

            – grochmal
            Jul 31 '17 at 9:41








          1




          1





          You've completely missed the case the manual refers to, which is when variables are communicated through the environment. In all fairness, that case no longer applies to modern versions of bash (post-Shellshock), which encode functions differently. But even so the reference to Lisp is hard to follow even for people who are familiar with Lisp. It would be much better to explain this in an autonomous way.

          – Gilles
          Jul 30 '17 at 22:54





          You've completely missed the case the manual refers to, which is when variables are communicated through the environment. In all fairness, that case no longer applies to modern versions of bash (post-Shellshock), which encode functions differently. But even so the reference to Lisp is hard to follow even for people who are familiar with Lisp. It would be much better to explain this in an autonomous way.

          – Gilles
          Jul 30 '17 at 22:54













          @Gilles - It is not that I missed it, I simply did not know it :) . I missed that part of Shellshock altogether and then attempted to test this on a post-shellshock bash only. I actually need to thank you for clearing that up.

          – grochmal
          Jul 31 '17 at 9:41





          @Gilles - It is not that I missed it, I simply did not know it :) . I missed that part of Shellshock altogether and then attempted to test this on a post-shellshock bash only. I actually need to thank you for clearing that up.

          – grochmal
          Jul 31 '17 at 9:41


















          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%2f382660%2fshell-functions-and-variables-with-the-same-name%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 reconfigure Docker Trusted Registry 2.x.x to use CEPH FS mount instead of NFS and other traditional...

          is 'sed' thread safe

          How to make a Squid Proxy server?