Importing environment variables settings from another server

9,769

Solution 1

TL,DR: export with

export -p >env_var.sh

and import with

. env_var.sh

Whether your code works depends on the format of env_var.txt and what special characters (i.e. characters that have a special meaning in shell syntax) are present in the variables' names and values.

`cat env_var.txt` is an unquoted command substitution. Leaving a variable command substitution unquoted applies the “split+glob” operator to it: first split the output of the command at the characters in the value of the IFS variable, then interpret each piece as a file name wildcard pattern and replace each pattern that matches some files by the names of the matching files. The result is a list of words that the for loop iterates on.

An unquoted command substitution is rarely what you want, and in this case it's definitely not what you want. It does work, however, if the syntax of the file is e.g. the output of env and the values of the variables don't contain any of *?\[ or whitespace.

If env_var.txt is the output of env, you can get better results if you parse it according to its actual syntax (newline-separated assignments), rather than using a parsing method that doesn't make sense. If you want to use the split+glob operator, which is the easiest way to do this, set IFS to be a newline only, and turn of wildcard matching.

set -f; IFS='
'
export `cat env_var.txt`
set +f; unset IFS

There is a problem that you can't solve on the recipient side however, which is that the output of env is ambiguous. Given the following content:

foo=bar
hello=world

there's no way to tell whether there are two variables (one called foo with the value bar and one called hello with the value world) or just one that's called foo with the value

bar
hello=world

To export the environment variables in an unambiguous way, don't use env, use export instead. The command export -p lists the values of all environment variables in a way that can be parsed back by the shell. So on the export side, run

export -p >env_var.sh

On the import side, run

. env_var.sh

Caveat: in bash, the output of export -p is parseable, but only by bash. To get output that works in other sh-style shells, set POSIXLY_CORRECT to any value value. This has no harmful effect in other shells, so you can just do

(POSIXLY_CORRECT=$POSIXLY_CORRECT; export -p) >env_var.sh

Setting POSIXLY_CORRECT to the value that it had before doesn't make a difference to the output — either it wasn't in the environment and it won't be after running this, or it was in the environment and its value doesn't change. But it's enough to force bash to use the portable syntax with export in the output of export -p rather than a bash-specific syntax with declare.

Note that importing environment variables can lead to the execution of arbitrary code, so make sure that you only import env_var.txt or env_var.sh from a source that you trust. The culprit is the environment variables, not the fact that . env_var.sh executes the code: just importing variables such as PATH, LD_PRELOAD, ENV, etc. can lead to code execution further down the line.

Solution 2

Use the bash "source" command in that way:

source env_var.txt

All variables should be imported.

For more information: https://en.wikipedia.org/wiki/Dot_(command)

Share:
9,769

Related videos on Youtube

keyboard_solo
Author by

keyboard_solo

Updated on September 18, 2022

Comments

  • keyboard_solo
    keyboard_solo over 1 year

    I would like to import all the 'env' variables from another box to a local machine. I have copied the env variables into env_var.txt on the local box. I have performed the following:

    for i in `cat env_var.txt`; do export $i; done
    

    However, this doesn't seem to set all my env variables correctly. I have modified

    do export $i
    

    into

    do echo $i
    

    and the variables seem to display all fine. What could be causing this problem. Or is there an alternative way to import all the env variables?

    • Pankaj Goyal
      Pankaj Goyal over 7 years
      Why not just $(cat env_var.txt)?
    • keyboard_solo
      keyboard_solo over 7 years
      Wow that worked...That's much simpler too. Thanks!
    • Pankaj Goyal
      Pankaj Goyal over 7 years
      Anytime; glad to have helped.
    • keyboard_solo
      keyboard_solo over 7 years
      Hey Scott, yes I just did env>env_var.txt I used DopeGhoti's recommendation and it imported the variables just fine
    • Gilles 'SO- stop being evil'
      Gilles 'SO- stop being evil' over 7 years
      @DopeGhoti That only works if there are no special characters in the values.
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' over 7 years
    Whether this works depends on how the variables were exported.
  • keyboard_solo
    keyboard_solo over 7 years
    This works but I think this is only for that session. Sourcing allows one to use the env variables for that instance but won't be available the next login. I followed DopeGhoti's example of $(cat env_var.txt)