Setting variable with default value behaves differently when preceding a command?












3















Setting a variable with a fallback default value works...as long as we're using the variable in a subsequent command:



$ unset APP_ENV
$ echo $APP_ENV

$ APP_ENV="${APP_ENV:-production}"; echo $APP_ENV
production
$ APP_ENV=staging
$ APP_ENV="${APP_ENV:-production}"; echo $APP_ENV
staging


However, trying to set the variable immediately preceding the command that uses it behaves differently:



$ unset APP_ENV
$ echo $APP_ENV

$ APP_ENV="${APP_ENV:-production}" echo $APP_ENV

$ APP_ENV=staging
$ APP_ENV="${APP_ENV:-production}" echo $APP_ENV
staging


Why the second example behaves differently?










share|improve this question





























    3















    Setting a variable with a fallback default value works...as long as we're using the variable in a subsequent command:



    $ unset APP_ENV
    $ echo $APP_ENV

    $ APP_ENV="${APP_ENV:-production}"; echo $APP_ENV
    production
    $ APP_ENV=staging
    $ APP_ENV="${APP_ENV:-production}"; echo $APP_ENV
    staging


    However, trying to set the variable immediately preceding the command that uses it behaves differently:



    $ unset APP_ENV
    $ echo $APP_ENV

    $ APP_ENV="${APP_ENV:-production}" echo $APP_ENV

    $ APP_ENV=staging
    $ APP_ENV="${APP_ENV:-production}" echo $APP_ENV
    staging


    Why the second example behaves differently?










    share|improve this question



























      3












      3








      3








      Setting a variable with a fallback default value works...as long as we're using the variable in a subsequent command:



      $ unset APP_ENV
      $ echo $APP_ENV

      $ APP_ENV="${APP_ENV:-production}"; echo $APP_ENV
      production
      $ APP_ENV=staging
      $ APP_ENV="${APP_ENV:-production}"; echo $APP_ENV
      staging


      However, trying to set the variable immediately preceding the command that uses it behaves differently:



      $ unset APP_ENV
      $ echo $APP_ENV

      $ APP_ENV="${APP_ENV:-production}" echo $APP_ENV

      $ APP_ENV=staging
      $ APP_ENV="${APP_ENV:-production}" echo $APP_ENV
      staging


      Why the second example behaves differently?










      share|improve this question
















      Setting a variable with a fallback default value works...as long as we're using the variable in a subsequent command:



      $ unset APP_ENV
      $ echo $APP_ENV

      $ APP_ENV="${APP_ENV:-production}"; echo $APP_ENV
      production
      $ APP_ENV=staging
      $ APP_ENV="${APP_ENV:-production}"; echo $APP_ENV
      staging


      However, trying to set the variable immediately preceding the command that uses it behaves differently:



      $ unset APP_ENV
      $ echo $APP_ENV

      $ APP_ENV="${APP_ENV:-production}" echo $APP_ENV

      $ APP_ENV=staging
      $ APP_ENV="${APP_ENV:-production}" echo $APP_ENV
      staging


      Why the second example behaves differently?







      bash shell-script variable






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 11 hours ago









      Rui F Ribeiro

      41.3k1481140




      41.3k1481140










      asked Jul 16 '15 at 16:11









      EvanKEvanK

      1214




      1214






















          2 Answers
          2






          active

          oldest

          votes


















          4














          Let's replace the semicolon with a newline to make the first version clearer:



          APP_ENV="${APP_ENV:-production}"
          echo $APP_ENV


          Line 1 executes completely before the shell looks at line 2.



          Line 1 causes $APP_ENV to be set equal to production.



          Line 2 accesses that variable and provided its value to the echo command.



          Now the single-command version:



          APP_ENV="${APP_ENV:-production}" echo $APP_ENV


          First the shell expands the command line according to parameter expansion and (not applicable in this case) other kinds of substitution. Since the current value of $APP_ENV is empty, that expands to:



          APP_ENV="${:-production}" echo


          After performing expansions, it sets the variable $APP_ENV to production for this command invocation only, and invokes echo "" with that value. But echo doesn not care that it got an environment varible $APP_ENV in its environment. It only looks at its command line, which consists of nothing. So it echoes nothing.



          Here's how you prove that $APP_ENV really is being set in this case:



          $ APP_ENV="${APP_ENV:-production}" env |grep APP_ENV
          APP_ENV=production


          In summary, your second example does not do what you thought it would do because the parameter expansion happens too soon.






          share|improve this answer
























          • Thank you for breaking that down, it makes perfect sense to me now!

            – EvanK
            Jul 16 '15 at 18:32



















          -4














          The second form is behaving differently because you're missing a ; after the variable initialization:



          APP_ENV="${APP_ENV:-production}" echo $APP_ENV


          should be:



          APP_ENV="${APP_ENV:-production}"; echo $APP_ENV
          ^ semicolon that's missing


          Fix that first, then restate your question.






          share|improve this answer





















          • 2





            Yes, it's a different command without the semicolon. That's the point of the question. The question is valid as it stands.

            – Celada
            Jul 16 '15 at 16:43











          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%2f216498%2fsetting-variable-with-default-value-behaves-differently-when-preceding-a-command%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














          Let's replace the semicolon with a newline to make the first version clearer:



          APP_ENV="${APP_ENV:-production}"
          echo $APP_ENV


          Line 1 executes completely before the shell looks at line 2.



          Line 1 causes $APP_ENV to be set equal to production.



          Line 2 accesses that variable and provided its value to the echo command.



          Now the single-command version:



          APP_ENV="${APP_ENV:-production}" echo $APP_ENV


          First the shell expands the command line according to parameter expansion and (not applicable in this case) other kinds of substitution. Since the current value of $APP_ENV is empty, that expands to:



          APP_ENV="${:-production}" echo


          After performing expansions, it sets the variable $APP_ENV to production for this command invocation only, and invokes echo "" with that value. But echo doesn not care that it got an environment varible $APP_ENV in its environment. It only looks at its command line, which consists of nothing. So it echoes nothing.



          Here's how you prove that $APP_ENV really is being set in this case:



          $ APP_ENV="${APP_ENV:-production}" env |grep APP_ENV
          APP_ENV=production


          In summary, your second example does not do what you thought it would do because the parameter expansion happens too soon.






          share|improve this answer
























          • Thank you for breaking that down, it makes perfect sense to me now!

            – EvanK
            Jul 16 '15 at 18:32
















          4














          Let's replace the semicolon with a newline to make the first version clearer:



          APP_ENV="${APP_ENV:-production}"
          echo $APP_ENV


          Line 1 executes completely before the shell looks at line 2.



          Line 1 causes $APP_ENV to be set equal to production.



          Line 2 accesses that variable and provided its value to the echo command.



          Now the single-command version:



          APP_ENV="${APP_ENV:-production}" echo $APP_ENV


          First the shell expands the command line according to parameter expansion and (not applicable in this case) other kinds of substitution. Since the current value of $APP_ENV is empty, that expands to:



          APP_ENV="${:-production}" echo


          After performing expansions, it sets the variable $APP_ENV to production for this command invocation only, and invokes echo "" with that value. But echo doesn not care that it got an environment varible $APP_ENV in its environment. It only looks at its command line, which consists of nothing. So it echoes nothing.



          Here's how you prove that $APP_ENV really is being set in this case:



          $ APP_ENV="${APP_ENV:-production}" env |grep APP_ENV
          APP_ENV=production


          In summary, your second example does not do what you thought it would do because the parameter expansion happens too soon.






          share|improve this answer
























          • Thank you for breaking that down, it makes perfect sense to me now!

            – EvanK
            Jul 16 '15 at 18:32














          4












          4








          4







          Let's replace the semicolon with a newline to make the first version clearer:



          APP_ENV="${APP_ENV:-production}"
          echo $APP_ENV


          Line 1 executes completely before the shell looks at line 2.



          Line 1 causes $APP_ENV to be set equal to production.



          Line 2 accesses that variable and provided its value to the echo command.



          Now the single-command version:



          APP_ENV="${APP_ENV:-production}" echo $APP_ENV


          First the shell expands the command line according to parameter expansion and (not applicable in this case) other kinds of substitution. Since the current value of $APP_ENV is empty, that expands to:



          APP_ENV="${:-production}" echo


          After performing expansions, it sets the variable $APP_ENV to production for this command invocation only, and invokes echo "" with that value. But echo doesn not care that it got an environment varible $APP_ENV in its environment. It only looks at its command line, which consists of nothing. So it echoes nothing.



          Here's how you prove that $APP_ENV really is being set in this case:



          $ APP_ENV="${APP_ENV:-production}" env |grep APP_ENV
          APP_ENV=production


          In summary, your second example does not do what you thought it would do because the parameter expansion happens too soon.






          share|improve this answer













          Let's replace the semicolon with a newline to make the first version clearer:



          APP_ENV="${APP_ENV:-production}"
          echo $APP_ENV


          Line 1 executes completely before the shell looks at line 2.



          Line 1 causes $APP_ENV to be set equal to production.



          Line 2 accesses that variable and provided its value to the echo command.



          Now the single-command version:



          APP_ENV="${APP_ENV:-production}" echo $APP_ENV


          First the shell expands the command line according to parameter expansion and (not applicable in this case) other kinds of substitution. Since the current value of $APP_ENV is empty, that expands to:



          APP_ENV="${:-production}" echo


          After performing expansions, it sets the variable $APP_ENV to production for this command invocation only, and invokes echo "" with that value. But echo doesn not care that it got an environment varible $APP_ENV in its environment. It only looks at its command line, which consists of nothing. So it echoes nothing.



          Here's how you prove that $APP_ENV really is being set in this case:



          $ APP_ENV="${APP_ENV:-production}" env |grep APP_ENV
          APP_ENV=production


          In summary, your second example does not do what you thought it would do because the parameter expansion happens too soon.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jul 16 '15 at 16:50









          CeladaCelada

          31k46584




          31k46584













          • Thank you for breaking that down, it makes perfect sense to me now!

            – EvanK
            Jul 16 '15 at 18:32



















          • Thank you for breaking that down, it makes perfect sense to me now!

            – EvanK
            Jul 16 '15 at 18:32

















          Thank you for breaking that down, it makes perfect sense to me now!

          – EvanK
          Jul 16 '15 at 18:32





          Thank you for breaking that down, it makes perfect sense to me now!

          – EvanK
          Jul 16 '15 at 18:32













          -4














          The second form is behaving differently because you're missing a ; after the variable initialization:



          APP_ENV="${APP_ENV:-production}" echo $APP_ENV


          should be:



          APP_ENV="${APP_ENV:-production}"; echo $APP_ENV
          ^ semicolon that's missing


          Fix that first, then restate your question.






          share|improve this answer





















          • 2





            Yes, it's a different command without the semicolon. That's the point of the question. The question is valid as it stands.

            – Celada
            Jul 16 '15 at 16:43
















          -4














          The second form is behaving differently because you're missing a ; after the variable initialization:



          APP_ENV="${APP_ENV:-production}" echo $APP_ENV


          should be:



          APP_ENV="${APP_ENV:-production}"; echo $APP_ENV
          ^ semicolon that's missing


          Fix that first, then restate your question.






          share|improve this answer





















          • 2





            Yes, it's a different command without the semicolon. That's the point of the question. The question is valid as it stands.

            – Celada
            Jul 16 '15 at 16:43














          -4












          -4








          -4







          The second form is behaving differently because you're missing a ; after the variable initialization:



          APP_ENV="${APP_ENV:-production}" echo $APP_ENV


          should be:



          APP_ENV="${APP_ENV:-production}"; echo $APP_ENV
          ^ semicolon that's missing


          Fix that first, then restate your question.






          share|improve this answer















          The second form is behaving differently because you're missing a ; after the variable initialization:



          APP_ENV="${APP_ENV:-production}" echo $APP_ENV


          should be:



          APP_ENV="${APP_ENV:-production}"; echo $APP_ENV
          ^ semicolon that's missing


          Fix that first, then restate your question.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jul 17 '15 at 1:30









          cuonglm

          105k25207305




          105k25207305










          answered Jul 16 '15 at 16:18









          David FavorDavid Favor

          36314




          36314








          • 2





            Yes, it's a different command without the semicolon. That's the point of the question. The question is valid as it stands.

            – Celada
            Jul 16 '15 at 16:43














          • 2





            Yes, it's a different command without the semicolon. That's the point of the question. The question is valid as it stands.

            – Celada
            Jul 16 '15 at 16:43








          2




          2





          Yes, it's a different command without the semicolon. That's the point of the question. The question is valid as it stands.

          – Celada
          Jul 16 '15 at 16:43





          Yes, it's a different command without the semicolon. That's the point of the question. The question is valid as it stands.

          – Celada
          Jul 16 '15 at 16:43


















          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%2f216498%2fsetting-variable-with-default-value-behaves-differently-when-preceding-a-command%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

          Loup dans la culture

          How to solve the problem of ntp “Unable to contact time server” from KDE?

          ASUS Zenbook UX433/UX333 — Configure Touchpad-embedded numpad on Linux