1

I want export variable from file. here's my file

cat file.txt
VERSION=1.0.0
LOCATION=USA
NAME=sample
ENVIRONMENT=$ENV

I export all variable on that file using this while loop

while read vars; do export $vars;done < file.txt

all variable is successfully exported, except ENVIRONMENT i got this value, ENVIRONMENT=$ENV (expected value is ENVIRONMENT=staging) .

printenv | grep ^ENV
ENV=staging

my question is, why substitute it's not working when using while loop, but its working if we manually export (e.g export ENVIRONMENT=$ENV) ??

actually there's many ways, to export variable from file, for example I can use envsubst < file > file1 and then do the while loop, but I just need explanation for case above.

Fixlensmith
  • 41
  • 1
  • 11

1 Answers1

2

The order of expansions are described in POSIX:

The order of word expansion shall be as follows:

  1. Tilde expansion (see Tilde Expansion), parameter expansion (see Parameter Expansion), command substitution (see Command Substitution), and arithmetic expansion (see Arithmetic Expansion) shall be performed, beginning to end. See item 5 in Token Recognition.

  2. Field splitting (see Field Splitting) shall be performed on the portions of the fields generated by step 1, unless IFS is null.

  3. Pathname expansion (see Pathname Expansion) shall be performed, unless set -f is in effect.

  4. Quote removal (see Quote Removal) shall always be performed last.

For Parameter Expansion, the tl;dr is:

${parameter}

The value, if any, of parameter shall be substituted.

You will notice that the definition is not recursive or multi-pass. There is no "5. Go back to step 1 and repeat until no further expansions can be performed", or "The value, if any, of parameter shall be substituted, and the process repeated until no more parameter expansions can be found."

This means that export $vars will expand $vars in step 1, but will not repeat that step and therefore leave $ENV alone.

This is also how basically all other programming languages work, e.g. Java:

String foo="bar";
String bar="baz";
// Prints `bar` without recursively resolving it into `baz`
System.out.println(foo);  
that other guy
  • 116,971
  • 11
  • 170
  • 194