skip to Main Content

I suppose there is something wrong with my bash init scripts (like .bashrc or .bash_profile). But let’s start from beginning.

I can create and activate pyenv environment, but when I try to use python, I get error: -bash: python: command not found.
It looks like pyenv understands creation and swapping envorinments. I mean, it’s probably not malformed. There is preview of my tries:

$ mkdir test-python-project
$ cd test-python-project/
$ pyenv versions
* system (set by /home/vagrant/.pyenv/version)
  3.7.10
  3.7.10/envs/k-pkb-env
$ pyenv virtualenv 3.7.10 test-env
Looking in links: /tmp/tmpkwojcc1e
Requirement already satisfied: setuptools in /home/vagrant/.pyenv/versions/3.7.10/envs/test-env/lib/python3.7/site-packages (47.1.0)
Requirement already satisfied: pip in /home/vagrant/.pyenv/versions/3.7.10/envs/test-env/lib/python3.7/site-packages (20.1.1)
$ pyenv activate test-env
pyenv-virtualenv: prompt changing will be removed from future release. configure export PYENV_VIRTUALENV_DISABLE_PROMPT=1 to simulate the behavior.
(test-env) $ python
-bash: python: command not found
(test-env) $ pyenv local test-env
(test-env) $ cd ..
(test-env) $ pyenv deactivate
$ cd test-python-project/
(test-env) $ python
-bash: python: command not found
(test-env) $ pip
-bash: pip: command not found
(test-env) $ pyenv version
test-env (set by /home/vagrant/Work/test-python-project/.python-version)

I’m not sure how to configure bash init scripts, because in pyenv readme they suggest using .profile, which I don’t have.

So, there are my bash inits:

.bashrc

$ cat .bashrc
# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

# User specific environment
if ! [[ "$PATH" =~ "$HOME/.local/bin:$HOME/bin:" ]]
then
    PATH="$HOME/.local/bin:$HOME/bin:$PATH"
fi
export PATH

# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=

# User specific aliases and functions

.bash_profile

$ cat .bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

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

Some additional information:

$PATH variable

$ echo $PATH
/home/vagrant/.pyenv/plugins/pyenv-virtualenv/shims:/home/vagrant/.pyenv/bin:/home/vagrant/.local/bin:/home/vagrant/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin

It’s a bit strange for me, because this additional paths added by pyenv doesn’t seem to contain path to desired virtual environment:

$ ls /home/vagrant/.pyenv/plugins/pyenv-virtualenv/shims
activate  deactivate
$ ls /home/vagrant/.pyenv/bin
pyenv

type python

$ type python
-bash: type: python: not found

which python

$ which python
/usr/bin/which: no python in (/home/vagrant/.pyenv/plugins/pyenv-virtualenv/shims:/home/vagrant/.pyenv/bin:/home/vagrant/.local/bin:/home/vagrant/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin)

I tried also pyenv rehash, but also still no effect:

(test-env) [vagrant@centos test-python-project]$ pyenv rehash
(test-env) [vagrant@centos test-python-project]$ python
-bash: python: command not found

2

Answers


  1. Chosen as BEST ANSWER

    With some help from @Simba, I managed to have my configuration correct:

    .bash_profile

    # .bash_profile
    
    # !!! ITS IMPORTANT THESE LINES MUST BE BEFORE . ~/.bashrc
    # PyEnv - only path-related
    export PYENV_ROOT="$HOME/.pyenv"
    export PATH="$PYENV_ROOT/bin:$PATH"
    # !!! ITS IMPORTANT THESE LINES ABOVE MUST BE BEFORE . ~/.bashrc
    
    
    
    # Get the aliases and functions
    if [ -f ~/.bashrc ]; then
            . ~/.bashrc
    fi
    
    # User specific environment and startup programs
    

    .bashrc

    # .bashrc
    
    # Source global definitions
    if [ -f /etc/bashrc ]; then
            . /etc/bashrc
    fi
    
    # User specific environment
    if ! [[ "$PATH" =~ "$HOME/.local/bin:$HOME/bin:" ]]
    then
        PATH="$HOME/.local/bin:$HOME/bin:$PATH"
    fi
    export PATH
    
    # Uncomment the following line if you don't like systemctl's auto-paging feature:
    # export SYSTEMD_PAGER=
    
    # User specific aliases and functions
    
    # PyEnv - commands
    eval "$(pyenv init -)"
    eval "$(pyenv virtualenv-init -)"
    

  2. Solution

    READ THE PYENV GUIDE CAREFULLY.

    You didn’t follow pyenv’s README guide correctly. The guide tells you put PATH related operation in .bash_profile or .profile. But eval "$(pyenv init -)" in .bashrc.

    Move pyenv init script from .bash_profile to .bashrc.

    # Put it in .bashrc
    
    # PyEnv
    eval "$(pyenv init -)"
    eval "$(pyenv virtualenv-init -)"
    

    Extended Reading

    You bash shell is not a login shell. .bash_profile is not sourced at all, which skip pyenv init -.

    Bash initialization

    1. login mode:
      1. /etc/profile
      2. ~/.bash_profile, ~/.bash_login, ~/.profile (only the first one that exists)
    2. interactive non-login:
      1. /etc/bash.bashrc (some Linux; not on Mac OS X)
      2. ~/.bashrc
    3. non-interactive:
      1. source file in $BASH_ENV

    The default shell on Linux is a non-login, interactive shell. The default shell on macOS is a login, interactive shell.

    There’s also a detailed explanation about the shell startup by flowblok

    Ref

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search