How to export variables from a file?
set -a
. ./tmp.txt
set +a
set -a
causes variables¹ defined from now on to be automatically exported. It's available in any Bourne-like shell. .
is the standard and Bourne name for the source
command so I prefer it for portability (source
comes from csh
and is now available in most modern Bourne-like shells including bash
though (sometimes with a slightly different behaviour)).
In POSIX shells, you can also use set -o allexport
as a more descriptive alternative way to write it (set +o allexport
to unset).
You can make it a function with:
export_from() {
# local is not a standard command but is pretty common. It's needed here
# for this code to be re-entrant (for the case where sourced files to
# call export_from). We still use _export_from_ prefix to namespace
# those variables to reduce the risk of those variables being some of
# those exported by the sourced file.
local _export_from_ret _export_from_restore _export_from_file
_export_from_ret=0
# record current state of the allexport option. Some shells (ksh93/zsh)
# have support for local scope for options, but there's no standard
# equivalent.
case $- in
(*a*) _export_from_restore=;;
(*) _export_from_restore='set +a';;
esac
for _export_from_file do
# using the command prefix removes the "special" attribute of the "."
# command so that it doesn't exit the shell when failing.
command . "$_export_from_file" || _export_from_ret="$?"
done
eval "$_export_from_restore"
return "$_export_from_ret"
}
¹ In bash
, beware that it also causes all functions declared while allexport
is on to be exported to the environment (as BASH_FUNC_myfunction%%
environment variables that are then imported by all bash
shells run in that environment, even when running as sh
).
source tmp.txt
export a b c
./child ...
Judging by your other question, you don't want to hardcode the variable names:
source tmp.txt
export $(cut -d= -f1 tmp.txt)
test it:
$ source tmp.txt
$ echo "$a $b $c"
123 hello world one more variable
$ perl -E 'say "@ENV{qw(a b c)}"'
$ export $(cut -d= -f1 tmp.txt)
$ perl -E 'say "@ENV{qw(a b c)}"'
123 hello world one more variable
A dangerous one-liner that doesn't require source:
export $(xargs <file)
- It can't handle comments, frequently used in environment files
- It can't handle values with whitespace, like in the question example
- It may unintentionally expand glob patterns into files if they match by any chance
It's a bit dangerous because it passes the lines through bash expansion, but it has been useful to me when I know I have safe environment files.