I’m trying to make sense of the scoping precedence of environment variables in Bash. I’ve come to understand that when you use a script to modify environment variables, those modifications are only available to child processes. That each script creates its own environment scope it can modify and that scope is passed off to child processes, but doesn’t effect the scope of the parent process. (Side question: Is that correct?)
The modifications can be pulled into a parent process’s using source
on the file that makes the modifications (which causes the commands being executed in the script to instead be executed in the parent context).
My question is, does the &&
operator create a child scope?
For instance, if I have a script, modify-environment.sh
, that exports
some environment variables like so:
#!/bin/bash export MY_VAR=hi
And another script, do-something.sh
, that attempts to use them:
#!/bin/bash echo $MY_VAR
And I call them like this:
$ ./modify-environment.sh && ./do-something.sh
Will do-something.sh
inherit the modified environment variables from modify-environment.sh
?
Edit
I updated to rephrase the question, because I realized the answer is “No” and what I was previously seeing had to do with the fact that the script I was looking at was called using eval
and was printing export MY_VAR=value
, so the export
was being called in the parent context, which is why it was getting passed to the &&
operator.
Advertisement
Answer
using the command does not execute the script that changes the environmental variable, source
imports all functions and variables defined in that script, it also executes all commands in the particular context where the script was sourced. if and only if you explicitly execute the script , the parent process won’t have access to the variables ( environmental and non environmental) declared in that script. Executing a script creates a new process but sourcing a script does not fork a new process
i think you mistaking &&
for &
, &&
is a logical operator ( this applies to all programming languages ) but &
places a command / script as a background job therefore the parent process won’t have access to any variable or function placed in the background
for example
sourcing
# myenv.sh #!/usr/bin/env bash export NAME="${HOSTNAME}"
at the command line
source myenv.sh echo "${NAME}" # 73mp74710n
executing
# execute.sh #!/usr/bin/env bash export NAME="${hostname}"
at the command line
chmod +x execute.sh ./execute.sh echo "${NAME}"
at the command line
export NAME="${HOSTNAME}" & echo ${NAME} # nothing shows up export NAME="${HOSTNAME}" && echo "${NAME}" # 73mp74710n
EDIT: fix a wrong assumption of how source works base on the below comments