Share environment variables between bash and fish
bash has special syntax for setting environment variables, while fish uses a builtin. I would suggest writing your .env file like so:
setenv VAR1 val1
setenv VAR2 val2
and then defining setenv
appropriately in the respective shells. In bash (e.g. .bashrc):
function setenv() { export "$1=$2"; }
. ~/.env
In fish (e.g. config.fish):
function setenv; set -gx $argv; end
source ~/.env
Note that PATH will require some special handling, since it's an array in fish but a colon delimited string in bash. If you prefer to write setenv PATH "$HOME/bin:$PATH"
in .env, you could write fish's setenv like so:
function setenv
if [ $argv[1] = PATH ]
# Replace colons and spaces with newlines
set -gx PATH (echo $argv[2] | tr ': ' \n)
else
set -gx $argv
end
end
This will mishandle elements in PATH that contain spaces, colons, or newlines.
The awkwardness in PATH is due to mixing up colon-delimited strings with true arrays. The preferred way to append to PATH in fish is simply set PATH $PATH ~/bin
.
Most Unix systems use PAM. The pam_env
module reads a file very much like your .env
.
On Linux, pam_env
reads a system file /etc/environment
and a user file ~/.pam_environment
. On OS X (and other *BSD, which likewise use OpenPAM), it appears that pam_env
only reads the system file, so you can't set variables per user this way, only for all users.
There is (now?) an easier way, per @Zanchey's answer here
Fish Shell: How to set multiple environment variables from a file using export
The digest though is:
Fish:
echo -e "foo=3\nfoobar=4" > .env; export (cat .env); env | grep foo
Bash:
echo -e "foo=3\nfoobar=4" > .env; export $(cat .env | xargs); env | grep foo
with the difference being $
and the use of xargs