0

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'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
2

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.