-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fish subshell changes PATH order #5456
Comments
The reason it's getting put at the end is that it is indeed in the inherited You should probably just change it to a test to see if it's already part of the PATH and remove it if so and then just put it in the front (no tests to see if if's a login shell or interactive one). |
Good enough for me. Thank you for the explanation and recommendation! |
@Darkshadow2 I don't understand the logic here - isn't this reordering only supposed to happen for login shells? The current behavior seems to be that this always happens. When I explicitly spawn a sub-shell, I want to environment the be inherited unmodified, yet there seems to be no way to do so. |
It's set to always happen, and looks like it has been that way (with one brief exception) since it was added. It's in |
This is really irritating. I started hitting this after fish 3.0.0 dropped. I use Nix so it's very important to me to be able to have the Nix paths at the very beginning. Without it I keep falling back to the macOS bundled version of vim (which is dark and sad) or even worse, the BSD versions of cli utils! Is there any way around this? |
I'm going to re-open this issue as this is a problem for
My current work-around solution is hackish, and other people are having this issue with (edit: if it is critical that your subshell PATH be consistent, then I simply suggest switching back to |
I think I know what is happening here, but I am not seeing any change in behavior between fish 2.7.1 and fish 3.0. The problem is that you are directly manipulating Replace if status --is-login
set -gx PATH ~/.pyenv/shims $PATH
end with if status --is-login
set -g fish_user_paths ~/.pyenv/shims fish_user_paths
end Or if if not contains ~/.pyenv/shims $fish_user_paths
set -g fish_user_paths ~/.pyenv/shims $fish_user_paths
end |
I'm finding that With the following $ cat ~/.config/fish/config.fish
if status --is-login
set -gx PATH ~/.pyenv/shims $PATH
end $ fish --version
fish, version 2.7.1
$ echo $PATH
/Users/thepathunfolds/.pyenv/shims /usr/local/bin /usr/bin /bin /usr/sbin /sbin /opt/X11/bin /usr/local/git/bin
# launch sub-shell
$ fish
$ echo $PATH
/Users/thepathunfolds/.pyenv/shims /usr/local/bin /usr/bin /bin /usr/sbin /sbin /opt/X11/bin /usr/local/git/bin
# shim path is at the front $ fish --version
fish, version 3.0.0
$ echo $PATH
/Users/thepathunfolds/.pyenv/shims /usr/local/bin /usr/bin /bin /usr/sbin /sbin /opt/X11/bin /usr/local/git/bin
# launch sub-shell
$ fish
$ echo $PATH
/usr/local/bin /usr/bin /bin /usr/sbin /sbin /opt/X11/bin /usr/local/git/bin /Users/thepathunfolds/.pyenv/shims
# shim path is now at the end |
In order to get my Python environment going again, I worked around this with the following function: function path-reordered -d "Echos the elements of $PATH, reordered such that custom paths precede standard system paths. This can be used to work around a fish 3.0.0 bug in which sub-shells fail to respect path ordering."
set -l sys_paths
for p in $PATH
if string match -q -r '^/usr/|^/s?bin(/|$)' $p
set -a sys_paths $p
else
echo $p
end
end
for p in $sys_paths; echo $p; end
end My config.fish now looks like: if status --is-login
set PATH $HOME/.local/bin $PATH
# etc.
else
set PATH (path-reordered)
end Your definition of what constitutes a system path may vary. |
Please try 4bf5288 from my "etc-paths-keep-order" branch. That makes it so, when we read from /etc/paths{,.d}, we only append paths that aren't already there, so the order should stay stable. |
That resolved the narrow issue, although it still seems a bit off. I removed all of the path customizations I had in my
Stock fish 3.0.0:
With change:
|
@psagers: What's the path in bash? This $PATH looks like fish inherits "/usr/bin /bin /usr/local/bin", and then appends "/usr/sbin /sbin" from /etc/paths. Which seems alright? If that's not acceptable, then this would actually require us to only do path_helper once instead of keeping the order. One possibility would be to only do it for login shells (AFAIK macOS terminal.app starts login shells by default?), another to export a variable to inhibit it. I have no idea how bash does this. Under what conditions is path_helper started there? Can we replicate those? |
I actually tried bash as well and (again, after moving I mostly work on FreeBSD, so I'm learning some new things about macOS here. The bash/csh invocations of Updated: I changed the conditional to |
I'm also having this problem. I set my $PATH in .bashrc, then start up fish. All my $PATH modifications were inherited no problem with fish 2.x. I just upgrade to 3.x and now the system default path (and paths out of /etc/paths.d - see below) appear before all my modifications.
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Should fix fish-shell#5456. [ci skip]
So, we now already only read /etc/paths in login shells (which macOS terminals tend to run, AFAIK), but I believe we still need the change to keep the order. I've submitted #5767, but I can't actually test it, so I'm going to have to have someone on macOS do that for me. Ideally several people with different configurations. |
* Keep the order for $PATH and $MANPATH when reading /etc/paths Fixes #5456.
@faho I have got the same problem, may I help to test ? I wonder how to install the 3.0.3, I have install 3.0.2 with Installer. Updated:I have flowed
and replace
and the result of |
Had this collision today installing https://github.com/kennethreitz/fish-pipenv on Linux. The race described in the documentation there appears to be occurring, though I haven't really debugged it. https://github.com/kennethreitz/fish-pipenv/blob/master/conf.d/pipenv.fish#L3 calls The fundamental issue re: Any thoughts? cc @kennethreitz @jorgebucaran |
@sjuxax happy to try to help, I had trouble following your description. I understand this has something to do with the fact that |
I was referencing the explanation in the fish-pipenv README (also discussed at sentriz/fish-pipenv#1). In particular:
Basically, the Ultimately the plugin should probably handle this itself by checking the path at runtime, but it raises questions around the semantics of |
Yes, it is intended. We have three options when it comes to conf.d snippets vs config.fish:
And we picked 1. Ideally, you wouldn't rely on the user's configuration - like you said, it should just check the path at runtime (or just try it?). Checking first is a bit of a premature optimization - If you absolutely could not, you'd have to tell the user to insert their configuration for e.g. $PATH in a snippet that's sourced early - 00-path.fish or something. But either way, none of that is really related to this issue - if you still have more questions related to this, I'd encourage you to open another one. |
Just replace the issue number because this is effectively a replacement of the previous. [ci skip]
For posterity, as I have just spent twenty minutes trying to understand the changes here:
|
That sounds about right. |
the script did not work on macOS because `fish` prepends the contents of `/etc/paths` and `/etc/paths.d/*` to `$PATH` [1], resulting in BSD `readlink` to be used instead of the one from `nixpkgs`. this is fixed on the master branch [2], but the patch is staged for 3.1.0 (!), while the most recent release is 3.0.2. well, also the script was badly broken, I never ran it since changing it the last time... [1]: fish-shell/fish-shell#5456 [2]: fish-shell/fish-shell#5637
@zanchey wished I've seen your comment before spending 20min trying to figure out where is the fix |
I use Pyenv which places its shims at the head of the PATH.
I also use Pipenv whose documentation recommends a certain shell-configuration.
pipenv shell --fancy
spawns a subshell...however, the order of the PATH variable is different in the subshell.I've given a simplified example below:
I created a simple
config.fish
to demonstrate the issue.Steps to repro:
The
set -gx
command inconfig.fish
is not executed in the sub-shell, but I would normally expect that the new sub-shell simply inherits the global PATH variable.From #4192, and #4336 I understand that Fish adds in the paths from
/etc/paths
and/etc/paths.d
.Is there a way to enforce the order that these paths are added, so that they are appended, rather than prepended?
The text was updated successfully, but these errors were encountered: