How to remove a path from $PATH variable in fish?
Solution 1
The 'fish' way of setting the $PATH variable is to actually use set --universal fish_user_paths $fish_user_paths /new/path/here
. Then $fish_user_paths is actually prepended to the $PATH variable when a new session starts. The $PATH documentation doesn't currently tell you how to delete it though.
In fish every variable is actually a list (array), and you can conveniently access each item directly by using an index/indice. echo $fish_user_paths
will print out a space delimited version of every item in the list, make the spaces newline with the translate function echo $fish_user_paths | tr " " "\n"
and then put line numbers on it with the number lines function, echo $fish_user_paths | tr " " "\n" | nl
. Then delete it with set --erase --universal fish_user_paths[5]
. You must use --universal
or it will not work in any new sessions.
If someone has the time, please submit a PR to the repo with this example. I opened an issue here.
tldr;
-
echo $fish_user_paths | tr " " "\n" | nl
// get the number of the one you want to delete, e.g. the 5th one -
set --erase --universal fish_user_paths[5]
// erase the 5th path universally so it persists in new sessions
Solution 2
As Elijah says, best practice is to modify the fish_user_paths
rather than the global PATH
. To avoid ever having to Google this again…
- Create a couple of functions that only modify
fish_user_paths
- Make both functions autoloading
To add to user paths:
function addpaths
contains -- $argv $fish_user_paths
or set -U fish_user_paths $fish_user_paths $argv
echo "Updated PATH: $PATH"
end
To remove a user path if it exists (partial credit to this):
function removepath
if set -l index (contains -i $argv[1] $PATH)
set --erase --universal fish_user_paths[$index]
echo "Updated PATH: $PATH"
else
echo "$argv[1] not found in PATH: $PATH"
end
end
And of course, to make them autoloading:
funcsave addpaths; funcsave removepath
Example Usage:
> addpaths /etc /usr/libexec
Modifying PATH: /usr/local/bin /usr/bin /bin /usr/sbin /sbin
Updated PATH: /etc /usr/libexec /usr/local/bin /usr/bin /bin /usr/sbin /sbin
> removepath /usr/libexec
Modifying PATH: /etc /usr/libexec /usr/local/bin /usr/bin /bin /usr/sbin /sbin
Updated PATH: /etc /usr/local/bin /usr/bin /bin /usr/sbin /sbin
Solution 3
This should erase paths 6 through the last path:
set -e PATH[6..-1]
The -e flag is erase. See help set
.
Solution 4
Reset fish_user_paths withtout the path you don't want anymore:
$ set -U fish_user_paths /usr/local/bin /usr/bin /bin /usr/local/games /usr/game
More info: https://fishshell.com/docs/current/tutorial.html#tut_path
Related videos on Youtube

tomekK
Updated on September 18, 2022Comments
-
tomekK 3 months
I am using fish as my shell in Debian and recently (after some upgrade) whenever I try to use command completion I have:
set: No such file or directory set: Could not add component /usr/lib/x86_64-linux-gnu/libfm to PATH. set: No such file or directory
Running this:
echo $PATH
Gives me this:
/usr/lib/x86_64-linux-gnu/libfm /usr/local/bin /usr/bin /bin /usr/local/games /usr/games
In my system there is no
/usr/lib/x86_64-linux-gnu/libfm
, so I understand why fish is complaining, but I cannot find how to remove this path from my$PATH
variable.Does anyone know how can I do this?
-
glenn jackman over 8 years
grep -R /usr/lib/x86_64-linux-gnu/libfm ~/.config/fish /usr/share/fish
??
-
-
clozach over 5 yearsNote: I've just discovered that this approach won't remove a path added through some other mechanism; Some dot-file cleanup may be in order if you find a path coming back each time you open a new terminal session.
-
Elijah Lynn about 5 yearsThis is great, just added to my local!
-
Pär Nils Amsen almost 5 yearsWhy is this so arcane? Shouldn't this be a build in feature and added to the documentation so that people doesn't have to Google and end up here? Oh well..
-
Elijah Lynn about 4 yearsI think if we take @clozach's answer here superuser.com/a/1212305/30982, which is the addpaths() and removepath() function, and open a PR then that would be the first step to getting it added. Most of the maintainers are pretty good to work with, one seems grumpy to me, but overall I think we would have a good chance. So that is our next step.
-
Daniel about 3 yearsthis will only work for the current session
-
theprogrammer over 1 yearThis is not working for me. It just prints the back to me, thats all.
-
theprogrammer over 1 year
echo $fish_user_paths
doesn't return anything, butecho $PATH
returns some stuff. -
Elijah Lynn over 1 yearWhat does
echo $SHELL
return? It should return/usr/bin/fish
or something like that. My suspicion is that it is a different shell. If it is fish, then what isfish --version
? -
demisx over 1 yearThis
set --erase --universal fish_user_paths[4]
doesn't work for me in v3.3.1 for some reson. No errors, but the path is not being deleted from the list. -
m0j0 over 1 yearA better solution, added in a more recent version of fish, is to use the fish_add_path command. fishshell.com/docs/current/cmds/fish_add_path.html
-
ivan_pozdeev 9 monthsUsing spaces as delimiters will break if a path has a space in it. The only 100% safe delimiter is
\0
.