Chaining (i.e. sequentially running) bash scripts and setting environment variables within these bash scripts
Apologies if this is a stupid question, but I'm having difficulty getting my head around this.
I have a file hadnodes.conf (setting node IP addresses for AWS VMs)
> ls -lista hadnodes.conf
7733498 4 -rwxrwxrwx. 1 pol pol 141 Feb 20 08:05 hadnodes.conf
Content (not real IPs):
> more hadnodes.conf
#!/bin/bash
export NAME_NODE=18.202.25.99
export DATA_NODE_1=52.30.117.99
export DATA_NODE_2=34.248.153.99
export DATA_NODE_3=52.17.111.99
And another script file setnodes
> ls -lista setnodes
7733504 4 -rwxrwxr-x. 1 pol pol 92 Feb 20 09:59 setnodes
Content:
> more setnodes
#!/bin/bash
source /home/pol/dcu/ca675_cloud_technologies/assignment_1/nodes/hadnodes.conf
Now, I can get setnodes to work if I type
source /path/to/setnodes
but not if I run
. /path/to/setnodes
as explained here and here.
But if I run just > setnodes (being an executable script), the variables don't take - i.e. $NAME_NODE, DATA_NODE_1 &c are undefined. I have put relevant directory in my $PATH and tab completion is occurring, so it's not like the script can't be seen. The command "> which setnodes" also shows it in the correct directory.
I also tried to use "exec" in setnodes to run my hadnodes.conf script (as described here) but to no avail.
I would like to know what I'm missing in terms of "chaining" (running sequentially) bash scripts so the environment variables in script "N" are passed back up the chain to the calling shell/environment (script 0).
I would really appreciate an explanation rather than just a "do this and it will work" kind of answer!
bash shell-script
add a comment |
Apologies if this is a stupid question, but I'm having difficulty getting my head around this.
I have a file hadnodes.conf (setting node IP addresses for AWS VMs)
> ls -lista hadnodes.conf
7733498 4 -rwxrwxrwx. 1 pol pol 141 Feb 20 08:05 hadnodes.conf
Content (not real IPs):
> more hadnodes.conf
#!/bin/bash
export NAME_NODE=18.202.25.99
export DATA_NODE_1=52.30.117.99
export DATA_NODE_2=34.248.153.99
export DATA_NODE_3=52.17.111.99
And another script file setnodes
> ls -lista setnodes
7733504 4 -rwxrwxr-x. 1 pol pol 92 Feb 20 09:59 setnodes
Content:
> more setnodes
#!/bin/bash
source /home/pol/dcu/ca675_cloud_technologies/assignment_1/nodes/hadnodes.conf
Now, I can get setnodes to work if I type
source /path/to/setnodes
but not if I run
. /path/to/setnodes
as explained here and here.
But if I run just > setnodes (being an executable script), the variables don't take - i.e. $NAME_NODE, DATA_NODE_1 &c are undefined. I have put relevant directory in my $PATH and tab completion is occurring, so it's not like the script can't be seen. The command "> which setnodes" also shows it in the correct directory.
I also tried to use "exec" in setnodes to run my hadnodes.conf script (as described here) but to no avail.
I would like to know what I'm missing in terms of "chaining" (running sequentially) bash scripts so the environment variables in script "N" are passed back up the chain to the calling shell/environment (script 0).
I would really appreciate an explanation rather than just a "do this and it will work" kind of answer!
bash shell-script
I'm a bit confused as to where you're stuck. Is it the two levels of shells involved? Because when you execute 'setnodes', it's a different shell. That shell will source the variables from thehadnodes.conf
file, but they're lost when the 'setnodes' shell exits.
– Haxiel
Feb 20 at 10:51
That''s what I want to undersand - I thought that the "export" would send the variables back up the chain?
– Vérace
Feb 20 at 11:07
Not the entire chain, because child processes cannot affect the parent process: unix.stackexchange.com/questions/30189/…
– Haxiel
Feb 20 at 11:29
add a comment |
Apologies if this is a stupid question, but I'm having difficulty getting my head around this.
I have a file hadnodes.conf (setting node IP addresses for AWS VMs)
> ls -lista hadnodes.conf
7733498 4 -rwxrwxrwx. 1 pol pol 141 Feb 20 08:05 hadnodes.conf
Content (not real IPs):
> more hadnodes.conf
#!/bin/bash
export NAME_NODE=18.202.25.99
export DATA_NODE_1=52.30.117.99
export DATA_NODE_2=34.248.153.99
export DATA_NODE_3=52.17.111.99
And another script file setnodes
> ls -lista setnodes
7733504 4 -rwxrwxr-x. 1 pol pol 92 Feb 20 09:59 setnodes
Content:
> more setnodes
#!/bin/bash
source /home/pol/dcu/ca675_cloud_technologies/assignment_1/nodes/hadnodes.conf
Now, I can get setnodes to work if I type
source /path/to/setnodes
but not if I run
. /path/to/setnodes
as explained here and here.
But if I run just > setnodes (being an executable script), the variables don't take - i.e. $NAME_NODE, DATA_NODE_1 &c are undefined. I have put relevant directory in my $PATH and tab completion is occurring, so it's not like the script can't be seen. The command "> which setnodes" also shows it in the correct directory.
I also tried to use "exec" in setnodes to run my hadnodes.conf script (as described here) but to no avail.
I would like to know what I'm missing in terms of "chaining" (running sequentially) bash scripts so the environment variables in script "N" are passed back up the chain to the calling shell/environment (script 0).
I would really appreciate an explanation rather than just a "do this and it will work" kind of answer!
bash shell-script
Apologies if this is a stupid question, but I'm having difficulty getting my head around this.
I have a file hadnodes.conf (setting node IP addresses for AWS VMs)
> ls -lista hadnodes.conf
7733498 4 -rwxrwxrwx. 1 pol pol 141 Feb 20 08:05 hadnodes.conf
Content (not real IPs):
> more hadnodes.conf
#!/bin/bash
export NAME_NODE=18.202.25.99
export DATA_NODE_1=52.30.117.99
export DATA_NODE_2=34.248.153.99
export DATA_NODE_3=52.17.111.99
And another script file setnodes
> ls -lista setnodes
7733504 4 -rwxrwxr-x. 1 pol pol 92 Feb 20 09:59 setnodes
Content:
> more setnodes
#!/bin/bash
source /home/pol/dcu/ca675_cloud_technologies/assignment_1/nodes/hadnodes.conf
Now, I can get setnodes to work if I type
source /path/to/setnodes
but not if I run
. /path/to/setnodes
as explained here and here.
But if I run just > setnodes (being an executable script), the variables don't take - i.e. $NAME_NODE, DATA_NODE_1 &c are undefined. I have put relevant directory in my $PATH and tab completion is occurring, so it's not like the script can't be seen. The command "> which setnodes" also shows it in the correct directory.
I also tried to use "exec" in setnodes to run my hadnodes.conf script (as described here) but to no avail.
I would like to know what I'm missing in terms of "chaining" (running sequentially) bash scripts so the environment variables in script "N" are passed back up the chain to the calling shell/environment (script 0).
I would really appreciate an explanation rather than just a "do this and it will work" kind of answer!
bash shell-script
bash shell-script
asked Feb 20 at 10:36
VéraceVérace
307213
307213
I'm a bit confused as to where you're stuck. Is it the two levels of shells involved? Because when you execute 'setnodes', it's a different shell. That shell will source the variables from thehadnodes.conf
file, but they're lost when the 'setnodes' shell exits.
– Haxiel
Feb 20 at 10:51
That''s what I want to undersand - I thought that the "export" would send the variables back up the chain?
– Vérace
Feb 20 at 11:07
Not the entire chain, because child processes cannot affect the parent process: unix.stackexchange.com/questions/30189/…
– Haxiel
Feb 20 at 11:29
add a comment |
I'm a bit confused as to where you're stuck. Is it the two levels of shells involved? Because when you execute 'setnodes', it's a different shell. That shell will source the variables from thehadnodes.conf
file, but they're lost when the 'setnodes' shell exits.
– Haxiel
Feb 20 at 10:51
That''s what I want to undersand - I thought that the "export" would send the variables back up the chain?
– Vérace
Feb 20 at 11:07
Not the entire chain, because child processes cannot affect the parent process: unix.stackexchange.com/questions/30189/…
– Haxiel
Feb 20 at 11:29
I'm a bit confused as to where you're stuck. Is it the two levels of shells involved? Because when you execute 'setnodes', it's a different shell. That shell will source the variables from the
hadnodes.conf
file, but they're lost when the 'setnodes' shell exits.– Haxiel
Feb 20 at 10:51
I'm a bit confused as to where you're stuck. Is it the two levels of shells involved? Because when you execute 'setnodes', it's a different shell. That shell will source the variables from the
hadnodes.conf
file, but they're lost when the 'setnodes' shell exits.– Haxiel
Feb 20 at 10:51
That''s what I want to undersand - I thought that the "export" would send the variables back up the chain?
– Vérace
Feb 20 at 11:07
That''s what I want to undersand - I thought that the "export" would send the variables back up the chain?
– Vérace
Feb 20 at 11:07
Not the entire chain, because child processes cannot affect the parent process: unix.stackexchange.com/questions/30189/…
– Haxiel
Feb 20 at 11:29
Not the entire chain, because child processes cannot affect the parent process: unix.stackexchange.com/questions/30189/…
– Haxiel
Feb 20 at 11:29
add a comment |
1 Answer
1
active
oldest
votes
I would like to know what I'm missing in terms of "chaining" (running sequentially) bash scripts so the environment variables in script "N" are passed back up the chain to the calling shell/environment (script 0).
You're missing the fact that you can't do that. There's no such thing as "the" environment, but instead each process has their own. Technically, the environment is just a set of strings passed from a parent process to the child (or actually, from a program calling exec*()
to the exec'ed program). There's no way to pass environment variables "up", and no way to modify the environment of a running program without support from the program itself.
Sourcing a script (with .
or source
) doesn't actually run the script in a separate process, but the calling shell reads and process it itself, in essentially the same context as the outer script is run.
So if we have a script a.sh
export FOO=abcd
then running . a.sh
will set the variable FOO
in the "parent" shell's environment. But running ./a.sh
as usual will not, and cannot.
One way to pass variable assignments "up" (sort of), is to output shell commands to set them, and then run those within eval
in the "parent" shell. This is what ssh-agent
does, the implementation in the shell would be something like this (b.sh
):
#!/bin/sh
# do something else here, but don't produce output
echo 'export FOO=abcd'
Now, we'd run eval "$(./b.sh)"
, and the parent shell would then execute the command export FOO=abcd
which it received from the command substitution.
Though if the child program is a shell script, just making it to be sourced as above might be easier.
Of course, when you talk about chaining, you can set variables in one shell, then call another, and then a third from that:
$ cat c1.sh
#!/bin/sh
export BAR=abcd
./c2.sh
$ cat c2.sh
#!/bin/sh
echo "$BAR"
Now, running c1.sh
would run c2.sh
, which would output abcd
, since the value of BAR
was inherited "down" from c1.sh
to c2.sh
.
add a comment |
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
});
}
});
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%2funix.stackexchange.com%2fquestions%2f501812%2fchaining-i-e-sequentially-running-bash-scripts-and-setting-environment-variab%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
I would like to know what I'm missing in terms of "chaining" (running sequentially) bash scripts so the environment variables in script "N" are passed back up the chain to the calling shell/environment (script 0).
You're missing the fact that you can't do that. There's no such thing as "the" environment, but instead each process has their own. Technically, the environment is just a set of strings passed from a parent process to the child (or actually, from a program calling exec*()
to the exec'ed program). There's no way to pass environment variables "up", and no way to modify the environment of a running program without support from the program itself.
Sourcing a script (with .
or source
) doesn't actually run the script in a separate process, but the calling shell reads and process it itself, in essentially the same context as the outer script is run.
So if we have a script a.sh
export FOO=abcd
then running . a.sh
will set the variable FOO
in the "parent" shell's environment. But running ./a.sh
as usual will not, and cannot.
One way to pass variable assignments "up" (sort of), is to output shell commands to set them, and then run those within eval
in the "parent" shell. This is what ssh-agent
does, the implementation in the shell would be something like this (b.sh
):
#!/bin/sh
# do something else here, but don't produce output
echo 'export FOO=abcd'
Now, we'd run eval "$(./b.sh)"
, and the parent shell would then execute the command export FOO=abcd
which it received from the command substitution.
Though if the child program is a shell script, just making it to be sourced as above might be easier.
Of course, when you talk about chaining, you can set variables in one shell, then call another, and then a third from that:
$ cat c1.sh
#!/bin/sh
export BAR=abcd
./c2.sh
$ cat c2.sh
#!/bin/sh
echo "$BAR"
Now, running c1.sh
would run c2.sh
, which would output abcd
, since the value of BAR
was inherited "down" from c1.sh
to c2.sh
.
add a comment |
I would like to know what I'm missing in terms of "chaining" (running sequentially) bash scripts so the environment variables in script "N" are passed back up the chain to the calling shell/environment (script 0).
You're missing the fact that you can't do that. There's no such thing as "the" environment, but instead each process has their own. Technically, the environment is just a set of strings passed from a parent process to the child (or actually, from a program calling exec*()
to the exec'ed program). There's no way to pass environment variables "up", and no way to modify the environment of a running program without support from the program itself.
Sourcing a script (with .
or source
) doesn't actually run the script in a separate process, but the calling shell reads and process it itself, in essentially the same context as the outer script is run.
So if we have a script a.sh
export FOO=abcd
then running . a.sh
will set the variable FOO
in the "parent" shell's environment. But running ./a.sh
as usual will not, and cannot.
One way to pass variable assignments "up" (sort of), is to output shell commands to set them, and then run those within eval
in the "parent" shell. This is what ssh-agent
does, the implementation in the shell would be something like this (b.sh
):
#!/bin/sh
# do something else here, but don't produce output
echo 'export FOO=abcd'
Now, we'd run eval "$(./b.sh)"
, and the parent shell would then execute the command export FOO=abcd
which it received from the command substitution.
Though if the child program is a shell script, just making it to be sourced as above might be easier.
Of course, when you talk about chaining, you can set variables in one shell, then call another, and then a third from that:
$ cat c1.sh
#!/bin/sh
export BAR=abcd
./c2.sh
$ cat c2.sh
#!/bin/sh
echo "$BAR"
Now, running c1.sh
would run c2.sh
, which would output abcd
, since the value of BAR
was inherited "down" from c1.sh
to c2.sh
.
add a comment |
I would like to know what I'm missing in terms of "chaining" (running sequentially) bash scripts so the environment variables in script "N" are passed back up the chain to the calling shell/environment (script 0).
You're missing the fact that you can't do that. There's no such thing as "the" environment, but instead each process has their own. Technically, the environment is just a set of strings passed from a parent process to the child (or actually, from a program calling exec*()
to the exec'ed program). There's no way to pass environment variables "up", and no way to modify the environment of a running program without support from the program itself.
Sourcing a script (with .
or source
) doesn't actually run the script in a separate process, but the calling shell reads and process it itself, in essentially the same context as the outer script is run.
So if we have a script a.sh
export FOO=abcd
then running . a.sh
will set the variable FOO
in the "parent" shell's environment. But running ./a.sh
as usual will not, and cannot.
One way to pass variable assignments "up" (sort of), is to output shell commands to set them, and then run those within eval
in the "parent" shell. This is what ssh-agent
does, the implementation in the shell would be something like this (b.sh
):
#!/bin/sh
# do something else here, but don't produce output
echo 'export FOO=abcd'
Now, we'd run eval "$(./b.sh)"
, and the parent shell would then execute the command export FOO=abcd
which it received from the command substitution.
Though if the child program is a shell script, just making it to be sourced as above might be easier.
Of course, when you talk about chaining, you can set variables in one shell, then call another, and then a third from that:
$ cat c1.sh
#!/bin/sh
export BAR=abcd
./c2.sh
$ cat c2.sh
#!/bin/sh
echo "$BAR"
Now, running c1.sh
would run c2.sh
, which would output abcd
, since the value of BAR
was inherited "down" from c1.sh
to c2.sh
.
I would like to know what I'm missing in terms of "chaining" (running sequentially) bash scripts so the environment variables in script "N" are passed back up the chain to the calling shell/environment (script 0).
You're missing the fact that you can't do that. There's no such thing as "the" environment, but instead each process has their own. Technically, the environment is just a set of strings passed from a parent process to the child (or actually, from a program calling exec*()
to the exec'ed program). There's no way to pass environment variables "up", and no way to modify the environment of a running program without support from the program itself.
Sourcing a script (with .
or source
) doesn't actually run the script in a separate process, but the calling shell reads and process it itself, in essentially the same context as the outer script is run.
So if we have a script a.sh
export FOO=abcd
then running . a.sh
will set the variable FOO
in the "parent" shell's environment. But running ./a.sh
as usual will not, and cannot.
One way to pass variable assignments "up" (sort of), is to output shell commands to set them, and then run those within eval
in the "parent" shell. This is what ssh-agent
does, the implementation in the shell would be something like this (b.sh
):
#!/bin/sh
# do something else here, but don't produce output
echo 'export FOO=abcd'
Now, we'd run eval "$(./b.sh)"
, and the parent shell would then execute the command export FOO=abcd
which it received from the command substitution.
Though if the child program is a shell script, just making it to be sourced as above might be easier.
Of course, when you talk about chaining, you can set variables in one shell, then call another, and then a third from that:
$ cat c1.sh
#!/bin/sh
export BAR=abcd
./c2.sh
$ cat c2.sh
#!/bin/sh
echo "$BAR"
Now, running c1.sh
would run c2.sh
, which would output abcd
, since the value of BAR
was inherited "down" from c1.sh
to c2.sh
.
answered Feb 20 at 11:47
ilkkachuilkkachu
60.4k1098171
60.4k1098171
add a comment |
add a comment |
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.
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%2funix.stackexchange.com%2fquestions%2f501812%2fchaining-i-e-sequentially-running-bash-scripts-and-setting-environment-variab%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
I'm a bit confused as to where you're stuck. Is it the two levels of shells involved? Because when you execute 'setnodes', it's a different shell. That shell will source the variables from the
hadnodes.conf
file, but they're lost when the 'setnodes' shell exits.– Haxiel
Feb 20 at 10:51
That''s what I want to undersand - I thought that the "export" would send the variables back up the chain?
– Vérace
Feb 20 at 11:07
Not the entire chain, because child processes cannot affect the parent process: unix.stackexchange.com/questions/30189/…
– Haxiel
Feb 20 at 11:29