How To pyenv (And Fix Some Bug) - Fri, Jan 21, 2022
Usually, up-to-date software is exactly where you want to be, but sometimes you just have a mighty need, by which I mean your employer-approved hacking-activities require you to run some 8 year old exploit and you desperately need legacy-Python. Just your average workday, you know.
Even if Python 2.X (aka legacy-Python) is still on your system, there is a high chance, they discontinued pip2 and for a good reason. Pip is always to be handled carefully, because it installs things on your system and if software like that is outdated, you really want to pay attention to where you put it. Luckily there is a solution for that: Pyenv! Pyenv can create one or more environments where normal rules (meaning: your system cofigurations) for Python are ignored in favor of a more creative, more free world.
Simply speaking: With pyenv you can declare a directory (and all its sub-dirs) a zone of a different Python. That is very handy for our initial goal. You want to use legacy-Python, but certainly not always - just for one project contained in one directory.
Pyenv makes this possible with a setup of environment variables and juggling different Python-versions that is far beyond my understanding, but the result is pretty neat. Now if you are looking to set it up, there are many good blog-posts on how to do that. I was running a current version of Kali (aka Debian Bullseye with some fancy) and hence adhered to this here tutorial. This tutorial is a good place to go, but if you encounter issues with actually using the intended Python version, come back here.
Oh look, you’re back. Not everyone can be as lucky as my coworker for whom it just worked.
Let me tell you my issues, so you know what’s up. Here’s my pain:
kali@kali:$ pyenv local
pyenv: no local version configured for this directory
If this accurately describes your situation, you might want to look at your PATH. If you are new to Linux (welcome!), have a very quick rundown of PATH:
Quick Intro to PATH
If you enter the name of a program into your command line, it just magically starts that program. Probably that’s not even magic to you, but try this: Write your own littel program, something really simple, like this:
#!/bin/bash
echo "What a beautiful day!"
Now save that as positive.sh
, execute chmod +x positive.sh
(that makes it executable and not just a bunch of text) and you can execute it by typing ./positive.sh
into your command line. Unless you change the directory, then you can’t. It has to be in the directory you are in, otherwise it won’t work. Alternatively you can always type out the full path where the file sits. In my case that would be /home/shark/positive.sh
. You can also type /usr/bin/whoami
and it will execute whoami. But why is just whoami
enough to do the same?
That’s the magic. That’s PATH. The environment variable $PATH tells your system a few places where to look when looking for executables. If I look at mine, it looks like this:
shark@tornado:~$ echo $PATH
/home/shark/.cargo/bin:/home/shark/bin:/home/shark/.cargo/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
This includes /usr/bin
, which is where whoami sits. Your OS scans all contents of PATH for an aptly named executable when you type a random word into the command line. You can move your positive.sh to /usr/local/bin
and give it a try. Now you can execute it from anywhere.
On With The Problem
Now that you know about PATH, back to the problem at hand: My system didn’t find anything named python
. Bad sign. It usually doesn’t, because there is python2 and python3, but in the pyenv it should. Pyenv sets python
to whatever Python-version you installed in the current virutal environment and I had set my current virtualenv to Python 2.7 and was in the correct directory, but still
kali@kali:$ pyenv local
pyenv: no local version configured for this directory
The answer, as I suggested earlier, was in PATH. If you look at the linked tutorial, they tell your to set the variable PYENV_ROOT to the .pyenv-directory in your home dir. Then they tell you to include the bin-directory in that PYENV_ROOT into your PATH. All of this is written to .zshrc to load it into PATH every time you start a new terminal session. Here is what they quote as commands to copy:
kali@kali:~$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
kali@kali:~$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
kali@kali:~$ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.zshrc
The last line initiates the virtual environment as needed. If you use bash, echo all these things to .bashrc instead of .zshrc. Anyway, the real issue is, if you go to .pyenv in your home and look for the actual Python-binaries and pip-binaries and all, you will find them in /shims
and this is right where the project intends them to be. But ./shims
is not ./bin
and also is not inside there. So that’s all the deal that took me several hours to find out. Just add PYENV_ROOT/shims
to PATH (in your .zshrc or .bashrc of course), and you’re good to go!
Why did it work for my coworker with that very same tutorial? I don’t know. Maybe she added all of PYENV_ROOT to her PATH, maybe she put the entire project into /home/[user]/bin
or something. Anyway, that was my issue, and if it’s yours too, you’re welcome!
Alright then, catch you later!