What's "which pyenv > /dev/null" mean? - bash

Everyone write if which pyenv > /dev/null; then eval "$(pyenv init -)"; fi into .bashrc etc after installation of pyenv.
I know if I didn't excute eval "$(pyenv init -)", python's version would not change.
Why do I need to write if which pyenv > /dev/null?
What's it mean? What would happen without it?
Thanks.

It is used to check if pyenv is found, but suppress the output of the which command.
Without it, the output of which would print to the console, every time .bashrc is sourced.

Related

How to set path correctly from RBENV shims on Mac M1 with zsh

I'm having trouble setting up the rbenv paths
I follow the instructions as specified here: rbenv installation page
I run the command on a zsh terminal:
rbenv init
The terminal gives me the instruction to run
eval "$(rbenv init - zsh)"
I then close the restart the terminal and check to see if all is configured correctly by running:
curl -fsSL https://github.com/rbenv/rbenv-installer/raw/main/bin/rbenv-doctor | bash
and I get the following failure:
Checking for rbenv shims in PATH: not found
If I try open the fils .zshrc I find only the following path written to it
export PATH="/opt/homebrew/opt/libpq/bin:$PATH"
but no shims. Can I add the shims manually? I don't know what it should look like? Or is there any reason the command eval "$(rbenv init - zsh)" is not working properly?
Got it working: I need to run echo 'eval "$(rbenv init -)"' >> ~/.zshrc

pyenv initialization in .bash_profile vs. .bashrc (after release 2.0.0)

With the recent release of pyenv 2.0.0, the documentation currently recommends the following configuration for a bash shell:
# inside ~/.bash_profile
eval "$(pyenv init --path)"
# inside ~/.bashrc
eval "$(pyenv init -)"
If I'm not allowed to edit .bashrc on my system (for reasons completely unrelated to pyenv), what would be the drawbacks of just putting both inside my profile, like this:
# inside ~/.bash_profile
eval "$(pyenv init --path)"
eval "$(pyenv init -)"
I've been using it like this for a few hours, and I haven't noticed any issues (on MacOS, with a Homebrew installation of pyenv, and Python 3.6/3.7/3.8 virtual environments created with venv). I'm trying to understand what might be the drawbacks of configuring my system this way, and why the documentation makes such a big deal about using both .bash_profile and .bashrc.
Will configuring pyenv in this way cause problems for me in the future?
Bash only runs ~/.bash_profile when you start a login shell. When you start a new shell by typing bash or exec bash, its runs only ~/.bashrc. However, you can work around this easily by always starting new shells with bash -l or exec bash -l, which will make the new shell a login shell.
To find out whether it makes a difference whether you don't run eval "$(pyenv init -)" in non-login shells, let's have a look at what pyenv init - really does:
$ pyenv init -
export PYENV_SHELL=bash
source '/usr/local/Cellar/pyenv/2.0.0/libexec/../completions/pyenv.bash'
command pyenv rehash 2>/dev/null
pyenv() {
local command
command="${1:-}"
if [ "$#" -gt 0 ]; then
shift
fi
case "$command" in
rehash|shell)
eval "$(pyenv "sh-$command" "$#")"
;;
*)
command pyenv "$command" "$#"
;;
esac
}
Since export PYENV_SHELL=bash puts $PYENV_SHELL into the environment, it will get imported for your non-login shells, too. So, that doesn't make any difference.
As for the rest, it looks like the main thing you're missing out on is command line completion for pyenv. Other than that, there's just some special wrapping for pyenv shell and pyenv rehash.
So, as long as you don't use tab completion for pyenv nor use the commands pyenv shell and pyenv rehash in your non-login shells, then it should make no difference. But even if you do want to use those there, you can simply start the shell with bash -l or just run eval "$(pyenv init -)" manually.

pyenv: failed to activate virtualenv - settings not read from .profile at login

This is a known topic, almost similar to this one.
However - why am I having the pyenv settings passed in ok from .profile at login only up to the virtualenv string.
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
if command -v pyenv 1>/dev/null 2>&1; then
eval "$(pyenv init -)"
fi
eval "$(pyenv virtualenv-init -)"
After login, the above portion is read (pyenv is active in terminal) but not virtualenv. Manual activation of the venv produces the well-known error message.
$pyenv activate venv_name
Failed to activate virtualenv.
Perhaps pyenv-virtualenv has not been loaded into your shell properly.
Please restart current shell and try again.
I can solve this by explicitly sourcing .profile - then it works fine.
But why would .profile not be read or interpreted at once at login?
Modifying .bashrc takes no effect. Seems like it's not being read. But .profile is.
Global python is system (2.7).
Take care
Try pyenv init --path instead of pyenv init - and again putting it in bashrc.

Restrict ansible features to an older version?

In my work environment I have already upgraded to a newer ansible version than what co-workers have. By accident I keep using features that their version does not have yet.
Is there a way to prevent this on my side in that I force ansible to pretend it is actually an older version?
You can use python virtual environments to handle multiple ansible versions. I use pyenv to manage virtualenvs. Here is how you can do it in bash on Linux:
Install pyenv:
You can change paths according to your liking if you don't want default paths.
git clone https://github.com/pyenv/pyenv.git ${HOME}/.pyenv
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ${HOME}/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ${HOME}/.bashrc
echo 'if command -v pyenv 1>/dev/null 2>&1; then eval "$(pyenv init -)"; fi' >> ${HOME}/.bashrc
Install pyenv virtualenv for user:
git clone https://github.com/pyenv/pyenv-virtualenv.git ${HOME}/.pyenv/plugins/pyenv-virtualenv
echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
export PYENV_VIRTUALENV_DISABLE_PROMPT=1
Initialize pyenv environment for current shell
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
Install older ansible in one virtualenv:
pyenv virtualenv old_env
pyenv activate old_env
pip install ansible==2.4
Install newer ansible in other virtualenv:
pyenv virtualenv new_env
pyenv activate new_env
pip install ansible==2.7
Daily Usage:
You can switch between virtualenvs whenver you want. e.g. to switch to old ansible virtualenv and check ansible version, you can do like this:
pyenv activate old_env
ansible --version

Failed to activate virtualenv via shellscript

I'm trying to activate my pyenv-virtualenv environment through very simple bash script like this.
set -e
pyenv activate myenv
But I can't activate my env with below error:
Failed to activate virtualenv.
Perhaps pyenv-virtualenv has not been loaded into your shell properly.
Please restart current shell and try again.
I can activate it in command line, so I think it's due to my shell environment.
I use fish shell, but it's launched after $PATH settings read in bash shell.
I show you my settings.
.bash_profile:
export LANG="ja_JP.UTF-8"
export XDG_CONFIG_HOME="$HOME/.config"
export PATH="/sbin"
export PATH="/usr/sbin:$PATH"
export PATH="/bin:$PATH"
export PATH="/usr/bin:$PATH"
export PATH="/usr/local/bin:$PATH"
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
exec fish
And my config.fish:
status --is-interactive; and source (pyenv init -|psub)
status --is-interactive; and source (pyenv virtualenv-init -|psub)
What's wrong?
I'm using:
OS: OS X 10.13.5
fish: v2.7.1
pyenv: v1.2.5
pyenv-virtualenv: v1.1.3
I believe the cause is that you are initializing PyEnv in the Fish shell environment but then calling PyEnv in the Bash shell environment (via your Bash script). To solve this problem, you could try either of the following potential solutions:
Initialize PyEnv in your Bash environment (in addition to your Fish environment)
Write your script in Fish instead of Bash
Since PyEnv seems so have better support for Bash than Fish, let's focus on option #1. Step 3 of the PyEnv installation guide suggests the following command for adding PyEnv initialization to your ~/.bash_profile:
$ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.bash_profile
After running that command, I suspect your script will function as you expect. If it does not, you could try adding the same PyEnv initialization snippet (that you just added to your ~/.bash_profile) to the top of your Bash script.

Resources