140

Can someone please tell me what's the correct way to set a bunch of environment variables in the fish shell?

In my ~/.config/fish/config.fish file, I have a function to setup my environment variables like so:

function setTESTENV
      set -x BROKER_IP '10.14.16.216'
      set -x USERNAME 'foo'
      set -x USERPASS 'bar'
end 

When I type from the command prompt setTESTENV and do a env in the command line, I don't see this information.

NotTheDr01ds
  • 15,620
  • 5
  • 44
  • 70
cfpete
  • 4,143
  • 8
  • 27
  • 23

4 Answers4

250

Use Universal Variables.

If the variable has to be shared between all the current user Fish instances on the current computer and preserved across restarts of the shell you can set them using -U or --universal. For example:

set -Ux FOO bar

Using set with -g or --global doesn't set the variable persistently between shell instances.


Note:

Do not append to universal variables in config.fish file, because these variables will then get longer with each new shell instance. Instead, simply run set -Ux once at the command line.

Universal variables will be stored in the file ~/.config/fish/fish_variables as of Fish 3.0. In prior releases, it was ~/.config/fish/fishd.MACHINE_ID, where MACHINE_ID was typically the MAC address.

NotTheDr01ds
  • 15,620
  • 5
  • 44
  • 70
Paolo Moretti
  • 54,162
  • 23
  • 101
  • 92
  • How can I export a new path to `$PATH` in bash? Are there any advantages of setting variables in fish in this way? – GoingMyWay Apr 24 '22 at 12:46
  • 1
    This is a horrible answer. Universal variables should never be used for env vars. Universal variables also shouldn't be used for values that can change each time you start a fish shell or that might be different for concurrently running shells. I can't believe this answer got so many upvotes. – Kurtis Rader Aug 08 '22 at 00:24
  • Have to agree with @KurtisRader. Right tools for the right job, which universal variables are not here. – CJK Aug 08 '22 at 05:22
  • I think it's just because many people are landing on this answer when googling how to set shell variables. The main paragraph makes pretty clear that you only want to use universal variables when they need to be shared between multiple shells and preserved across restarts of the shell. – Paolo Moretti Aug 08 '22 at 13:51
  • @PaoloMoretti: I understand the point you're making. However, in my four decades of using UNIX I've never seen a situation where I want a change to an env var in one shell instance to be automatically reflected in all other instances. At least not where that behavior is more likely to cause problems than benefit. Note that I used, and contributed changes to, the Fish shell for several years. And every single time someone asked about doing `set -Ux` they didn't understand the implications and the `-U` option was always the wrong thing. – Kurtis Rader Aug 09 '22 at 00:56
  • There are some variables that are commonly used by different tools and rarely need to be updated, such as `PATH`, `EDITOR` or `GIT_EDITOR`, where it's convenient to use `set -Ux` – Paolo Moretti Aug 09 '22 at 11:54
95

The variables you are declaring are keep in a local scope inside your function.

Use:

set -g -x

Here "g" is for global.

JosEduSol
  • 5,268
  • 3
  • 23
  • 31
27

another option is to run:

export (cat env_file.txt |xargs -L 1)

where env_file.txt contains rows of the format VAR=VALUE

this has the benefit of keeping the variables in a format supported by other shells and tools

Ophir Yoktan
  • 8,149
  • 7
  • 58
  • 106
14

Environment Variables in Fish

I would like to add that, while @JosEduSol's answer is not incorrect and does help solve the OP problem, -g is only setting the scope to be global, while -x is causing the specified environment variable to be exported to child processes.

The reason the above fails, is because @cfpete is setting the env vars inside a function and the default scope will be local to that function.

Jorge Bucaran
  • 5,588
  • 2
  • 30
  • 48