skorada
skorada

Reputation: 461

Making exported variables stick around in bash scripts

I have 2 scripts, one.sh and two.sh

one.sh triggers a call to two.sh which internally sources/runs other scripts. I want to use variables exported in two.sh to stick around and use them in one.sh

one.sh:

#!/bin/bash
. ./path/two.sh
echo "VAR: $VAR"

--------------

two.sh

#!/bin/bash

#source/run other .sh scripts
. $(dirname "$0")/../three.sh

export VAR="hello"

When I run one.sh it allows me to use the var "VAR" but throws an error for the scripts that are being internally sourced or run within two.sh:

./path/two.sh: line 3: ./../three.sh: No such file or directory

If I change one.sh to the following:

one.sh
#!/bin/bash
./path/two.sh --> removed the "." in front of ./path/two.sh
echo "VAR: $VAR"

output: ./one.sh
VAR:    ===> NOT EXPORTED

Is there a way that allows me to export variables in two.sh and use them in one.sh and also lets me trigger/source other scripts in two.sh Apologies if this seems a little too basic but I looked around for similar questions and didnt find one

Upvotes: 1

Views: 109

Answers (2)

John1024
John1024

Reputation: 113844

The problem is with the lines int two.sh that look like:

. $(dirname "$0")/../three.sh

This tries to locate three.sh relative to the location of the script currently being executed. But, merely sourcing a script doesn't count. When one.sh sources two.sh, the value of $0 still refers to one.sh.

I see two reasonable solutions:

  1. Move one.sh to the two.sh's directory. That way the relative paths to source files in two.sh will still work.

    Or:

  2. Remove from two.sh all references to $(dirname "$0")/. Instead provide explicit paths.

Upvotes: 1

A.Villegas
A.Villegas

Reputation: 517

The first version of "one.sh" is OK. But in the "two.sh" script, if you run "dirname $0", it always returns ".". This makes that the path to the "three.sh" could be invalid. I recommend you change:

#source/run other .sh scripts
. $(dirname "$0")/../three.sh

for this:

#source/run other .sh scripts
. $(readlink -f $(dirname "$0"))/../three.sh

or by this:

#source/run other .sh scripts
. $(pwd)/../three.sh

In this case the two answers are correct by I prefer the first becasuse if "two.sh" runs a "cd" commands it will work too.

Upvotes: 1

Related Questions