I am using a Catalina macOS. I previously was able to work with my python installations with ease on this system. But today after updating other packages, such as wget and julia, I have encountered these errors zsh: command not found: python3.8 on my terminal. Following suggestions on these links I have tried to modify the PATH and zshrc but none of these approaches enables me to solve my problem.
I would be grateful if you can share your suggestions on how to deal with this issue.
Here are some of the outputs of my system.
zshrc:
vi ~/.zshrc
alias python=/usr/local/bin/python3.8
# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/Users/shasa/anaconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
eval "$__conda_setup"
else
if [ -f "/Users/shasa/anaconda3/etc/profile.d/conda.sh" ]; then
. "/Users/shasa/anaconda3/etc/profile.d/conda.sh"
else
export PATH="/Users/shasa/anaconda3/bin:$PATH"
fi
fi
unset __conda_setup
# <<< conda initialize <<<
python:
which python
python: aliased to /usr/local/bin/python3.8
PATH:
echo $PATH
/Users/shasa/anaconda3/bin:/Users/shasa/anaconda3/condabin:/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/TeX/texbin:/opt/X11/bin:/Library/Apple/usr/bin
Edit 1: In /usr/local/bin/, I can see that python3#, python3.9# and python3.8#* are present. Do you think the extra * near python3.8# can cause this problem? If yes, how can resolve that?
Following the discussion in the comments, I have found the source of the problem. I run brew doctor and indeed found out that the python3.8 symlinks were broken. I have then removed broken symlinks by brew cleanup and reinstalled that again.
Related
I have a project set up in Pycharm, with an existing conda environment. My scripts work when run from within the console.
I would like to be able to run python -m path_to_my_script/script.py from any location, but I need conda activated. Conda recommends I do conda init but I'm worried it may change settings someplace and break things.
What does conda init do?
Strategy for Answering
Exactly what the conda init command does and its consequences are shell-specific. Instead of trying to cover all cases, let's walk through a case, noting along the way that one can replicate this analysis by substituting their shell of interest.
Case Study: conda init zsh
Let's look at zsh as the shell. This is a common shell (default for macOS 10.15+) and very close to bash. Plus, I don't already have it configured.
Probing the Command: Dry Run
Many Conda commands include some form of dry run functionality via a --dry-run, -d flag, which - combined with verbosity flags - enables seeing what this would do without doing them. For the init command, dry run alone will only tell us what files it would modify:
$ conda init -d zsh
no change /Users/mfansler/miniconda3/condabin/conda
no change /Users/mfansler/miniconda3/bin/conda
no change /Users/mfansler/miniconda3/bin/conda-env
no change /Users/mfansler/miniconda3/bin/activate
no change /Users/mfansler/miniconda3/bin/deactivate
no change /Users/mfansler/miniconda3/etc/profile.d/conda.sh
no change /Users/mfansler/miniconda3/etc/fish/conf.d/conda.fish
no change /Users/mfansler/miniconda3/shell/condabin/Conda.psm1
no change /Users/mfansler/miniconda3/shell/condabin/conda-hook.ps1
no change /Users/mfansler/miniconda3/lib/python3.7/site-packages/xontrib/conda.xsh
no change /Users/mfansler/miniconda3/etc/profile.d/conda.csh
modified /Users/mfansler/.zshrc
==> For changes to take effect, close and re-open your current shell. <==
Here we can see that it plans to target the user-level resources file for zsh, /Users/mfansler/.zshrc, but it doesn't tell us how it will modified it. Also, OMG! the UX here is awful, because it in no way reflects the fact that I used the -d flag. But don't worry: as long as the -d flag is there it won't actually change things.
Patch Preview
To see what exactly it will do, add a single verbosity flag (-v) to the command. This will give everything from the previous output, but will now shows us the diff it will use to patch (update) the .zshrc file.
$ conda init -dv zsh
/Users/mfansler/.zshrc
---
+++
## -0,0 +1,16 ##
+
+# >>> conda initialize >>>
+# !! Contents within this block are managed by 'conda init' !!
+__conda_setup="$('/Users/mfansler/miniconda3/bin/conda' 'shell.zsh' 'hook' 2> /dev/null)"
+if [ $? -eq 0 ]; then
+ eval "$__conda_setup"
+else
+ if [ -f "/Users/mfansler/miniconda3/etc/profile.d/conda.sh" ]; then
+ . "/Users/mfansler/miniconda3/etc/profile.d/conda.sh"
+ else
+ export PATH="/Users/mfansler/miniconda3/bin:$PATH"
+ fi
+fi
+unset __conda_setup
+# <<< conda initialize <<<
+
# ...the rest is exactly as above
That is, the plan of action is to add these 16 lines to the .zshrc file. In this case, I don't have an existing .zshrc file, so it plans to add it at line 1. If the file had already existed, it would append these lines.
Interpreting the Shell Code
Let's overview this code, before focusing on the details. Essentially, this is a redundant sequence of attempts to set up some shell functionality. They are ordered from most to least functional.
What Conda Hopes To Do
The code
__conda_setup="$('/Users/mfansler/miniconda3/bin/conda' 'shell.zsh' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
eval "$__conda_setup"
gets something from conda itself, storing the result to a string, and then evaluates that string if the command had a clean exit ($? -eq 0). The neat engineering here is that the subprocess (technically python -m conda) passes back a result that can be run within this current process (zsh), allowing it to define shell functions.
I'll dig deeper into what is going on here in a second.
Fallback 1: Hardcoded Shell Functions
If that strange internal command fails, the devs included a hardcoded version of some essential shell functions (specifically conda activate). This is in:
miniconda3/etc/profile.d/conda.sh
and they simply check the file exists and source it. Let's hit that last option, then we'll swing back to look at the functionality.
Fallback 2: The Last Resort
The absolute last resort is to literally violate the standing recommendation since Conda v4.4, which is to simply put the base environment's bin directory on PATH. In this case, there is no conda activate functionality; this only ensures that Conda is on your PATH.
Details: Shell Functionality
Coming back to the intended case, we can inspect exactly what it would evaluate by simply getting that string result:
$ conda shell.zsh hook
__add_sys_prefix_to_path() {
# In dev-mode CONDA_EXE is python.exe and on Windows
# it is in a different relative location to condabin.
if [ -n "${_CE_CONDA}" ] && [ -n "${WINDIR+x}" ]; then
SYSP=$(\dirname "${CONDA_EXE}")
else
SYSP=$(\dirname "${CONDA_EXE}")
SYSP=$(\dirname "${SYSP}")
fi
if [ -n "${WINDIR+x}" ]; then
PATH="${SYSP}/bin:${PATH}"
PATH="${SYSP}/Scripts:${PATH}"
PATH="${SYSP}/Library/bin:${PATH}"
PATH="${SYSP}/Library/usr/bin:${PATH}"
PATH="${SYSP}/Library/mingw-w64/bin:${PATH}"
PATH="${SYSP}:${PATH}"
else
PATH="${SYSP}/bin:${PATH}"
fi
\export PATH
}
__conda_exe() (
__add_sys_prefix_to_path
"$CONDA_EXE" $_CE_M $_CE_CONDA "$#"
)
__conda_hashr() {
if [ -n "${ZSH_VERSION:+x}" ]; then
\rehash
elif [ -n "${POSH_VERSION:+x}" ]; then
: # pass
else
\hash -r
fi
}
__conda_activate() {
if [ -n "${CONDA_PS1_BACKUP:+x}" ]; then
# Handle transition from shell activated with conda <= 4.3 to a subsequent activation
# after conda updated to >= 4.4. See issue #6173.
PS1="$CONDA_PS1_BACKUP"
\unset CONDA_PS1_BACKUP
fi
\local ask_conda
ask_conda="$(PS1="${PS1:-}" __conda_exe shell.posix "$#")" || \return
\eval "$ask_conda"
__conda_hashr
}
__conda_reactivate() {
\local ask_conda
ask_conda="$(PS1="${PS1:-}" __conda_exe shell.posix reactivate)" || \return
\eval "$ask_conda"
__conda_hashr
}
conda() {
\local cmd="${1-__missing__}"
case "$cmd" in
activate|deactivate)
__conda_activate "$#"
;;
install|update|upgrade|remove|uninstall)
__conda_exe "$#" || \return
__conda_reactivate
;;
*)
__conda_exe "$#"
;;
esac
}
if [ -z "${CONDA_SHLVL+x}" ]; then
\export CONDA_SHLVL=0
# In dev-mode CONDA_EXE is python.exe and on Windows
# it is in a different relative location to condabin.
if [ -n "${_CE_CONDA:+x}" ] && [ -n "${WINDIR+x}" ]; then
PATH="$(\dirname "$CONDA_EXE")/condabin${PATH:+":${PATH}"}"
else
PATH="$(\dirname "$(\dirname "$CONDA_EXE")")/condabin${PATH:+":${PATH}"}"
fi
\export PATH
# We're not allowing PS1 to be unbound. It must at least be set.
# However, we're not exporting it, which can cause problems when starting a second shell
# via a first shell (i.e. starting zsh from bash).
if [ -z "${PS1+x}" ]; then
PS1=
fi
fi
conda activate base
I'm not going to walk through all this, but the main part is that instead of directly putting bin on PATH, it defines a shell function called conda and this serves as a wrapper for the condabin/conda entrypoint. This also defines a new functionality conda activate, which uses a shell function, __conda_activate(), behind the scenes. At the final step, it then activates the base environment.
Why do it this way?
This is engineered like this in order to be responsive to the configuration settings. Configuration options like auto_activate_base and change_ps1 affect how Conda manipulates the shell, and so that changes what functionality Conda includes in its shell functions.
Does Conda "Pollute the Environment"?
Not really. The main behavioral things like auto-activation and prompt modification can be disabled through configuration settings, so that conda init ultimately just adds the conda activate function to the shell, enabling clean switching between environments without ever having to manually manipulate PATH.
Your caution may be warranted. The conda init command adds Anaconda to the path on Linux or Mac (not recommended on Windows). Anaconda FAQ
You also need to prep for conda init by running source <path to conda>/bin/activate first.
You can run your script in your desired conda environment by specifying the python environment in the shebang statement in the first line of your code.
You can get that value by activating your desired environment and executing which python
(base) -> conda activate py39
(py39) -> which python
/home/user/anaconda3/envs/py39/bin/python
The shebang would be:
#!/home/user/anaconda3/env/py39/bin/python
On Mac and Linux, once you add the shebang you can chmod the file to be executable (e.g. chmod 700 myscript.py) and run from the command line directly. (I'm not a Windows user, so ymmv.)
(base) -> <path-to-script>/myscript.py
(Which now runs in shebang virtual environment instead of base.)
I have a Mac (latest software update) with Pyenv and Anaconda. I manage packages with Homebrew and have installed Python 3 with it. When I echo $PATH I get the following:
/Library/Frameworks/Python.framework/Versions/3.8/bin:
\ /usr/local/bin:
\ /usr/bin:
\ /bin:
\ /usr/local/sbin:
\ /usr/sbin:
\ /sbin:
\ /Library/TeX/texbin:
\ /Users/luca/.pyenv/versions/anaconda3-2020.02/condabin:
\ /Users/luca/.pyenv/versions/3.8.5/bin:
\ /Users/luca/.pyenv/bin
I do not know what sets up /Library/Frameworks/Python.framework/Versions/3.8/bin: this directory is non-existent on my Mac. I had previously installed Python without Homebrew that is why the directory was created. I did remove that, but there is still something that exports that line in $PATH, but I cannot find it! Does someone have a guess? I did try and grep -r /* it, but that is too much of a search for my laptop to finish.
I set up in my .zshenv the code for initialising pyenv and conda. Of course, I did write PATH="/dir/to/conda/bin:$PATH" and the same for pyenv (see code below). I do not understand why, but they end up at the end of $PATH. Does someone know why? Is it because of eval "$(pyenv init -)" being evaluated before conda?
# >>> pyenv initialize
export PYENV_SHELL=$SHELL
export PATH="/Users/luca/.pyenv/bin:$PATH"
export PATH="/Users/luca/.pyenv/versions/3.8.5/bin:$PATH" #export Python 3.8 bin directory
if command -v pyenv 1>/dev/null 2>&1; then
eval "$(pyenv init -)"
fi
# <<< pyenv initialize <<<
# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/Users/luca/.pyenv/versions/anaconda3-2020.02/bin/conda' 'shell.zsh' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
eval "$__conda_setup"
else
if [ -f "/Users/luca/.pyenv/versions/anaconda3-2020.02/etc/profile.d/conda.sh" ]; then
. "/Users/luca/.pyenv/versions/anaconda3-2020.02/etc/profile.d/conda.sh"
else
export PATH="/Users/luca/.pyenv/versions/anaconda3-2020.02/bin:$PATH"
fi
fi
unset __conda_setup
# <<< conda initialize <<<
I have the exact same problem, and I could not find any other source on why the conda environment gets appended instead of prepended. I have added the following code to my .bash_profile (after conda initialisation) which flips the order of all path location. This is definitely a terrible practice, but it might be a quick fix for someone who is stuck on the same problem.
locations=($(echo $PATH | tr ":" "\n"))
path=""
for (( idx=${#locations[#]}-2 ; idx>=0 ; idx-- )) ; do
# Skip the last path location since this would put the general /Users/XXX/opt/anaconda3/condabin first
# To not do this change the -2 to -1
path="${path}:${locations[$idx]}"
done
path="${path:1}"
PATH=$path
export $PATH
As noted in the comment, I do not add the location "/Users/XXX/opt/anaconda3/condabin", since it would mess up my environment location, which is located second to last. Please examine your own path variable and decide accordingly.
EDIT: If anyone has a better solution, please let me know!
TL;DR
In macOS, if you place any code that modifies $PATH on macOS inside .zshenv, it will be overridden. You should put it in .zshrc or somewhere else which is then sourced by your .zshrc.
Complete explanation
As answered on Unix & Linux Stack Exchange, when zsh is sourced, files are read in the following order:
etc/zshenv/ -> $ZDOTDIR/.zshenv/ -> etc/zprofile/ -> $ZDOTDIR/.zprofile/ -> etc/zshrc/ -> $ZDOTDIR/.zshrc/ -> etc/zlogin/ -> $ZDOTDIR/.zlogin/
In macOS's /etc/zprofile, a script is sourced that overrides the $PATH according to the contents of these files:
/etc/paths
/etc/paths.d
/etc/manpaths
/etc/manpaths.d
So you should put not put any line that changes $PATH in your $ZDOTDIR/.zshenv, but rather in any file sourced after that (e.g. $ZDOTDIR/.zshrc). Do not edit files in /etc/!
I have trouble using anaconda environment in Tmux. I am on OSX.
I first
tmux
Then activate the Conda env:
conda activate myenv
At this point when I conda info shows the correct active environment and correct location. But which python still points to the default /usr/bin/python.
In the .bash_profile I have these lines added by anaconda when installed. So I guess I need to add something to let the terminal find the right python path?
# added by Anaconda3 5.3.1 installer
# >>> conda init >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$(CONDA_REPORT_ERRORS=false '/Users/jiajunyang/anaconda3/bin/conda' shell.bash hook 2> /dev/null)"
if [ $? -eq 0 ]; then
\eval "$__conda_setup"
else
if [ -f "/Users/username/anaconda3/etc/profile.d/conda.sh" ]; then
. "/Users/username/anaconda3/etc/profile.d/conda.sh"
CONDA_CHANGEPS1=false conda activate base
else
\export PATH="/Users/username/anaconda3/bin:$PATH"
fi
fi
Thank you for your suggestion.
Below works for me on macOS 10.15 with zsh:
Add below line to your ~/.tmux.conf file
set -g default-command "/bin/zsh"
If you're using a shell other than zsh, I assume changing the path to the shell you're using will also work.
same here, mac 10.14, tmux 3.0a
solution is:
source /Users/mac/opt/anaconda3/etc/profile.d/conda.sh
[[ -z $TMUX ]] ∨ conda deactivate; conda activate base
add 2 lines in your .zshrc. Then
source ~/.zshrc
everything works fine now!!
I had the same issue. Finally I find that tmux will always call the profile for your shell, not just the rc. So if you are using bash like I do, it will call /etc/profile, which will have a call to path_helper.
In order to fix this, change /etc/profile to:
if [[ -z $TMUX ]] && [ -x /usr/libexec/path_helper ]; then
eval `/usr/libexec/path_helper -s`
fi
If you are using bash, also change any export PATH=$PATH:/foo in .bashrc to
if [[ -z $TMUX ]]; then
export PATH=$PATH:/foo
fi
then you restart the terminal(for example Iterm). Everything should be good!
Every time I try to use conda in my terminal I get this error:
zsh: correct 'conda' to '.conda' [nyae]?
I have added export PATH=$PATH:$HOME/anaconda/bin to my .zshrc and to my .bash_profile files.
Now, if I run source ~/.bash_profile it works, but I have to run this command every time I open a new window. Is there a way to fix this?
I got the same problem, so I copy the coda initialize code from my .bashrc to .zshrc and it worked.
# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/path/to/ur/anaconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
eval "$__conda_setup"
else
if [ -f "/path/to/ur/anaconda3/etc/profile.d/conda.sh" ]; then
. "/path/to/ur/anaconda3/etc/profile.d/conda.sh"
else
export PATH="/path/to/ur/anaconda3/bin:$PATH"
fi
fi
unset __conda_setup
# <<< conda initialize <<<
I'm using ZSH/oh-my-zsh and the regular OSX terminal, though the same problem occurs in iTerm. I'd been using rbenv and nvm without issue, but recently started working with python and pyenv, and have run into the following issue. On loading a new terminal window, I get the following message at the prompt:
Last login: Sat Apr 1 11:56:46 on ttys001
/Users/jackfuller/.zshenv:3: command not found: pyenv
Since installing pyenv, my machine seems noticeably slower. Obviously loading pyenv will slow things down but load times have dropped way off.
The catch is that pyenv works perfectly after the terminal is loaded, and as far as I can tell my .zshrc is configured properly:
alias dev="cd ~/development"
alias gow="cd ~/goworkspace"
alias dl="cd ~/downloads"
export PATH=/usr/local/bin:$HOME/bin:$PATH
export EDITOR='atom -n'
export PAGER='less -f'
export PATH=$HOME/.rbenv/shims:$PATH
RBENV
if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi
# NVM
export NVM_DIR="/Users/jackfuller/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm
# PYENV
export PYENV_ROOT=/usr/local/opt/pyenv
eval "$(pyenv init - --no-rehash)"
# if which pyenv > /dev/null; then eval "$(pyenv init - --no-rehash)";
fi
# For go.
export GOPATH="$HOME/goworkspace"
export PATH=$PATH:/usr/local/go/bin
export GOROOT="usr/local/go"
If anyone can offer any advice/solutions, it would be much appreciated. Environment variables and shell config files seem more temperamental /confusing than they should be.
/Users/jackfuller/.zshenv:3: command not found: pyenv indicates that your error is in .zshenv at line 3. Maybe you could post your .zshenv. Is there a reason the fi after #PYENV is not commented? Also you could do export PATH=... once and not thrice. Try which pyenv to find the path to pyenv and look if its in your $PATH. For Future uses i'd put my aliases into ~/.zsh_aliases and do a source ~/.zsh_aliases in the .zshrc, otherwise it gets pretty ugly once you have some more aliases. Sorry for the bad structured answer ;)