envsubst not working as expected in a bash for loop

Viewed 2637

I'm trying to use bash's envsubst to substitute an environment variable into a file. Here's a simple example that fails to work as expected:

Create a file with a variable substitution in it:

echo 'Filename: ${FILE}' > test.txt

Now try to use envsubst in a for loop:

for FILE in `ls`; do envsubst < test.txt; done

Filename:

The result is just Filename: the substitution fails.

Echo works as expected in this context:

for FILE in `ls`; do echo Filename: ${FILE}; done

Filename: test.txt

I don't understand why echo would work and envsubst would fail.

2 Answers

Make sure to export the variable and, optionally if you are paranoid/security-minded, name it on the command line:

export FILE
envsubst < template #all exported environment avail in template
envsubst '${FILE}' < template #only FILE available

That is because in the for loop FILE is a shell variable and it is not actually part of the environment, so it is not passed to envsubst's environment.

Try this

for FILE in `ls`; do
    env | grep FILE;
done

and compare it to this

for FILE in `ls`; do
    export FILE;
    env | grep FILE;
done

So if you want to make FILE an environment variable you need to use export builtin before.

Related