I know this question is from a while ago, but I stumbled upon the same problem, and here's the approach that I took.
To make sure we're on the same page...
Initially, I had (and I assume you do too) both python
and python3
pointing to system's Python:
$ pyenv versions
* system (set by /home/nigorojr/.pyenv/version)
3.7.4
$ python --version && pyenv which python
Python 2.7.12
/usr/bin/python
$ python3 --version && pyenv which python3
Python 3.5.2
/usr/bin/python3
However, this is what I wanted:
$ python --version && pyenv which python
Python 2.7.12
/usr/bin/python
$ python3 --version && pyenv which python3
Python 3.7.4
/home/nigorojr/.pyenv/versions/3.7.4/bin/python3
Approach
The approach I took is similar to @Kapitol's second suggestion. However, I created a shell script instead of an alias because I wanted other commands (including pyenv
) to be able to find my new python3
command.
I created ~/bin/python3
(with ~/bin
in my $PATH
variable) with the following content:
#!/bin/sh
# PYENV_VERSION="$( pyenv versions | tr -d ' ' | awk '/^3\./ { print $1 }' | tail -n 1 )" pyenv exec python3 $@
# Or simply,
PYENV_VERSION="3.7.4" pyenv exec python3 $@
With this shell script, I get:
$ python --version && pyenv which python
Python 2.7.12
/usr/bin/python
$ python3 --version && pyenv which python3
Python 3.7.4
/home/nigorojr/bin/python3
Note 1: Using exec python3 $@
instead of pyenv exec python3 $@
in the shell script does not work because it becomes an infinite recursive call to the script itself (depending on $PATH
). Using pyenv exec
ensures that the pyenv
Python gets called no matter how the $PATH
variable is ordered.
Note 2: Having all the pipes to get the latest version managed by pyenv
does slow down the startup when calling python3
. Thus, I would recommend simply setting your desired Python version in PYENV_VERSION
if you have a particular version you want to use.
Note 3: Be aware that pip3
and other commands will not be found with this approach. One solution is to create a shell script for each command that you use. Another solution is to run pyenv global system 3.7.4
so that pyenv
can search in 3.7.4 if the command is not installed in the system.
Checking that it works
To make sure that everything is working as expected, I wrote the following Python script:
#!/usr/bin/env python
import sys
print(sys.version)
and ran:
$ ./sample.py
2.7.12 (default, Oct 8 2019, 14:14:10)
[GCC 5.4.0 20160609]
$ python ./sample.py
2.7.12 (default, Oct 8 2019, 14:14:10)
[GCC 5.4.0 20160609]
$ python3 ./sample.py
3.7.4 (default, Sep 16 2019, 16:09:11)
[GCC 5.4.0 20160609]
Changing the first line to #!/usr/bin/env python3
, I got:
$ ./sample.py
3.7.4 (default, Sep 16 2019, 16:09:11)
[GCC 5.4.0 20160609]
$ python ./sample.py
2.7.12 (default, Oct 8 2019, 14:14:10)
[GCC 5.4.0 20160609]
$ python3 ./sample.py
3.7.4 (default, Sep 16 2019, 16:09:11)
[GCC 5.4.0 20160609]
To conclude, with the abovementioned approach, you can have python
point to system's Python 2 while having python3
point to the version installed with pyenv
.