rustup icon indicating copy to clipboard operation
rustup copied to clipboard

PATH support doesn't work for fish shell

Open brson opened this issue 8 years ago • 40 comments

It's a popular shell and doesn't read .profile. cc @nagisa cc https://github.com/rust-lang-nursery/rustup.rs/pull/468

brson avatar May 17 '16 00:05 brson

Many linuxes should be covered by putting the environment to both ~/.pam_environment and ~/.profile, though it is a bag of worms because either or both can be disabled, not run or configured to be in another, non-standard location (i.e. not $HOME/.file).

For OS X it seems like you’d want to also inform launchd about the updated path with launchctl setenv PATH $PATH after setting the environment variable in any of the files.

Either way this goes, fixing https://github.com/rust-lang-nursery/rustup.rs/issues/473 is another thing that would fix a lot of the problem here, since both /usr/local or ~/local/, where I’d like to have rustup be, are already in my path.

nagisa avatar May 24 '16 16:05 nagisa

FWIW OCaml's opam has a similar problem and handles it just by having a version of the add-stuff-to-PATH hook for each shell. There's also the "eval (opam config env)" idiom which sets the appropriate environment variables to point to wherever opam thinks they need to point to, including PATH. So a solution like that might work well.

snheath avatar May 26 '16 19:05 snheath

rustup create env with export PATH="$HOME/.cargo/bin:$PATH". Why not simply also create a file env.fish (like opam) with set -gx PATH "$HOME/.cargo/bin" $PATH;?

ariasuni avatar Sep 26 '16 20:09 ariasuni

this still doesn't work. ~/.cargo/env is completely wrong.

robey avatar Mar 04 '17 19:03 robey

I think you can just drop the set -gx ... command in a file in ~/.config/fish/conf.d/, see http://fishshell.com/docs/current/index.html#initialization

icefoxen avatar Mar 05 '17 03:03 icefoxen

I have had this issue a few times. It is easy to resolve.

Create a fish config file in the below directory, if it doesn't already exist.

~/.config/fish/config.fish

Then add the following line to the file.

export PATH="$HOME/.cargo/bin:$PATH"

Once you restart your terminal, the rust commands should work again.

chriswoollard avatar Sep 19 '17 08:09 chriswoollard

Exporting in a more fisher way

set PATH $HOME/.cargo/bin $PATH

in ~/.config/fish/config.fish maybe better.

ndac-todoroki avatar Sep 23 '17 10:09 ndac-todoroki

An even more fishier way would be to use the fish_user_paths universal variable.

Example: set -U fish_user_paths $HOME/.cargo/bin $fish_user_paths

No need to mess with config files. A universal variable, once set, is permanently and persistently set across all fish shell sessions. The contents of that variable are automatically prepended to the $PATH environment variable.

mojotx avatar Sep 26 '19 22:09 mojotx

Hi, any update with this, I think it's confusing that the script doesn't even at least mention this issue, nor is it mentioned with the documentation. I believe it's worthwhile to make change in the installation script to correctly handle for fish.

clearnote01 avatar Dec 22 '19 10:12 clearnote01

Unfortunately nobody who works on rustup uses fish so we're not really in a position to know if anything we do would be right. I've labelled this E-mentor because I'm prepared to assist someone who knows fish to prepare a PR, but I simply don't know the right things to do. If you want to help solve this, I'm around either on this issue, or on the Rust discord in #wg-rustup

kinnison avatar Dec 23 '19 08:12 kinnison

As I commented above, we probably want to solve this is in a way that’s shell-independent. On linux that’d be .pam_environment and on macOS we’d use launchctl.

This will only become more relevant as people start experimenting and depending more with non-POSIX shells such as nushell or powershell. We cannot possibly hope to handle all these different shells in a shell-specific manner.

nagisa avatar Dec 23 '19 17:12 nagisa

Python virtualenv module does handle each shell in shell-specific manner. It has a similar problem to set environment variables for these different shells. For Unixy systems they have multiple versions of this activate script to support fish along with csh and bash/zsh.

At least for linux there are some problems with ~/.pam_environment. Currently it doesn't seem to be read by WSL bash - issue here.

Another, problem is that there seems to be a need to re-login after making changes in ~/.pam_environment, as per following:

Suitable files for environment variable settings that should affect just a particular user (rather than the system as a whole) are ~/.pam_environment and ~/.profile. After having edited one of those files, you should re-login in order to initialize the variables.

https://help.ubuntu.com/community/EnvironmentVariables

clearnote01 avatar Dec 23 '19 21:12 clearnote01

@kinnison I use fish and am happy to try digging into Rustup if someone can point me in the right direction.

Realistically there seems to be only a small handful of non-POSIX shells people actually use, and once support is implemented it probably won't need much in the way of maintenance.

icefoxen avatar Dec 29 '19 15:12 icefoxen

@icefoxen Hi, I'm glad that you're interested in helping. Just before the holidays, @clearnote01 (I believe) was looking into things, so it may be best to join forces with them. If they've run out of energy for the work, perhaps you might help bring it over the line.

kinnison avatar Dec 30 '19 08:12 kinnison

So any progress? Also why not use /etc/profile which is read by shell independent?

lordlycastle avatar Jul 21 '20 23:07 lordlycastle

I believe @workingjubilee is looking at shell support so it's possible Fish may come later from their work. We won't touch /etc/profile because that's global and rustup is a user-local installer. Also, if fish reads /etc/profile why doesn't it also read ~/.profile ?

kinnison avatar Jul 22 '20 07:07 kinnison

FYI fish does not read any profile files

Source: https://github.com/fish-shell/fish-shell/issues/3665

max-sixty avatar Jul 22 '20 14:07 max-sixty

I recommend that because fish sessions are persisted that we detect fish during setup and direct the user to simply run the command which sets PATH appropriately, possibly after writing a fish script to make it easy.

workingjubilee avatar Jul 23 '20 02:07 workingjubilee

I would recommend simply running set -Ua fish_user_paths $HOME/.cargo/bin if on fish.¹ It persistently adds the cargo path to path and does not require modifying any file(s).

[1] https://github.com/fish-shell/fish-shell/issues/527#issue-10108069

aadibajpai avatar Nov 02 '20 07:11 aadibajpai

I still had some issues even after trying set -Ua fish_user_paths $HOME/.cargo/bin, so instead I added the line source $HOME/.cargo/env to my config.fish file, which worked!

TylerYep avatar Nov 09 '20 02:11 TylerYep

fwiw, poetry installation which is also very similar to rustup does it like that as well https://github.com/python-poetry/poetry/blob/cc195f1dd086d1c4d12a3acc8d6766981ba431ac/get-poetry.py#L256

aadibajpai avatar Nov 19 '20 15:11 aadibajpai

Rustup prefers to prepend it's bin directory to PATH in order to override any system rustc, so you would want to use -p instead of -a when setting fish_user_paths like so:

$ set -Up fish_user_paths ~/.cargo/bin

jwillikers avatar Dec 10 '20 12:12 jwillikers

For people stumbling across it later on. Newer fish versions have a new builtin command for appending to a path:

fish_add_path <path>

This can be even called multiple times and will only append once to the path. Note that the builtin errors if the path doesn't exist.

mainrs avatar May 12 '21 07:05 mainrs

This can be even called multiple times and will only append once to the path.

It actually prepends to the path by default, which is even better. That is unless the given directory already exists in the path, in which case it is not moved to the front unless the -m switch is given.

jhenninger avatar May 14 '21 09:05 jhenninger

An even more fishier way would be to use the fish_user_paths universal variable.

Example: set -U fish_user_paths $HOME/.cargo/bin $fish_user_paths

No need to mess with config files. A universal variable, once set, is permanently and persistently set across all fish shell sessions. The contents of that variable are automatically prepended to the $PATH environment variable.

Many thanks, this works! And I recommand use fish_add_path $HOME/.cargo/bin, it's easier and directly supported by fishshell. :wink:

Ray-Eldath avatar Jul 27 '21 15:07 Ray-Eldath

rustup create env with export PATH="$HOME/.cargo/bin:$PATH". Why not simply also create a file env.fish (like opam) with set -gx PATH "$HOME/.cargo/bin" $PATH;?

As I'm using ohmyfish I have found the config for my terminal here .config/fish/conf.d/omf.fish.

emadbaqeri avatar Sep 25 '21 09:09 emadbaqeri

export PATH="$HOME/.cargo/bin:$PATH" works fine :+1:

Powerm1nt avatar Feb 18 '22 18:02 Powerm1nt

即使在尝试之后我仍然遇到一些问题set -Ua fish_user_paths $HOME/.cargo/bin,所以我将这一行添加source $HOME/.cargo/env到我的config.fish文件中,这有效!

~/.cargo/env (line 4): 'case' builtin not inside of switch block case ":${PATH}:" in ^ from sourcing file ~/.cargo/env called on line 6 of file ~/.config/fish/config.fish from sourcing file ~/.config/fish/config.fish called during startup source: Error while reading file '/Users/lw/.cargo/env' It don't work

wenwen12345 avatar Feb 23 '22 13:02 wenwen12345

I add the $HOME/.cargo/bin in my /etc/paths, it works.

wenwen12345 avatar Feb 26 '22 00:02 wenwen12345

Create a new fish config file (or use an existing one). Here for example pathvars under:

nano ~/.config/fish/conf.d/pathvars

and add

if status --is-login
    set -gx PATH $PATH ~/.cargo/bin
end

login/logout

freakydude avatar Feb 28 '22 22:02 freakydude