Access variable declared inside Makefile command












0















I'm trying to access a variable declared by previous command (inside a Makefile).



Here's the Makefile:



all:
./script1.sh
./script2.sh


Here's the script declaring the variable I want to access,script1.sh:



#!/usr/bin/env bash
myVar=1234


Here's the script trying to access the variable previously defined, script2.sh:



#!/usr/bin/env bash
echo $myVar


Unfortunately when I run make, myVar isn't accessible. Is there an other way around? Thanks.










share|improve this question



























    0















    I'm trying to access a variable declared by previous command (inside a Makefile).



    Here's the Makefile:



    all:
    ./script1.sh
    ./script2.sh


    Here's the script declaring the variable I want to access,script1.sh:



    #!/usr/bin/env bash
    myVar=1234


    Here's the script trying to access the variable previously defined, script2.sh:



    #!/usr/bin/env bash
    echo $myVar


    Unfortunately when I run make, myVar isn't accessible. Is there an other way around? Thanks.










    share|improve this question

























      0












      0








      0








      I'm trying to access a variable declared by previous command (inside a Makefile).



      Here's the Makefile:



      all:
      ./script1.sh
      ./script2.sh


      Here's the script declaring the variable I want to access,script1.sh:



      #!/usr/bin/env bash
      myVar=1234


      Here's the script trying to access the variable previously defined, script2.sh:



      #!/usr/bin/env bash
      echo $myVar


      Unfortunately when I run make, myVar isn't accessible. Is there an other way around? Thanks.










      share|improve this question














      I'm trying to access a variable declared by previous command (inside a Makefile).



      Here's the Makefile:



      all:
      ./script1.sh
      ./script2.sh


      Here's the script declaring the variable I want to access,script1.sh:



      #!/usr/bin/env bash
      myVar=1234


      Here's the script trying to access the variable previously defined, script2.sh:



      #!/usr/bin/env bash
      echo $myVar


      Unfortunately when I run make, myVar isn't accessible. Is there an other way around? Thanks.







      bash shell makefile






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Jun 23 '16 at 13:13









      julesboujulesbou

      3,22732230




      3,22732230
























          2 Answers
          2






          active

          oldest

          votes


















          3














          Make will run each shell command in its own shell. And when the shell exits, its environment is lost.



          If you want variables from one script to be available in the next, there are constructs which will do this. For example:



          all:
          ( . ./script1.sh; ./script2.sh )


          This causes Make to launch a single shell to handle both scripts.



          Note also that you will need to export the variable in order for it to be visible in the second script; unexported variables are available only to the local script, and not to subshells that it launches.





          UPDATE (per Kusalananda's comment):



          If you want your shell commands to populate MAKE variables instead of merely environment variables, you may have options that depend on the version of Make that you are running. For example, in BSD make and GNU make, you can use "variable assignment modifiers" including (from the BSD make man page):



           !=      Expand the value and pass it to the shell for execution and
          assign the result to the variable. Any newlines in the result
          are replaced with spaces.


          Thus, with BSD make and GNU make, you could do this:



          $ cat Makefile

          foo!= . ./script1.sh; ./script2.sh

          all:
          @echo "foo=${foo}"

          $
          $ cat script1.sh
          export test=bar
          $
          $ cat script2.sh
          #!/usr/bin/env bash

          echo "$test"
          $
          $ make
          foo=bar
          $


          Note that script1.sh does not include any shebang because it's being sourced, and is therefore running in the calling shell, whatever that is. That makes the shebang line merely a comment. If you're on a system where the default shell is POSIX but not bash (like Ubuntu, Solaris, FreeBSD, etc), this should still work because POSIX shells should all understand the concept of exporting variables.






          share|improve this answer


























          • That works nicely. However, the variables are not available outside the shell created by ( ... ). That might not be a problem for the OP though... Strictly speaking, that's the same as having a script3.sh that sources the first script and executes the second. It's no longer "inside the Makefile" at that point.

            – Kusalananda
            Jun 23 '16 at 13:56








          • 1





            @Kusalananda - updated with a solution that populates make variables in BSD and GNU make. Doesn't work with all variants, but at least it's something. :)

            – ghoti
            Jun 23 '16 at 15:06











          • That's a good solution.

            – Kusalananda
            Jun 23 '16 at 15:08











          • The parentheses in the first example are unnecessary and slightly inefficient. There is no need to run a shell with a subshell.

            – tripleee
            Apr 7 '18 at 18:04



















          1














          The two separate invocations of the scripts create two separate environments. The first script sets a variable in its environment and exits (the environment is lost). The second script does not have that variable in its environment, so it outputs an empty string.



          You can not have environment variables pass between environments other than between the environments of a parent shell to its child shell (not the other way around). The variables passed over into the child shell are only those that the parent shell has export-ed. So, if the first script invoked the second script, the value would be outputted (if it was export-ed in the first script).



          In a shell, you would source the first file to set the variables therein in the current environment (and then export them!). However, in Makefiles it's a bit trickier since there's no convenient source command.



          Instead you may want to read this StackOverflow question.



          EDIT in light of @ghoti's answer: @ghoti has a good solution, but I'll leave my answer in here as it explains a bit more verbosely about environment variables and what we can do and not do with them with regards to passing them between environments.






          share|improve this answer


























          • that's what I thought, thanks a lot

            – julesbou
            Jun 23 '16 at 13:45












          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%2f37992696%2faccess-variable-declared-inside-makefile-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









          3














          Make will run each shell command in its own shell. And when the shell exits, its environment is lost.



          If you want variables from one script to be available in the next, there are constructs which will do this. For example:



          all:
          ( . ./script1.sh; ./script2.sh )


          This causes Make to launch a single shell to handle both scripts.



          Note also that you will need to export the variable in order for it to be visible in the second script; unexported variables are available only to the local script, and not to subshells that it launches.





          UPDATE (per Kusalananda's comment):



          If you want your shell commands to populate MAKE variables instead of merely environment variables, you may have options that depend on the version of Make that you are running. For example, in BSD make and GNU make, you can use "variable assignment modifiers" including (from the BSD make man page):



           !=      Expand the value and pass it to the shell for execution and
          assign the result to the variable. Any newlines in the result
          are replaced with spaces.


          Thus, with BSD make and GNU make, you could do this:



          $ cat Makefile

          foo!= . ./script1.sh; ./script2.sh

          all:
          @echo "foo=${foo}"

          $
          $ cat script1.sh
          export test=bar
          $
          $ cat script2.sh
          #!/usr/bin/env bash

          echo "$test"
          $
          $ make
          foo=bar
          $


          Note that script1.sh does not include any shebang because it's being sourced, and is therefore running in the calling shell, whatever that is. That makes the shebang line merely a comment. If you're on a system where the default shell is POSIX but not bash (like Ubuntu, Solaris, FreeBSD, etc), this should still work because POSIX shells should all understand the concept of exporting variables.






          share|improve this answer


























          • That works nicely. However, the variables are not available outside the shell created by ( ... ). That might not be a problem for the OP though... Strictly speaking, that's the same as having a script3.sh that sources the first script and executes the second. It's no longer "inside the Makefile" at that point.

            – Kusalananda
            Jun 23 '16 at 13:56








          • 1





            @Kusalananda - updated with a solution that populates make variables in BSD and GNU make. Doesn't work with all variants, but at least it's something. :)

            – ghoti
            Jun 23 '16 at 15:06











          • That's a good solution.

            – Kusalananda
            Jun 23 '16 at 15:08











          • The parentheses in the first example are unnecessary and slightly inefficient. There is no need to run a shell with a subshell.

            – tripleee
            Apr 7 '18 at 18:04
















          3














          Make will run each shell command in its own shell. And when the shell exits, its environment is lost.



          If you want variables from one script to be available in the next, there are constructs which will do this. For example:



          all:
          ( . ./script1.sh; ./script2.sh )


          This causes Make to launch a single shell to handle both scripts.



          Note also that you will need to export the variable in order for it to be visible in the second script; unexported variables are available only to the local script, and not to subshells that it launches.





          UPDATE (per Kusalananda's comment):



          If you want your shell commands to populate MAKE variables instead of merely environment variables, you may have options that depend on the version of Make that you are running. For example, in BSD make and GNU make, you can use "variable assignment modifiers" including (from the BSD make man page):



           !=      Expand the value and pass it to the shell for execution and
          assign the result to the variable. Any newlines in the result
          are replaced with spaces.


          Thus, with BSD make and GNU make, you could do this:



          $ cat Makefile

          foo!= . ./script1.sh; ./script2.sh

          all:
          @echo "foo=${foo}"

          $
          $ cat script1.sh
          export test=bar
          $
          $ cat script2.sh
          #!/usr/bin/env bash

          echo "$test"
          $
          $ make
          foo=bar
          $


          Note that script1.sh does not include any shebang because it's being sourced, and is therefore running in the calling shell, whatever that is. That makes the shebang line merely a comment. If you're on a system where the default shell is POSIX but not bash (like Ubuntu, Solaris, FreeBSD, etc), this should still work because POSIX shells should all understand the concept of exporting variables.






          share|improve this answer


























          • That works nicely. However, the variables are not available outside the shell created by ( ... ). That might not be a problem for the OP though... Strictly speaking, that's the same as having a script3.sh that sources the first script and executes the second. It's no longer "inside the Makefile" at that point.

            – Kusalananda
            Jun 23 '16 at 13:56








          • 1





            @Kusalananda - updated with a solution that populates make variables in BSD and GNU make. Doesn't work with all variants, but at least it's something. :)

            – ghoti
            Jun 23 '16 at 15:06











          • That's a good solution.

            – Kusalananda
            Jun 23 '16 at 15:08











          • The parentheses in the first example are unnecessary and slightly inefficient. There is no need to run a shell with a subshell.

            – tripleee
            Apr 7 '18 at 18:04














          3












          3








          3







          Make will run each shell command in its own shell. And when the shell exits, its environment is lost.



          If you want variables from one script to be available in the next, there are constructs which will do this. For example:



          all:
          ( . ./script1.sh; ./script2.sh )


          This causes Make to launch a single shell to handle both scripts.



          Note also that you will need to export the variable in order for it to be visible in the second script; unexported variables are available only to the local script, and not to subshells that it launches.





          UPDATE (per Kusalananda's comment):



          If you want your shell commands to populate MAKE variables instead of merely environment variables, you may have options that depend on the version of Make that you are running. For example, in BSD make and GNU make, you can use "variable assignment modifiers" including (from the BSD make man page):



           !=      Expand the value and pass it to the shell for execution and
          assign the result to the variable. Any newlines in the result
          are replaced with spaces.


          Thus, with BSD make and GNU make, you could do this:



          $ cat Makefile

          foo!= . ./script1.sh; ./script2.sh

          all:
          @echo "foo=${foo}"

          $
          $ cat script1.sh
          export test=bar
          $
          $ cat script2.sh
          #!/usr/bin/env bash

          echo "$test"
          $
          $ make
          foo=bar
          $


          Note that script1.sh does not include any shebang because it's being sourced, and is therefore running in the calling shell, whatever that is. That makes the shebang line merely a comment. If you're on a system where the default shell is POSIX but not bash (like Ubuntu, Solaris, FreeBSD, etc), this should still work because POSIX shells should all understand the concept of exporting variables.






          share|improve this answer















          Make will run each shell command in its own shell. And when the shell exits, its environment is lost.



          If you want variables from one script to be available in the next, there are constructs which will do this. For example:



          all:
          ( . ./script1.sh; ./script2.sh )


          This causes Make to launch a single shell to handle both scripts.



          Note also that you will need to export the variable in order for it to be visible in the second script; unexported variables are available only to the local script, and not to subshells that it launches.





          UPDATE (per Kusalananda's comment):



          If you want your shell commands to populate MAKE variables instead of merely environment variables, you may have options that depend on the version of Make that you are running. For example, in BSD make and GNU make, you can use "variable assignment modifiers" including (from the BSD make man page):



           !=      Expand the value and pass it to the shell for execution and
          assign the result to the variable. Any newlines in the result
          are replaced with spaces.


          Thus, with BSD make and GNU make, you could do this:



          $ cat Makefile

          foo!= . ./script1.sh; ./script2.sh

          all:
          @echo "foo=${foo}"

          $
          $ cat script1.sh
          export test=bar
          $
          $ cat script2.sh
          #!/usr/bin/env bash

          echo "$test"
          $
          $ make
          foo=bar
          $


          Note that script1.sh does not include any shebang because it's being sourced, and is therefore running in the calling shell, whatever that is. That makes the shebang line merely a comment. If you're on a system where the default shell is POSIX but not bash (like Ubuntu, Solaris, FreeBSD, etc), this should still work because POSIX shells should all understand the concept of exporting variables.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jun 23 '16 at 15:09

























          answered Jun 23 '16 at 13:47









          ghotighoti

          35.7k74283




          35.7k74283













          • That works nicely. However, the variables are not available outside the shell created by ( ... ). That might not be a problem for the OP though... Strictly speaking, that's the same as having a script3.sh that sources the first script and executes the second. It's no longer "inside the Makefile" at that point.

            – Kusalananda
            Jun 23 '16 at 13:56








          • 1





            @Kusalananda - updated with a solution that populates make variables in BSD and GNU make. Doesn't work with all variants, but at least it's something. :)

            – ghoti
            Jun 23 '16 at 15:06











          • That's a good solution.

            – Kusalananda
            Jun 23 '16 at 15:08











          • The parentheses in the first example are unnecessary and slightly inefficient. There is no need to run a shell with a subshell.

            – tripleee
            Apr 7 '18 at 18:04



















          • That works nicely. However, the variables are not available outside the shell created by ( ... ). That might not be a problem for the OP though... Strictly speaking, that's the same as having a script3.sh that sources the first script and executes the second. It's no longer "inside the Makefile" at that point.

            – Kusalananda
            Jun 23 '16 at 13:56








          • 1





            @Kusalananda - updated with a solution that populates make variables in BSD and GNU make. Doesn't work with all variants, but at least it's something. :)

            – ghoti
            Jun 23 '16 at 15:06











          • That's a good solution.

            – Kusalananda
            Jun 23 '16 at 15:08











          • The parentheses in the first example are unnecessary and slightly inefficient. There is no need to run a shell with a subshell.

            – tripleee
            Apr 7 '18 at 18:04

















          That works nicely. However, the variables are not available outside the shell created by ( ... ). That might not be a problem for the OP though... Strictly speaking, that's the same as having a script3.sh that sources the first script and executes the second. It's no longer "inside the Makefile" at that point.

          – Kusalananda
          Jun 23 '16 at 13:56







          That works nicely. However, the variables are not available outside the shell created by ( ... ). That might not be a problem for the OP though... Strictly speaking, that's the same as having a script3.sh that sources the first script and executes the second. It's no longer "inside the Makefile" at that point.

          – Kusalananda
          Jun 23 '16 at 13:56






          1




          1





          @Kusalananda - updated with a solution that populates make variables in BSD and GNU make. Doesn't work with all variants, but at least it's something. :)

          – ghoti
          Jun 23 '16 at 15:06





          @Kusalananda - updated with a solution that populates make variables in BSD and GNU make. Doesn't work with all variants, but at least it's something. :)

          – ghoti
          Jun 23 '16 at 15:06













          That's a good solution.

          – Kusalananda
          Jun 23 '16 at 15:08





          That's a good solution.

          – Kusalananda
          Jun 23 '16 at 15:08













          The parentheses in the first example are unnecessary and slightly inefficient. There is no need to run a shell with a subshell.

          – tripleee
          Apr 7 '18 at 18:04





          The parentheses in the first example are unnecessary and slightly inefficient. There is no need to run a shell with a subshell.

          – tripleee
          Apr 7 '18 at 18:04













          1














          The two separate invocations of the scripts create two separate environments. The first script sets a variable in its environment and exits (the environment is lost). The second script does not have that variable in its environment, so it outputs an empty string.



          You can not have environment variables pass between environments other than between the environments of a parent shell to its child shell (not the other way around). The variables passed over into the child shell are only those that the parent shell has export-ed. So, if the first script invoked the second script, the value would be outputted (if it was export-ed in the first script).



          In a shell, you would source the first file to set the variables therein in the current environment (and then export them!). However, in Makefiles it's a bit trickier since there's no convenient source command.



          Instead you may want to read this StackOverflow question.



          EDIT in light of @ghoti's answer: @ghoti has a good solution, but I'll leave my answer in here as it explains a bit more verbosely about environment variables and what we can do and not do with them with regards to passing them between environments.






          share|improve this answer


























          • that's what I thought, thanks a lot

            – julesbou
            Jun 23 '16 at 13:45
















          1














          The two separate invocations of the scripts create two separate environments. The first script sets a variable in its environment and exits (the environment is lost). The second script does not have that variable in its environment, so it outputs an empty string.



          You can not have environment variables pass between environments other than between the environments of a parent shell to its child shell (not the other way around). The variables passed over into the child shell are only those that the parent shell has export-ed. So, if the first script invoked the second script, the value would be outputted (if it was export-ed in the first script).



          In a shell, you would source the first file to set the variables therein in the current environment (and then export them!). However, in Makefiles it's a bit trickier since there's no convenient source command.



          Instead you may want to read this StackOverflow question.



          EDIT in light of @ghoti's answer: @ghoti has a good solution, but I'll leave my answer in here as it explains a bit more verbosely about environment variables and what we can do and not do with them with regards to passing them between environments.






          share|improve this answer


























          • that's what I thought, thanks a lot

            – julesbou
            Jun 23 '16 at 13:45














          1












          1








          1







          The two separate invocations of the scripts create two separate environments. The first script sets a variable in its environment and exits (the environment is lost). The second script does not have that variable in its environment, so it outputs an empty string.



          You can not have environment variables pass between environments other than between the environments of a parent shell to its child shell (not the other way around). The variables passed over into the child shell are only those that the parent shell has export-ed. So, if the first script invoked the second script, the value would be outputted (if it was export-ed in the first script).



          In a shell, you would source the first file to set the variables therein in the current environment (and then export them!). However, in Makefiles it's a bit trickier since there's no convenient source command.



          Instead you may want to read this StackOverflow question.



          EDIT in light of @ghoti's answer: @ghoti has a good solution, but I'll leave my answer in here as it explains a bit more verbosely about environment variables and what we can do and not do with them with regards to passing them between environments.






          share|improve this answer















          The two separate invocations of the scripts create two separate environments. The first script sets a variable in its environment and exits (the environment is lost). The second script does not have that variable in its environment, so it outputs an empty string.



          You can not have environment variables pass between environments other than between the environments of a parent shell to its child shell (not the other way around). The variables passed over into the child shell are only those that the parent shell has export-ed. So, if the first script invoked the second script, the value would be outputted (if it was export-ed in the first script).



          In a shell, you would source the first file to set the variables therein in the current environment (and then export them!). However, in Makefiles it's a bit trickier since there's no convenient source command.



          Instead you may want to read this StackOverflow question.



          EDIT in light of @ghoti's answer: @ghoti has a good solution, but I'll leave my answer in here as it explains a bit more verbosely about environment variables and what we can do and not do with them with regards to passing them between environments.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited May 23 '17 at 10:29









          Community

          11




          11










          answered Jun 23 '16 at 13:41









          KusalanandaKusalananda

          9,90512841




          9,90512841













          • that's what I thought, thanks a lot

            – julesbou
            Jun 23 '16 at 13:45



















          • that's what I thought, thanks a lot

            – julesbou
            Jun 23 '16 at 13:45

















          that's what I thought, thanks a lot

          – julesbou
          Jun 23 '16 at 13:45





          that's what I thought, thanks a lot

          – julesbou
          Jun 23 '16 at 13:45


















          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%2f37992696%2faccess-variable-declared-inside-makefile-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

          Monofisismo

          Angular Downloading a file using contenturl with Basic Authentication

          Olmecas