Skip to content

Instantly share code, notes, and snippets.

@nikoheikkila
Last active April 15, 2024 17:15
Show Gist options
  • Star 34 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save nikoheikkila/dd4357a178c8679411566ba2ca280fcc to your computer and use it in GitHub Desktop.
Save nikoheikkila/dd4357a178c8679411566ba2ca280fcc to your computer and use it in GitHub Desktop.
Fish Shell function for sourcing standard .env files

envsource

⚠️ NOTE (20.5.2023): I don't really use this function at all anymore since there are now tools such as Taskfile, which reads the .env file for me sparing me the need to pollute my session with environment variables.


I've been using Fish shell for years which is great and all, but one thing that has got me frustrated is using it with .env files.

When attempting to run source .env in a project, I usually encounter this problem:

.env (line 2): Unsupported use of '='. In fish, please use 'set KEY value'.
from sourcing file .env
source: Error while reading file '.env'

This is because Fish wants environment variables to be exported with syntax set -gx KEY value instead of export KEY=valuein Bash and ZSH.

So, I added the envsource command into my functions. Ideally, I wouldn't have to do this as many projects use dotenv or similar library to read environment variables. Then again, many projects are not quite there.

# Place this in your Fish functions folder to make it available immediately
# e.g. ~/.config/fish/functions/envsource.fish
#
# Usage: envsource <path/to/env>
function envsource
for line in (cat $argv | grep -v '^#')
set item (string split -m 1 '=' $line)
set -gx $item[1] $item[2]
echo "Exported key $item[1]"
end
end
@vgavro
Copy link

vgavro commented Jul 12, 2022

also you may want to ignore empty lines: (cat $argv | grep -v '^#' | grep -v '^\s*$')

@avegancafe
Copy link

This is a lovely little script, thank you both

@krashanoff
Copy link

krashanoff commented Nov 3, 2022

Great function. Thanks for sharing. vgavro's addition is great, but could also benefit from trimming quoted values: (string trim --chars=\'\" $item[2]).

@tacerus
Copy link

tacerus commented May 20, 2023

My variant with built-in regex matching and a test for whether the input file exists:

function envsource
  set -f envfile "$argv"
  if not test -f "$envfile"
    echo "Unable to load $envfile"
    return 1
  end
  while read line
    if not string match -qr '^#|^$' "$line"
      set item (string split -m 1 '=' $line)
      set -gx $item[1] $item[2]
      echo "Exported key $item[1]"
    end
  end < "$envfile"
end

@eterps
Copy link

eterps commented May 25, 2023

A quick and dirty one-liner that works for straight-forward dotenv files using recent Fish versions:

. (sed 's/^/export /' .env | psub)

@grahamannett
Copy link

@tacerus super helpful. I needed ability to expand a variable as well if you have something like

local_key=key1
remote_key=key2

api_key=$local_key

so added the following (might want to get rid of the else+eval if you dont need):

function envsource
    set -f envfile "$argv"
    if not test -f "$envfile"
        echo "Unable to load $envfile"
        return 1
    end
    while read line
        if not string match -qr '^#|^$' "$line" # skip empty lines and comments
            if string match -qr '=' "$line" # if `=` in line assume we are setting variable.
                set item (string split -m 1 '=' $line)
                set item[2] (eval echo $item[2]) # expand any variables in the value
                set -gx $item[1] $item[2]
                echo "Exported key: $item[1]" # could say with $item[2] but that might be a secret
            else
                eval $line # allow for simple commands to be run e.g. cd dir/mamba activate env
            end
        end
    end < "$envfile"
end

@Dakad
Copy link

Dakad commented Nov 21, 2023

Alternative https://direnv.net/

@jonashaag
Copy link

Strip leading and trailing "

set -gx $item[1] (echo $item[2] | sed -E 's/^"(.+)"$/\1/g')

@nikitavoloboev
Copy link

nikitavoloboev commented Apr 15, 2024

I am getting this every time:

envsource .env
Exported key LOCAL
Exported key email
Exported key EDGEDB_DSN
set: : invalid variable name. See `help identifiers`

~/src/config/fish/functions.fish (line 252):
        set -gx $item[1] $item[2]
        ^
in function 'envsource' with arguments '.env'

(Type 'help set' for related documentation)
Exported key
set: : invalid variable name. See `help identifiers`

~/src/config/fish/functions.fish (line 252):
        set -gx $item[1] $item[2]
        ^
in function 'envsource' with arguments '.env'

(Type 'help set' for related documentation)
Exported key
set: : invalid variable name. See `help identifiers`

~/src/config/fish/functions.fish (line 252):
        set -gx $item[1] $item[2]
        ^
in function 'envsource' with arguments '.env'

(Type 'help set' for related documentation)
Exported key

My .env looks like:

# local
LOCAL=true
email=nikita@
EDGEDB_DSN=edgedb://edgedb:HYmIkn

That is with @grahamannett function:

function envsource
    set -f envfile "$argv"
    if not test -f "$envfile"
        echo "Unable to load $envfile"
        return 1
    end
    while read line
        if not string match -qr '^#|^$' "$line" # skip empty lines and comments
            if string match -qr '=' "$line" # if `=` in line assume we are setting variable.
                set item (string split -m 1 '=' $line)
                set item[2] (eval echo $item[2]) # expand any variables in the value
                set -gx $item[1] $item[2]
                echo "Exported key: $item[1]" # could say with $item[2] but that might be a secret
            else
                eval $line # allow for simple commands to be run e.g. cd dir/mamba activate env
            end
        end
    end <"$envfile"
end

But also:

function envsource
    for line in (cat $argv | grep -v '^#')
        set item (string split -m 1 '=' $line)
        set -gx $item[1] $item[2]
        echo "Exported key $item[1]"
    end
end

@grahamannett
Copy link

@nikitavoloboev dunno, possibly you have an extra setting or something?

ss 2024-04-15 at 11 12 10 AM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment