Reputation: 10349
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?
Upvotes: 173
Views: 182274
Reputation: 8530
Current answer
As of fish 3.2.0, released in March 2021, the canonical approach is:
fish_add_path /opt/mycoolthing/bin
This works both one-off interactively, and in config.fish
— it won't produce duplicates in the config.fish
case.
Previous answer for fish < 3.2.0:
The recommended commands for modifying PATH
from fish's maintainers are:
If you want to run the command once:
set -Ua fish_user_paths /path
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
Upvotes: 208
Reputation: 147
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.
Upvotes: 7
Reputation: 2701
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/
Upvotes: 0
Reputation: 19030
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.
Upvotes: 0
Reputation: 134
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]
Upvotes: 7
Reputation: 1210
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.
RUST
: set -Ua fish_user_paths $HOME/.cargo/bin
JAVA
: set -Ua fish_user_paths /path/to/java/bin
Node
& nvm
: make sure you have installed nvm
properly then
omf install nvm
set -gx NVM_DIR /path/to/nvm
Go
: set -Ua fish_user_paths /path/to/go/bin/
Scala
: set -Ua fish_user_paths /path/to/scala/bin/
Groovy
: set -Ua fish_user_paths /path/to/groovy/bin/
Maven
: set -Ua fish_user_paths /path/to/mvn/bin/
Gradle
: set -Ua fish_user_paths /path/to/groovy/bin/
Finally, refresh your terminal.
PS in some operating system (eg OpenSuse), drop a
.
Upvotes: 3
Reputation: 13622
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.
Upvotes: 247
Reputation: 2040
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.
Upvotes: 12