Safest way to store environment variable value in a file

If it's storing for the sake of reading it in later (in a bash script), just use declare -p KEY and then source the file to read it in again. If you just want to store the value, use printf '%s\n' "$KEY" as you would do when you output any variable data.


printf '%s\n' "$KEY" >key.pem


printf 'BEGIN %s END\n' "$KEY" >key.pem

or whatever you need to output.

Your issue occurs since -n is a valid option to echo in bash. The strings -e and -E (and combinations like -neEne) would also cause issues in bash, for the same reason. Depending on how bash is built or the environment or options, backslash characters in arguments may also be a problem.

These issues and more are outlined in the following Q/A:

  • Why is printf better than echo?

Many systems have a printenv command that outputs the contents of the given environment variable followed by one newline character to standard output (printenv appeared in 3BSD in the late 70s):

printenv 'My Env Var' > file

Would store the content of the My Env Var variable followed by NL into file in all shells on those systems.

For environment variables that are mapped to shell variables (includes at least those whose name starts with an ASCII letter or underscore and are followed by 0 or more ASCII letters, digits or underscore, and are not otherwise special variables set by the shell), in Bourne-like shells (also works in fish), you can do the same with:

printf '%s\n' "$ENVVAR" > file

(though if the variable is unset, that will still store an empty line into file)

In rc-like shells (where all shell variables are mapped to environment variables):

printf '%s\n' $ENVVAR > file
printf '%s\n' $'My Env Var' > file

(same caveat as above)

In csh-like shells:

printf '%s\n' $ENVVAR:q > file

(if the variable is not set, it will fail and not overwrite file)

Some implementations/versions of ksh don't have printf builtin. In those, you could also do:

print -r -- "$ENVVAR" > file