Installing pyenv-win on top of working wsl2 Ubuntu instance breaks Ubuntu pyenv
Asked Answered
H

4

12

I've been using pyenv for the past year in my ubuntu 22.04 under wsl2. It works fine, and I have no issues with installing python versions and setting them up for a project. I now have a windows app project I want to work on while in Windows (it's a GUI app). I found pyenv-win and when I install it, it breaks my wsl2 installation. When it starts, I get the following error:

-bash: /mnt/c/Users/mryan/.pyenv/pyenv-win/bin/pyenv: /bin/sh^M: bad interpreter: No such file or directory

So mryan is my windows user name. My ubuntu user name is dev.

I've also messed up my ubuntu install so what I'm going to do after submitting this question is restore my windows system back to yesterday before I started this process. I'll then start from scratch on getting windows pyenv-win going.

Has anyone else gone through this? Do you know the proper way to get this all going? Should I uninstall pyenv from ubuntu, install it in windows, and then re-install it in ubuntu? I get the feeling this is a path issue where windows and ubuntu is overlapping?

Heated answered 30/3, 2023 at 0:20 Comment(0)
P
17

The issue

I had the same problem, having both pyenv-win and pyenv in Windows+WSL setup can cause conflict in your environment variables.

That’s because WSL appends Windows PATH to Linux $PATH variable. As a result, whenever you type pyenv in your WSL terminal, the system looks in $PATH variable, which references pyenv-win instead of pyenv. It tries to read /mnt/c/Users/<username>/.pyenv/pyenv-win/bin/pyenv and it just can’t. Even if you make the OS to read it with sed -i -e 's/\r$//' /mnt/c/Users/<username>/.pyenv/pyenv-win/bin/pyenv command, you will get other problems, because pyenv-win was build for Windows.

The solution

Instead of uninstalling anything, let us just make sure that Windows points to pyenv-win and WSL to pyenv. After making sure that you have both properly installed, just replace WSL paths to pyenv-win executables in WSL $PATH with paths to pyenv executables.

Where to do this may depend on your system. Please read the documentation on how to set this correctly. In Ubuntu the default shell is probably bash with startup configuration in ~/.bashrc, ~/.profile, and/or ~/.bash_profile.

In short, just add the following to the ~/.bashrc, ~/.profile, and/or ~/.bash_profile files:

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

Note that contrary to the documentation, we have changed the command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH". That’s because in WSL with pyenv-win installed the first condition will return true, and your PATH will never be updated.

If you don’t like your $PATH variable to have redundant paths, instead of adding $PYENV_ROOT at the beginning of $PATH, you can simply replace paths to pyenv-win with paths to pyenv in $PATH variable with the sed command. For example, instead of the above script, you can enter the following snippet:

export PYENV_ROOT="$HOME/.pyenv"
BIN_OLD="/mnt/c/Users/<username>/.pyenv/pyenv-win/bin"
BIN_NEW="$PYENV_ROOT/bin"
SHIMS_OLD="/mnt/c/Users/<username>/.pyenv/pyenv-win/shims"
SHIMS_NEW="$PYENV_ROOT/shims"
export PATH=`echo $PATH | sed "s@$BIN_OLD@$BIN_NEW@" | sed "s@$SHIMS_OLD@$SHIMS_NEW@"`
eval "$(pyenv init -)"
Parachute answered 15/6, 2023 at 16:52 Comment(2)
I'll check out these suggestions soon. Thank you both for detailed answers. I'll update if it all works.Heated
Each WSL instance can be configured to exclude Windows PATH variable by editing /etc/wsl.conf in the WSL instance. See this answer https://mcmap.net/q/239332/-how-to-remove-the-win10-39-s-path-from-wslSheikh
C
1

Your problem come from Windows pyenv installation interfering with the WSL2 Ubuntu pyenv installation, to solve this follow these step:

First uninstall pyenv from both Windows and WSL2 Ubuntu environments then install it (pyenv) on WSL2 https://github.com/pyenv/pyenv#installation then pyenv-win on Windows then after update the Windows PATH variable to remove the references to pyenv-win. Go to "Environment Variables" then on "System Variables", find the variable named Path. Edit it and remove any entries related to pyenv-win then create a new Windows user environment variable called PYENV_WIN and set it to C:\Users\mryan\.pyenv\pyenv-win

Now when you need to use pyenv-win in the Windows command prompt or PowerShell do this: set PATH=%PYENV_WIN%\bin;%PYENV_WIN%\shims;%PATH%

and for PowerShell: $env:Path = "$env:PYENV_WIN\bin;$env:PYENV_WIN\shims;$env:Path"

Code answered 31/3, 2023 at 2:53 Comment(1)
I can confirm that this worked in my case. However I did not uninstall pyenv-win, just removed the pyenv-win references from Window's PATH. For WSL I have reinstalled pyenv.Rotow
M
0

If you are in a hurry and you don't want to remove anything, then update your .bashrc file in wsl like this, append it at the end:

export PATH=$(echo "$PATH" | sed -E 's#([^:]+pyenv-win[^:]+)##g; s#:+#:#g; s#:?$#:#')

It might not be elegant but it solves the issue by removing any path entry related to pyenv-win.

Moralize answered 30/4 at 13:27 Comment(0)
S
0

I fixed this by removing the windows path in my bashrc file like this

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
export PATH=$(echo "$PATH" | tr ':' '\n' | grep -v "/mnt/c/Users/username/.pyenv" | tr '\n' ':' | sed 's/:$//')
eval "$(pyenv init -)"
Scyros answered 27/8 at 14:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.