Access variable declared inside Makefile command
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
add a comment |
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
add a comment |
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
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
bash shell makefile
asked Jun 23 '16 at 13:13
julesboujulesbou
3,22732230
3,22732230
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
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.
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 ascript3.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
add a comment |
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.
that's what I thought, thanks a lot
– julesbou
Jun 23 '16 at 13:45
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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 ascript3.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
add a comment |
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.
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 ascript3.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
add a comment |
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.
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.
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 ascript3.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
add a comment |
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 ascript3.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
add a comment |
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.
that's what I thought, thanks a lot
– julesbou
Jun 23 '16 at 13:45
add a comment |
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.
that's what I thought, thanks a lot
– julesbou
Jun 23 '16 at 13:45
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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