Bash export variables but only for current command

Viewed 1008

I want to load some environment variables from a file before running a node script, so that the script has access to them. However, I don't want the environment variables to be set in my shell after the script is done executing.

I can load the environment variables like this:

export $(cat app-env-vars.txt | xargs) && node my-script.js

However, after the command is run, all of the environment variables are now set in my shell.

I'm asking this question to answer it, since I figured out a solution but couldn't find an answer on SO.

3 Answers

If you wrap the command in parentheses, the exports will be scoped to within those parens and won't pollute the global shell namespace:

(export $(cat app-env-vars.txt | xargs) && node my-script.js)

Echo'ing one of the environment variables from the app.env file after executing the command will show it as empty.

This is what the env command is for:

env - run a program in a modified environment

You can try something like:

env $(cat app-en-vars.txt) node my-script.js

This (and any unquoted $(...) expansion) is subject to word splitting and glob expansion, both of which can easily cause problems with something like environment variables.

A safer approach is to use arrays, like so:

my_vars=(
  FOO=bar
  "BAZ=hello world"
  ...
)
env "${my_vars[@]}" node my-script.js

You can populate an array from a file if needed. Note you can also use -i with env to only pass the environment variables you set explicitly.


If you trust the .txt's files contents, and it contains valid Bash syntax, you should source it (and probably rename it to a .sh/.bash extension). Then you can use a subshell, as you posted in your answer, to prevent the sourced state from leaking into the parent shell:

( source app-env-vars.txt && node my-script.js )

If you file just contains variables like

FOO='x y z'
BAR='bar'
...

you can try

eval $(< app-en-vars.txt) node my-script.js
Related