Skip to content
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

The master branch of rbenv breaks inside of tmux. #369

Closed
tmiller opened this issue Mar 28, 2013 · 29 comments
Closed

The master branch of rbenv breaks inside of tmux. #369

tmiller opened this issue Mar 28, 2013 · 29 comments
Milestone

Comments

@tmiller
Copy link

tmiller commented Mar 28, 2013

When using the master branch version of rbenv, tmux no longer respects rbenv. For example I have global ruby setup to 2.0.0-p0 and when I run rbenv version it correctly reports 2.0.0-p0, it is also correctly reported when I run ruby --version. Now in the same session I start a new tmux session using tmux new. Now when I run rbenv version it still correctly reports 2.0.0-p0, however when I run ruby --version it now reports 1.8.7. When I run which ruby it shows me /usr/bin/ruby instead of the ruby shim.

@tmiller
Copy link
Author

tmiller commented Mar 28, 2013

I forgot to mention that everything works as expected on v0.4.0.

@mislav
Copy link
Member

mislav commented Mar 28, 2013

Your problem is due to $PATH ordering. You could have shared your PATH with us, but you don't have to now because I know exactly what happened.

Your PATH in your regular terminal session is something like:

rbenv shims : rbenv bin : system paths

By entering tmux, you spawned a nested interactive subshell. That means that your .bashrc or .zshrc get sourced again, and the same paths get added to the already prepared PATH. You finish up with something like:

rbenv bin : system paths : rbenv shims : rbenv bin : system paths

The master branch of rbenv avoids adding shims to the PATH twice. So you finished with ruby from system paths (/usr/bin/ruby) having precedence over rbenv's shims (~/.rbenv/shims/ruby).

The solution is to configure your shell initialization file (e.g. .bashrc) to not repeat the PATH setup if it's already there. I solve that by running my PATH through a small executable that strips out the duplicates.

@mislav mislav closed this as completed Mar 28, 2013
@jsmestad
Copy link

@mislav maybe I am missing it, but I cannot figure out quite where your checking the PATH for duplicates in that file you linked to. Could you add something to the README for ZSH and BASH users?

@mislav
Copy link
Member

mislav commented Apr 21, 2013

It's handled by a command I call in the end of the above linked file

@jgeiger
Copy link

jgeiger commented May 24, 2013

I'm not able to get your solution working as it puts the rbenv shims and bin paths at the end of the PATH. At this point /usr/bin/ruby takes over.

As you can see the shims get properly added in the non-tmux version, but adding the consolidation code moves them to the end anyway.

rbenv.sh (bash_profile include)

export PATH="$HOME/.rbenv/bin:$PATH"
echo $PATH
eval "$(rbenv init -)"
echo $PATH
export PATH="$(consolidate-path)"
echo $PATH

output from tmux new tab

/Users/code/.rbenv/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Users/code/.rbenv/shims:/Users/code/.rbenv/bin
/Users/code/.rbenv/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Users/code/.rbenv/shims:/Users/code/.rbenv/bin
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Users/code/.rbenv/bin:/Users/code/.rbenv/shims

output from new iterm window

/Users/code/.rbenv/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin
/Users/code/.rbenv/shims:/Users/code/.rbenv/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Users/code/.rbenv/shims:/Users/code/.rbenv/bin

@mislav
Copy link
Member

mislav commented May 24, 2013

@jgeiger Strange; it looks like as though you have something in /etc/zshenv or ~/.zshenv?

@jgeiger
Copy link

jgeiger commented May 24, 2013

The default shell is bash but I checked the files you suggested. Right now my workaround is to just remove the check to see if shims has already been added. Once I do that, everything works file (with the issue of having rbenv shims,bin in the path twice)

~/.zshenv is empty

box:etc $ cat zshenv

# system-wide environment settings for zsh(1)
if [ -x /usr/libexec/path_helper ]; then
       eval `/usr/libexec/path_helper -s`
fi

box:etc $ /usr/libexec/path_helper -s

PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Users/code/.rbenv/shims:/Users/code/.rbenv/bin"; export PATH;

@mislav
Copy link
Member

mislav commented May 24, 2013

@jgeiger As I suspected, there is your problem: you have a /etc/zshenv calling out to path_helper. This is not your fault, but a bug that ships with OS X. Rename that file to zprofile:

sudo mv /etc/zshenv /etc/zprofile

@jgeiger
Copy link

jgeiger commented May 24, 2013

I tried this and it didn't seem to help. I'm running into an issue where the rbenv bin,shims always end up at the end up the path. The box I'm working on may be re-imaged in the near future so for now I'll just fix it in the rbenv init script by removing the check to see if shims already exists.

Thanks.

@tonyarkles
Copy link

It seems like tmux will always call the profile for your shell, not just the rc (I'm using bash, and it's definitely calling /etc/profile, which also has a call to path_helper).

What I'm doing to fix it is changing /etc/profile to this:

if [[ -z $TMUX ]] && [ -x /usr/libexec/path_helper ]; then
        eval `/usr/libexec/path_helper -s`
fi

instead of

if [ -x /usr/libexec/path_helper ]; then
        eval `/usr/libexec/path_helper -s`
fi

@mislav
Copy link
Member

mislav commented Jul 13, 2013

tmux doesn't call the profile for any shell by itself. Your shell does, because with tmux, interactive shells get nested and that can lead to the above problems.

Reopening this because it's getting people tripped up

@mislav mislav reopened this Jul 13, 2013
@markprzepiora
Copy link

After a couple of hours of tinkering, the optimal way to solve this (without disabling path_helper entirely) is to make the following patch to /etc/zshenv:

--- /etc/zshenv.orig
+++ /etc/zshenv
@@ -1,4 +1,5 @@
 # system-wide environment settings for zsh(1)
 if [ -x /usr/libexec/path_helper ]; then
+ PATH=""
  eval `/usr/libexec/path_helper -s`
 fi

The underlying problem is that all your shell configuration files are loaded twice when you create a tmux session/window. So the following happens:

  1. /etc/zshenv is loaded, which runs /usr/libexec/path_helper, which sets your PATH variable.
  2. Your own configuration scripts, which load rbenv, which puts the shims directory at the front of your PATH.
  3. You run tmux.
  4. path_helper runs again, putting stuff before your shims directory.
  5. Your configuration scripts run again, and rbenv sees that the shims directory already exists in your PATH, and does nothing.

This patch ensures that your shell configuration is loaded starting from a blank path. This has two benefits:

  1. You won't end up with duplicate paths and an even messier PATH variable.
  2. At step 5, rbenv will see that the shims directory doesn't exist in your PATH yet, and load it properly.

@cpb
Copy link

cpb commented Aug 21, 2013

@markprzepiora's solution worked for me

@bayendor
Copy link

I ran into the same problem with tmux & rbenv this morning, @tonyarkles solution worked for me as a bash user.

@graywh
Copy link

graywh commented Aug 26, 2013

@markprzepiora the problem with your solution (versus what @mislav recommends: moving /etc/zshenv to /etc/zprofile) is that any modifications to $PATH in ~/.zprofile will be wiped out when starting a sub-shell or running a script.

@tuomasj
Copy link

tuomasj commented Nov 12, 2013

I'm running tmux + bash in ITerm 2 (Mac OS X 10.9), and @tonyarkles solution worked for me.

@rajibahmed
Copy link

I'm running tmux + bash in ITerm 2 (Mac OS X 10.9) and @tonyarkles solution worked for me as well. But after a boot or shell rebooting.
//best

@audionerd
Copy link
Contributor

EDIT: Don't do this. It sorts alphabetically, which you probably don't want.

Running tmux + bash on OS X 10.9 with this in my ~/.profile:

PATH=`echo $PATH | tr ':' '\n' | sort | uniq | tr '\n' ':'`

via http://linuxg.net/oneliners-for-removing-the-duplicates-in-your-path/

@mislav
Copy link
Member

mislav commented Jan 13, 2014

@audionerd I would not advise using this method, since it uses sort and therefore arranges items in your PATH alphabetically, which is never what I want (I want manual control of ordering of items in my PATH)

@audionerd
Copy link
Contributor

@mislav Thanks, good point.

I think I found a fix that works now. I'm running bash, and I wanted a solution that worked only for my current user (no messing with /etc/profile), so I ended up with a ~/.bash_profile which looks like this:

if [ -f /etc/profile ]; then
    PATH=""
    source /etc/profile
fi
. ~/.profile
. ~/.bashrc

Now my $PATH is the same with or without tmux.

via http://superuser.com/a/583502

@iphenom
Copy link

iphenom commented Jan 23, 2014

Override path_helper by calling it again. The PATH is cleared first and then rebuilt. The result is far less duplication of directories. rbenv is also setup here. /etc/zshenv:

# Mac OS X uses path_helper to preload PATH, clear it out first
if [ -x /usr/libexec/path_helper ]; then
    PATH=''
    eval `/usr/libexec/path_helper -s`
fi

# if rbenv is present, configure it for use
if which rbenv &> /dev/null; then
    # Put the rbenv entry at the front of the line
    export PATH="$HOME/.rbenv/bin:$PATH"

    # enable shims and auto-completion
    eval "$(rbenv init -)"
fi

@andyatkinson
Copy link

@audionerd @serta Thanks for the explanations. I am using the example from @serta above with tmux and rbenv and things are working as expected. P.S. Hi Eric! :)

vnavarro added a commit to vnavarro/oh-my-zsh that referenced this issue Jan 29, 2014
ericboehs added a commit to ericboehs/dotfiles that referenced this issue Jan 29, 2014
djtal added a commit to djtal/dotfiles that referenced this issue Jan 31, 2014
see [This issue on rbenv](rbenv/rbenv#369) for more information
@janko
Copy link

janko commented Feb 16, 2014

I'm really having problems with this. I can't use your consolidate-path script, because I'm not using zsh.

Why does Rbenv not add the .rbenv/shims/ directory to the $PATH if it already exists? If it did, then everything would be duplicated, and everything would be fine. This way only .rbenv/shims/ isn't duplicated, and then shell gets to system Ruby.

@mislav
Copy link
Member

mislav commented Feb 16, 2014

Your problem is not rbenv. Your problem is other parts of the system (that includes user scripts) reordering and duplicating PATH entries in a way it breaks your environment.

consolidate-path is a unix executable which can be invoked from bash, zsh, ksh, fish, Ruby, Python, or any other program or shell, as long as you have zsh installed somewhere on the system. You don't actually have to run zsh as your interactive shell.

@janko
Copy link

janko commented Feb 17, 2014

I already went with @markprzepiora's solution. But thanks for the info, I didn't know that I can run it anyways.

Other parts of system don't reorder my PATH entries, they just duplicate them. But what is the bright side of rbenv not duplicating its shims? Why is it in the code base?

@mislav
Copy link
Member

mislav commented Feb 17, 2014

rbenv doesn't duplicate the shims directory since it goes against the practice of duplicating PATH entries, in case shims is already in PATH. Crazy as it may sound, rbenv actually doesn't believe that the way to fight the duplication problem is with more duplication.

@reicheltd
Copy link

Hi all. Ive had duplicate path entries for quite some time now. Running OSX 10.7, zsh, rbenv, tmux. I've tried solutions from some comments here and the only solution that worked for me was putting this inside .zprofile.

# ~/.zprofile
if [ -f /etc/profile ]; then
    PATH=""
    source /etc/profile
fi

Whereas /etc/profile I've never touched. The contents are:

if [ -x /usr/libexec/path_helper ]; then
        eval `/usr/libexec/path_helper -s`
fi

if [ "${BASH-no}" != "no" ]; then
        [ -r /etc/bashrc ] && . /etc/bashrc
fi

larrylv added a commit to larrylv/dotfiles that referenced this issue Mar 17, 2014
mikeastock added a commit to mikeastock/dotfiles that referenced this issue Apr 28, 2014
@jottr
Copy link

jottr commented May 20, 2014

I too simply can't get this to work.

I've tried @mislav's solution using his consolidate-path script and then having these two exports at the end of my .zshenv:

export PATH
export PATH="$(consolidate-path)"

which results in the terminal session freezing upon sourcing (I can force cancel whatever sourcing process is happening by sending ctrl-c). This happens when spawning a new terminal or when launching tmux.

Was anybody on linux using zsh able to solve this?



tmux -V
tmux 1.8
tmux show environment -g 

RBENV_DIR=/home/jottr
RBENV_HOOK_PATH=:/home/jottr/.rbenv/rbenv.d:/usr/local/etc/rbenv.d:/etc/rbenv.d:/usr/lib/rbenv/hooks:/home/jottr/.rbenv/plugins/rbenv-binstubs/etc/rbenv.d:/home/jottr/.rbenv/plugins/rbenv-gem-rehash/etc/rbenv.d
RBENV_ROOT=/home/jottr/.rbenv
RBENV_SHELL=zsh
RBENV_VERSION=1.9.3-p484

@fernandes
Copy link

running consolidate path got this error everytime was opening my terminal:

/etc/zshenv:3: fork failed: resource temporarily unavailable
/Users/fernandes/.zshenv:89: fork failed: resource temporarily unavailable

maybe its a zsh config or something like that, but solved putting @mislav consolidate-path inline on my ~/.zshenv

export PATH
typeset -a paths result
paths=($path)

while [[ ${#paths} -gt 0 ]]; do
  p="${paths[1]}"
  shift paths
  [[ -z ${paths[(r)$p]} ]] && result+="$p"
done

export PATH=${(j+:+)result}

if someone knows the fix for resource temporarily unavailable please tell, if someone has the same problem, this workaround worked

thank you guys, thanks @mislav for the solution

croaky pushed a commit to thoughtbot/dotfiles that referenced this issue Sep 30, 2014
On Mac OS X, there is a bug where `/etc/zshenv`'s `path_helper`
forces `/usr/bin` to the front of the `$PATH`:

rbenv/rbenv#369

    # system-wide environment settings for zsh(1)
    if [ -x /usr/libexec/path_helper ]; then
      eval `/usr/libexec/path_helper -s`
    fi

This breaks rbenv by always using the system Ruby.

We have fixed this in the past in our Laptop script
by moving `/etc/zshenv` to `/etc/zprofile`:

thoughtbot/laptop@c64806e

And more recently, to `/etc/zshrc`:

https://github.com/thoughtbot/laptop/blame/master/mac

On Yosemite with the version of thoughtbot/dotfiles before this commit,
with rbenv being initialized in `~/.zshenv`,
the problem returned.

Moving rbenv initialization back to `~/.zshrc` fixed the problem.

The official documentation for rbenv also recommends initializing in `~/.zshrc`.

https://github.com/sstephenson/rbenv#basic-github-checkout

It also recommends:

    export PATH="$HOME/.rbenv/bin:$PATH"
croaky pushed a commit to thoughtbot/dotfiles that referenced this issue Oct 1, 2014
On Mac OS X, there is a bug where `/etc/zshenv`'s `path_helper`
forces `/usr/bin` to the front of the `$PATH`:

rbenv/rbenv#369

    # system-wide environment settings for zsh(1)
    if [ -x /usr/libexec/path_helper ]; then
      eval `/usr/libexec/path_helper -s`
    fi

This breaks rbenv by always using the system Ruby.

We have fixed this in the past in our Laptop script
by moving `/etc/zshenv` to `/etc/zprofile`:

thoughtbot/laptop@c64806e

And more recently, to `/etc/zshrc`:

https://github.com/thoughtbot/laptop/blame/master/mac

On Yosemite with the version of thoughtbot/dotfiles before this commit,
with rbenv being initialized in `~/.zshenv`,
the problem returned.

Moving rbenv initialization back to `~/.zshrc` fixed the problem.

The official documentation for rbenv also recommends initializing in `~/.zshrc`.

https://github.com/sstephenson/rbenv#basic-github-checkout

It also recommends:

    export PATH="$HOME/.rbenv/bin:$PATH"
@mislav mislav closed this as completed in e2173df Oct 15, 2014
blueyed added a commit to blueyed/rbenv that referenced this issue Apr 19, 2015
Commit e2173df (for issue rbenv#369) did not handle the fish test properly.

This renames it and fixes the assertion.
dawaa added a commit to dawaa/dotfiles that referenced this issue Apr 22, 2021
I noticed my `PATH` had duplicated entries in it. With help from a
GitHub issue[1] and a comment[2] linking to another comment at
StackOverflow[3] I understand the reason behind this duplication and it
also provided me with a solution.

[1]: rbenv/rbenv#369
[2]: rbenv/rbenv#369 (comment)
[3]: https://superuser.com/questions/544989/does-tmux-sort-the-path-variable/583502#583502
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests