4

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?

Mark Ryan
  • 155
  • 1
  • 1
  • 8

2 Answers2

2

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 -)"
Pawel Kam
  • 1,684
  • 3
  • 14
  • 30
  • I'll check out these suggestions soon. Thank you both for detailed answers. I'll update if it all works. – Mark Ryan Jun 16 '23 at 18:34
  • Each WSL instance can be configured to exclude Windows PATH variable by editing /etc/wsl.conf in the WSL instance. See this answer https://stackoverflow.com/a/51345880/30911 – pufferfish Jul 26 '23 at 13:51
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"

Saxtheowl
  • 4,136
  • 5
  • 23
  • 32
  • 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. – Kristoff May 22 '23 at 08:59