Why can I not use variables as prefix to a command to set environment variables?











up vote
3
down vote

favorite
1












Normally, it is possible to set an environment variable for a command by prefixing it like so:



hello=hi bash -c 'echo $hello'


I also know that we can use a variable to substitute any part of a command invocation like the following:



$ cmd=bash
$ $cmd -c "echo hi" # equivalent to bash -c "echo hi"


I was very surprised to find out that you cannot use a variable to prefix a command to set an environment variable. Test case:



$ prefix=hello=hi
$ echo $prefix # prints hello=hi
$ $prefix bash -c 'echo $hello'
hello=hi: command not found


Why can I not set the environment variable using a variable? Is the prefix part a special part? I was able to get it working by using eval in front, but I still do not understand why. I am using bash 4.4.










share|improve this question




























    up vote
    3
    down vote

    favorite
    1












    Normally, it is possible to set an environment variable for a command by prefixing it like so:



    hello=hi bash -c 'echo $hello'


    I also know that we can use a variable to substitute any part of a command invocation like the following:



    $ cmd=bash
    $ $cmd -c "echo hi" # equivalent to bash -c "echo hi"


    I was very surprised to find out that you cannot use a variable to prefix a command to set an environment variable. Test case:



    $ prefix=hello=hi
    $ echo $prefix # prints hello=hi
    $ $prefix bash -c 'echo $hello'
    hello=hi: command not found


    Why can I not set the environment variable using a variable? Is the prefix part a special part? I was able to get it working by using eval in front, but I still do not understand why. I am using bash 4.4.










    share|improve this question


























      up vote
      3
      down vote

      favorite
      1









      up vote
      3
      down vote

      favorite
      1






      1





      Normally, it is possible to set an environment variable for a command by prefixing it like so:



      hello=hi bash -c 'echo $hello'


      I also know that we can use a variable to substitute any part of a command invocation like the following:



      $ cmd=bash
      $ $cmd -c "echo hi" # equivalent to bash -c "echo hi"


      I was very surprised to find out that you cannot use a variable to prefix a command to set an environment variable. Test case:



      $ prefix=hello=hi
      $ echo $prefix # prints hello=hi
      $ $prefix bash -c 'echo $hello'
      hello=hi: command not found


      Why can I not set the environment variable using a variable? Is the prefix part a special part? I was able to get it working by using eval in front, but I still do not understand why. I am using bash 4.4.










      share|improve this question















      Normally, it is possible to set an environment variable for a command by prefixing it like so:



      hello=hi bash -c 'echo $hello'


      I also know that we can use a variable to substitute any part of a command invocation like the following:



      $ cmd=bash
      $ $cmd -c "echo hi" # equivalent to bash -c "echo hi"


      I was very surprised to find out that you cannot use a variable to prefix a command to set an environment variable. Test case:



      $ prefix=hello=hi
      $ echo $prefix # prints hello=hi
      $ $prefix bash -c 'echo $hello'
      hello=hi: command not found


      Why can I not set the environment variable using a variable? Is the prefix part a special part? I was able to get it working by using eval in front, but I still do not understand why. I am using bash 4.4.







      bash environment-variables variable






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 3 hours ago









      Jeff Schaller

      38.1k1053124




      38.1k1053124










      asked 3 hours ago









      wbkang

      1183




      1183






















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          3
          down vote













          I suspect this is the part of the sequence that's catching you:




          The words that are not variable assignments or redirections are expanded (see Shell Expansions). If any words remain after expansion, the first word is taken to be the name of the command and the remaining words are the arguments




          That's from the Bash reference manual in the section on Simple Command Expansion.



          In the cmd=bash example, no environment variables are set, and bash processes the command line up through parameter expansion, leaving bash -c "echo hi".



          In the prefix=hello=hi example, there are again no variable assignments in the first pass, so processing continues to parameter expansion, resulting in a first word of hello=hi.



          Once the variable assignments have been processed, they are not re-processed during command execution.



          See the processing and its results under set -x:



          $ prefix=hello=hi
          + prefix=hello=hi
          $ $prefix bash -c 'echo $hello'
          + hello=hi bash -c 'echo $hello'
          -bash: hello=hi: command not found
          $ hello=42 bash -c 'echo $hello'
          + hello=42
          + bash -c 'echo $hello'
          42





          share|improve this answer

















          • 1




            Similarly, $foo=bar bash -c ... won't work, because $foo=bar isn't a variable assignment (whatever be the value of $foo), because $foo=bar doesn't fit the name=value pattern for variable assignment.
            – muru
            3 hours ago











          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%2f490057%2fwhy-can-i-not-use-variables-as-prefix-to-a-command-to-set-environment-variables%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          3
          down vote













          I suspect this is the part of the sequence that's catching you:




          The words that are not variable assignments or redirections are expanded (see Shell Expansions). If any words remain after expansion, the first word is taken to be the name of the command and the remaining words are the arguments




          That's from the Bash reference manual in the section on Simple Command Expansion.



          In the cmd=bash example, no environment variables are set, and bash processes the command line up through parameter expansion, leaving bash -c "echo hi".



          In the prefix=hello=hi example, there are again no variable assignments in the first pass, so processing continues to parameter expansion, resulting in a first word of hello=hi.



          Once the variable assignments have been processed, they are not re-processed during command execution.



          See the processing and its results under set -x:



          $ prefix=hello=hi
          + prefix=hello=hi
          $ $prefix bash -c 'echo $hello'
          + hello=hi bash -c 'echo $hello'
          -bash: hello=hi: command not found
          $ hello=42 bash -c 'echo $hello'
          + hello=42
          + bash -c 'echo $hello'
          42





          share|improve this answer

















          • 1




            Similarly, $foo=bar bash -c ... won't work, because $foo=bar isn't a variable assignment (whatever be the value of $foo), because $foo=bar doesn't fit the name=value pattern for variable assignment.
            – muru
            3 hours ago















          up vote
          3
          down vote













          I suspect this is the part of the sequence that's catching you:




          The words that are not variable assignments or redirections are expanded (see Shell Expansions). If any words remain after expansion, the first word is taken to be the name of the command and the remaining words are the arguments




          That's from the Bash reference manual in the section on Simple Command Expansion.



          In the cmd=bash example, no environment variables are set, and bash processes the command line up through parameter expansion, leaving bash -c "echo hi".



          In the prefix=hello=hi example, there are again no variable assignments in the first pass, so processing continues to parameter expansion, resulting in a first word of hello=hi.



          Once the variable assignments have been processed, they are not re-processed during command execution.



          See the processing and its results under set -x:



          $ prefix=hello=hi
          + prefix=hello=hi
          $ $prefix bash -c 'echo $hello'
          + hello=hi bash -c 'echo $hello'
          -bash: hello=hi: command not found
          $ hello=42 bash -c 'echo $hello'
          + hello=42
          + bash -c 'echo $hello'
          42





          share|improve this answer

















          • 1




            Similarly, $foo=bar bash -c ... won't work, because $foo=bar isn't a variable assignment (whatever be the value of $foo), because $foo=bar doesn't fit the name=value pattern for variable assignment.
            – muru
            3 hours ago













          up vote
          3
          down vote










          up vote
          3
          down vote









          I suspect this is the part of the sequence that's catching you:




          The words that are not variable assignments or redirections are expanded (see Shell Expansions). If any words remain after expansion, the first word is taken to be the name of the command and the remaining words are the arguments




          That's from the Bash reference manual in the section on Simple Command Expansion.



          In the cmd=bash example, no environment variables are set, and bash processes the command line up through parameter expansion, leaving bash -c "echo hi".



          In the prefix=hello=hi example, there are again no variable assignments in the first pass, so processing continues to parameter expansion, resulting in a first word of hello=hi.



          Once the variable assignments have been processed, they are not re-processed during command execution.



          See the processing and its results under set -x:



          $ prefix=hello=hi
          + prefix=hello=hi
          $ $prefix bash -c 'echo $hello'
          + hello=hi bash -c 'echo $hello'
          -bash: hello=hi: command not found
          $ hello=42 bash -c 'echo $hello'
          + hello=42
          + bash -c 'echo $hello'
          42





          share|improve this answer












          I suspect this is the part of the sequence that's catching you:




          The words that are not variable assignments or redirections are expanded (see Shell Expansions). If any words remain after expansion, the first word is taken to be the name of the command and the remaining words are the arguments




          That's from the Bash reference manual in the section on Simple Command Expansion.



          In the cmd=bash example, no environment variables are set, and bash processes the command line up through parameter expansion, leaving bash -c "echo hi".



          In the prefix=hello=hi example, there are again no variable assignments in the first pass, so processing continues to parameter expansion, resulting in a first word of hello=hi.



          Once the variable assignments have been processed, they are not re-processed during command execution.



          See the processing and its results under set -x:



          $ prefix=hello=hi
          + prefix=hello=hi
          $ $prefix bash -c 'echo $hello'
          + hello=hi bash -c 'echo $hello'
          -bash: hello=hi: command not found
          $ hello=42 bash -c 'echo $hello'
          + hello=42
          + bash -c 'echo $hello'
          42






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 3 hours ago









          Jeff Schaller

          38.1k1053124




          38.1k1053124








          • 1




            Similarly, $foo=bar bash -c ... won't work, because $foo=bar isn't a variable assignment (whatever be the value of $foo), because $foo=bar doesn't fit the name=value pattern for variable assignment.
            – muru
            3 hours ago














          • 1




            Similarly, $foo=bar bash -c ... won't work, because $foo=bar isn't a variable assignment (whatever be the value of $foo), because $foo=bar doesn't fit the name=value pattern for variable assignment.
            – muru
            3 hours ago








          1




          1




          Similarly, $foo=bar bash -c ... won't work, because $foo=bar isn't a variable assignment (whatever be the value of $foo), because $foo=bar doesn't fit the name=value pattern for variable assignment.
          – muru
          3 hours ago




          Similarly, $foo=bar bash -c ... won't work, because $foo=bar isn't a variable assignment (whatever be the value of $foo), because $foo=bar doesn't fit the name=value pattern for variable assignment.
          – muru
          3 hours ago


















          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%2f490057%2fwhy-can-i-not-use-variables-as-prefix-to-a-command-to-set-environment-variables%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

          flock() on closed filehandle LOCK_FILE at /usr/bin/apt-mirror

          Mangá

          Eduardo VII do Reino Unido