Modifying PATH with fish shell

ShellEnvironment VariablesFish

Shell Problem Overview


I'm currently playing around with the fish shell and I'm having some trouble wrapping my head around how the PATH variable is set. For what it's worth, I'm also using oh-my-fish.

If I echo my current path I get:

➜ fish echo $PATH
/usr/local/bin /usr/bin /bin /usr/sbin /sbin /usr/local/bin /opt/X11/bin /usr/texbin /Users/myname/.opam/system/bin

Looking at ~/.config/fish/config.fish I see the following line

set PATH /usr/local/bin $PATH /Users/myname/.opam/system/bin

My question is (and this phrasing will probably reflect my lack of knowledge on the subject): prior to config.fish being processed, where is the PATH variable set? ie: where do all of the paths between /usr/local/bin and /Users/myname/.opam/system/bin come from?

Shell Solutions


Solution 1 - Shell

As stated in the official fish tutorial, you can modify the $fish_user_paths universal variable.

Run the following once from the command-line:

set -U fish_user_paths /usr/local/bin $fish_user_paths

This will prepend /usr/local/bin permanently to your path, and will affect the current session and all future instances too because the -U argument will make the variable universal.

From the fish documentation: > ... (Note: you should NOT add this line to config.fish. If you do, the variable will get longer each time you run fish!) > > fish_user_paths, a list of directories that are prepended to PATH. This can be a universal variable.

Solution 2 - Shell

As of fish 3.2.0, released in March 2021, the canonical answer is:

fish_add_path /opt/mycoolthing/bin

Existing answer for fish < 3.2.0:

The recommended commands for modifying PATH from fish's maintainers are:

  1. If you want to run the command once:

    set -Ua fish_user_paths /path
    
  2. If you want to add a command to a startup script, this is idempotent:

     contains /path $fish_user_paths; or set -Ua fish_user_paths /path
    

Solution 3 - Shell

Like all shells, fish inherits its PATH from the environment it is started in. How this is set for login shells differs between operating systems - on Linux, for example, /etc/login.defs controls the initial PATH set for all login shells. I don't know how this is set on OS X.

Next, like bash or csh, the initialisation files for the shell may alter the path. For fish on OS X, there is code in share/fish/config.fish to load paths from the standard OS X path configuration files /etc/paths and /etc/paths.d/*. There is alternative code to set a useful path on Solaris.

There is also code to pick up paths from the universal variable $fish_user_paths, which is the right way to add something to your PATH and have it reflected across all shells.

Solution 4 - Shell

1. Enumerate user paths:

echo $fish_user_paths | tr " " "\n" | nl

2. Append a new bin path, permanently:

set -ga fish_user_paths my_appended_path

3. Remove 7th bin search path by index: (see #1):

set —eg fish_user_paths[7]

Solution 5 - Shell

The way that worked with me :

in your ~/.config/fish/config.fish add the following line:

set -gx PATH /path/to/dir1 /path/to/dir2 $PATH This will append those directories to your $PATH Environment variable.

Solution 6 - Shell

In order to set variables for shell config file, I did as follows:

> The main command to set any user specific variable is > > set -Ua fish_user_paths /path/to/bin/directory/

set -Ux fish_user_paths /usr/local/bin Run touch ~/.config/fish/config.fish, unless it exists.

  1. RUST: set -Ua fish_user_paths $HOME/.cargo/bin

  2. JAVA: set -Ua fish_user_paths /path/to/java/bin

  3. Node & nvm: make sure you have installed nvm properly then

    omf install nvm

    set -gx NVM_DIR /path/to/nvm

  4. Go: set -Ua fish_user_paths /path/to/go/bin/

  5. Scala: set -Ua fish_user_paths /path/to/scala/bin/

  6. Groovy: set -Ua fish_user_paths /path/to/groovy/bin/

  7. Maven: set -Ua fish_user_paths /path/to/mvn/bin/

  8. Gradle: set -Ua fish_user_paths /path/to/groovy/bin/

Finally, refresh your terminal.

PS in some operating system (eg OpenSuse), drop a.

The result after configuration

Solution 7 - Shell

Above solutions do not work well with python virtual environment. The path to virtual environment will not be the first one in the list.

In order to set path once and do not override it every time you start python virtual environment

You need to change the path conditionally in ~/.config/fish/config.fish, like this:

contains /home/$USER/.pyenv/bin $PATH; or set -x PATH "/home/$USER/.pyenv/bin" $PATH
contains /home/$USER/.local/bin $PATH; or set -x PATH "/home/$USER/.local/bin" $PAT
contains /home/$USER/.asdf/bin $PATH; or source ~/.asdf/asdf.fish

This will ensure that you have new paths in $PATH but wnen you spawn new shell for virtual environment you'll will not add these paths again.

Unfortunately paths set with set -Ua fish_user_paths would endup in the beginning of the $PATH, pushing your virtual environment path away from the first place.

Solution 8 - Shell

You may use a script like the one below to ease adding or removing paths:

#!/usr/bin/env fish

#remove PHP72
for argv in /usr/local/opt/[email protected]/bin /usr/local/opt/[email protected]/sbin;
    while contains $argv $fish_user_paths
        set -l index (contains -i $argv $fish_user_paths)
        set –erase –universal fish_user_paths[$index]
    end
end

#add PHP74
for argv in /usr/local/opt/[email protected]/bin /usr/local/opt/[email protected]/sbin;
    if contains $argv $fish_user_paths
        echo "Path already contains $argv"
    else
fish_add_path $argv
    end
end

echo $fish_user_paths | tr " " "\n" | nl

brew services stop [email protected]
brew services start [email protected]

Copied from https://www.tai.ro/2021/10/22/how-to-switch-path-in-fish-shell-with-example-script/

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPaymahn MoghadasianView Question on Stackoverflow
Solution 1 - ShellKasperView Answer on Stackoverflow
Solution 2 - ShellMaximilianView Answer on Stackoverflow
Solution 3 - ShellZancheyView Answer on Stackoverflow
Solution 4 - ShelljorjunView Answer on Stackoverflow
Solution 5 - ShelltakizeeView Answer on Stackoverflow
Solution 6 - ShellEsmaeil MIRZAEEView Answer on Stackoverflow
Solution 7 - ShellJanusz SkoniecznyView Answer on Stackoverflow
Solution 8 - ShellJorjView Answer on Stackoverflow