2

I have a seemingly simple bash script to setup my environment: The first two lines are:

#!/bin/bash
export CVE_ENV_DIR=$PWD

easy, hey? Well, see what happens when I run it, I get the following output:

$ echo $PWD
/work/env
$ ./env.sh 
$ echo $CVE_ENV_DIR

$ 

Why does CVE_ENV_DIR not get set to /work/env? What is happening here? When I type export CVE_ENV_DIR=$PWD manually on the shell, it works as expected...

stdcerr
  • 13,725
  • 25
  • 71
  • 128

1 Answers1

5

Child shells cannot affect the environment of their parent. If you want the script to affect the parent's environment, you need to:

source ./env.sh

So what's going on? When you run a bash script, either by bash env.sh or env.sh, you're spawning a program with its own environment, an environment that's divorced from its parent. But, when you run the commands contained in the script at the command line, or using source, there is no spawned environment.


Edit to address @syme's comment. Bash scripts meant to be read using source are often pure configuration, containing only assignments and calculations. It's possible to also make them a little more helpful and self-documenting with a clever she-bang hack like:

#!/bin/echo USAGE: source 
# Default configuration file for the Frobnicator package.

FOO=bar
BAR=$(stat /baz)
[[ -f /baz ]] && BAZ=file || BAZ=

export FOO BAR BAZ

Making a bash script meant for configuration look like a configuration script, you help future maintainers. You also help yourself my modularizing your script code into distinct parts, each part with its one unique function.

As a side note, please don't export on the same line as you assign.

bishop
  • 37,830
  • 11
  • 104
  • 139
  • 1
    And I would have added two little things. Since the script is no longer executed: the execution rights are no longer necessary (only those of reading), and the shebang either. – syme May 15 '18 at 15:08