Bash Environment Variables – Share Between Bash and Fish

bashenvironment-variablesfish

bash and fish scripts are not compatible, but I would like to have a file that defines some some environment variables to be initialized by both bash and fish.

My proposed solution is defining a ~/.env file that would contain the list of environment variables like so:

PATH="$HOME/bin:$PATH"
FOO="bar"

I could then just source it in bash and make a script that converts it to fish format and sources that in fish.

I was thinking that there may be a better solution than this, so I'm asking for better way of sharing environment variables between bash fish.

Note: I'm using OS X.


Here is an example .env file that I would like both fish and bash to handle using ridiculous-fish's syntax (assume ~/bin and ~/bin2 are empty directories):

setenv _PATH "$PATH"
setenv PATH "$HOME/bin"
setenv PATH "$PATH:$HOME/bin2"
setenv PATH "$PATH:$_PATH"

Best Answer

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.

Related Question