简体   繁体   中英

Modifying PATH with fish shell

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?

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.

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

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 .

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]

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 .

配置后的结果

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.

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/php@7.2/bin /usr/local/opt/php@7.2/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/php@7.4/bin /usr/local/opt/php@7.4/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 php@7.2
brew services start php@7.4

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM