Chaining (i.e. sequentially running) bash scripts and setting environment variables within these bash scripts

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP












0















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!










share|improve this question






















  • 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
















0















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!










share|improve this question






















  • 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














0












0








0








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!










share|improve this question














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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










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


















  • 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

















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











1 Answer
1






active

oldest

votes


















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.






share|improve this answer






















    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%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









    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.






    share|improve this answer



























      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.






      share|improve this answer

























        2












        2








        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.






        share|improve this answer














        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.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Feb 20 at 11:47









        ilkkachuilkkachu

        61.5k10100177




        61.5k10100177



























            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%2f501812%2fchaining-i-e-sequentially-running-bash-scripts-and-setting-environment-variab%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

            How to check contact read email or not when send email to Individual?

            Bahrain

            Postfix configuration issue with fips on centos 7; mailgun relay