Using Anaconda with zsh on Catalina - bash

The Anaconda installer added this script originally to my .bashrc or .bash_profile so I copied it over to .zshrc when I switched to zsh. I recently read I didn't need to/shouldn't have copied it over since it was meant for .bash_profile, but now that macOS is moving to use zsh anyway I'd like to know what I should do. Obviously I need to tell zsh where Anaconda is but do I need that script or can I just export the Anaconda path like export PATH=/Users/ty604/anaconda3/bin:$PATH?
Script added by Anaconda installer.
export PATH=/Users/ty604/anaconda3/bin:$PATH
# added by Anaconda3 2019.03 installer
# >>> conda init >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$(CONDA_REPORT_ERRORS=false '/Users/ty604/anaconda3/bin/conda' shell.bash hook 2> /dev/null)"
if [ $? -eq 0 ]; then
\eval "$__conda_setup"
else
if [ -f "/Users/ty604/anaconda3/etc/profile.d/conda.sh" ]; then
. "/Users/ty604/anaconda3/etc/profile.d/conda.sh"
CONDA_CHANGEPS1=false conda activate base
else
\export PATH="/Users/ty604/anaconda3/bin:$PATH"
fi
fi
unset __conda_setup
# <<< conda init <<<
I also have many duplicate paths in $PATH because of duplicate export commands in various shell files.
$ echo $PATH
/Users/ty604/anaconda3/bin:/Users/ty604/anaconda3/condabin:/Users/ty604/anaconda3/bin:/Users/ty604/.cargo/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/VMware Fusion.app/Contents/Public:/usr/local/share/dotnet:/Users/ty604/flutter/bin
Files in my system
.bash_history, .bash_profile, .bashrc, .profile, .zprofile, .zsh_history, .zshrc, .zshrc.pre-oh-my-zsh
Folders in my system
.bash_sessions, .oh-my-zsh, .zsh
macOS will be using zsh moving forward and we can set zsh as the default shell in Catalina which I have done. With Catalina is it ok if I remove all traces of bash and oh-my-zsh since zsh is now the default shell? Also I am using Hyper Terminal which means I do not need oh-my-zsh any longer right?

If you are using zsh as your shell (which is up to you, since Catalina still provides bash as well), and need some settings for it, they should go into .zshrc, respectivels .zprofile. Of course you don't blindly copy everything from .bashrc over, because you need to be sure that the code is valid under Zsh too. However, the code snippet you posted, looks safe for me, i.e. it should work under both bash and zsh.
In this case, I suggest (for easier maintenance) to put initialization code common to bash and zsh into a separate file, say ~/.commonrc, and source this file in .zshrc and .bashrc. Note also that .zshrc is only read if this is an interactive shell. See the section STARTUP/SHUTDOWN FILES in the zshall man-page.

Found out via an Anaconda dev post that she was using
conda_setup="$(CONDA_REPORT_ERRORS=false '/Users/user_name/anaconda3/bin/conda' shell.zsh hook 2> /dev/null)"
Couldn't find shell.zsh hook anywhere else so hopefully this will help someone else.
I am proceeding to move all bash files outside of my system since the default macOS zsh shell is now zsh.

Related

How do I update the PATH in bash_profile on OSX

I'm trying to install flutter on my Mac, in order to do so I need to add a path to the .bash_profile. But when I run the command vim .bash_profile in the terminal ,I'm met with the following message.
# The original version is saved in .bash_profile.pysave
PATH="/Library/Frameworks/Python.framework/Versions/3.7/bin:${PATH}"
export PATH
export M2_HOME=/Applications/apache-maven-3.6.3
export PATH=$PATH:$M2_HOME/bin# added by Anaconda3 2019.10 installer
# >>> conda init >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$(CONDA_REPORT_ERRORS=false '/Users/sofie-amaliepetersen/opt/anaconda3/bin/conda' shell.bash hook 2> /dev/null)"
if [ $? -eq 0 ]; then
\eval "$__conda_setup"
else
if [ -f "/Users/sofie-amaliepetersen/opt/anaconda3/etc/profile.d/conda.sh" ]; then
. "/Users/sofie-amaliepetersen/opt/anaconda3/etc/profile.d/conda.sh"
CONDA_CHANGEPS1=false conda activate base
else
\export PATH="/Users/sofie-amaliepetersen/opt/anaconda3/bin:$PATH"
fi
fi
unset __conda_setup
# <<< conda init <<<
This is my first time adding a PATH, I've tried looking at setting path in terminal
But I'm not sure how it applies to my problem.
Any suggestions would be appreciated. Thanks
Something important to note, is that if you're using Catalina (Or any of the newer forms os osx) your computer won't be using the bash shell by default (Although you'll still be able to update your bash_profile, it won't work, as the computer doesn't care). You'll need to update your zshrc instead of the bash profile. (just typing zsh in your terminal should be able to switch between them, showing you a % instead of a $)
The same process as with the bash profile can be used, and the same line too. Also if you WANT the computer to use the bash profile instead you can force it, but there's no realistic functionality changes between the two in 99% of applications.
Anywhere in your .bash_profile, add this line
export PATH=$PATH:/your/new/path/to/add
This simply add /your/new/path/to/add to your existing $PATH

Conda does not set paths when activating environment

When starting a new shell, the PATH environment variable is not configured
properly. The directories anaconda3/bin or miniconda3/bin are at second
position only, not at first position in the PATH variable. This can be
resolved by conda deactivate and activating it again.
This question was asked several times already (e.g. here and here)
but the existing questions are either very old or concentrate on the use of
source activate env-name. All in all, I found no answer that resolves my
problem.
When I start a new shell, the base environment is activated. The relevant
snippet from my .bashrc reads like this:
condaexe="/home/$USER/.miniconda3/bin/conda"
condash="/home/$USER/.miniconda3/etc/profile.d/conda.sh"
__conda_setup="$($condaexe 'shell.bash' 'hook' 2> /dev/null)"
# shellcheck disable=SC2181
if [[ $? -eq 0 ]]
then
eval "$__conda_setup"
elif [[ -f "$condash" ]]
then
source "$condash"
fi
unset __conda_setup condaexe condash
Then, the PATH variables are defined as follows:
(base)$ echo $PATH
/home/user/.local/bin:/home/user/.miniconda3/bin:/home/user/.miniconda3/condabin:/home/user/workspace/my-project/:/home/user/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
(base)$ conda deactivate && echo $PATH
/home/user/.local/bin:/home/user/.miniconda3/condabin:/home/user/workspace/my-project/:/home/user/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
$ conda activate base && echo $PATH
/home/user/.miniconda3/bin:/home/user/.local/bin:/home/user/.miniconda3/condabin:/home/user/workspace/my-project/:/home/user/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
(base)$
Note that /home/user/.local/bin is contained twice; once before and once
after the Miniconda3 directories.
I tried to debug the problem by appending the following snippet to .bashrc:
echo $CONDA_PROMPT_MODIFIER
echo $PATH
This yields
(base)
/home/user/.miniconda3/bin:/home/user/.miniconda3/condabin:/home/user/workspace/my-project:/home/user/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
which would be perfectly fine but, somehow, is modified after .bashrc.
Note that here /home/user/.local/bin is contained only once.
What goes on here? How can I setup Bash/Conda to get a properly defined PATH
environment variable?
There are three components I missed in the original question which are key to the solution.
First, I run all my shells inside TMux. Second, TMux sources the .profile. Third, in .profile some local directories like the aformentioned ~/.local/bin are blindly prepended to the PATH.
Taken this altogether all the weird behaviour above makes sense. Especially that PATH is correct at the end of ~/.bashrc but not in the shell is obvious now; it got modified in between by ~/.profile.
There are three solutions for this:
deactivating and activating conda manually (temporary workaround)
being more picky about which shells are started inside TMux (very unhandy)
commenting out the manipulations of PATH in ~/.profile
It seems as if one cannot configure TMux to source only ~/.bashrc (reference 1, reference 2), albeit some workarounds exist here too.
This is related to the Bash init files. By default, ~/.bashrc is used in an interactive, non-login shell. It won't be sourced in a login shell. Tmux uses a login shell by default. Hence, shells started by tmux skip ~/.bashrc.
default-command shell-command
The default is an empty string, which instructs tmux to create a login shell using the value of the default-shell option.
Init files for Bash,
login mode:
/etc/profile
~/.bash_profile, ~/.bash_login, ~/.profile (only first one that exists)
interactive non-login:
/etc/bash.bashrc (some Linux; not on Mac OS X)
~/.bashrc
non-interactive:
source file in $BASH_ENV
The weird interactive, non-login loading requirement confuses people in other situations as well. The best solution is to change the loading requirement of ~/.bashrc as interactive only, which is exactly what some distros, like Ubuntu, are doing.
# write content below into ~/.profile, or ~/.bash_profile
# if running bash
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
This should be the solution you desire. And I recommend every Bash user setup this in the profile.
References
Unix Shell Initialization
man tmux
Thanks for this post! That give me hint to debug same issue. I think everyone is different situdation but the idea is same: there is a command like export $PATH change the path in your zshrc or .bashrc which will affect the computer to find the path you want.

Java_HOME not found when changed shell from Bash to Zsh on OSX?

This is weird, I have set JAVA_HOME for my mac which can be found when I am using bash shell, but if I change shell, I get a message saying JAVA_HOME not set. What could be going on here?
I stumbled upon your question when trying to solve the same issue while migrating from bash to oh-my-zsh. The reason it's not there is that there is no code setting it for zsh but there was for bash. Generally theres something exporting JAVA_HOME whenever a new bash window is opened so it's always set for you. There is a good thread where this might be happening on the Unix & Linux StackExchange site.
To do the same thing in zsh, you can edit the .zshrc which is run every time zsh starts. I found a sample .zshrc which got me most of the way. The key line being:
export JAVA_HOME=`/usr/libexec/java_home`
Here is the file which I appended to the end of my existing ~/.zshrc file:
#zshrc, interactive shell settings
export ZSH=$HOME/.zsh
# emacs integration
[[ $EMACS = t ]] && unsetopt zle
# env
if [[ -e /usr/libexec/java_home ]]; then
export JAVA_HOME=`/usr/libexec/java_home`
fi
if [[ -e /usr/local/lib/node_modules ]]; then
export NODE_PATH=/usr/local/lib/node_modules
fi
# path
export PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11/bin
export PATH=/opt/usr/sbin:/opt/sbin:/opt/usr/bin:/opt/bin:$PATH
export PATH=/usr/local/bin:/usr/local/sbin:$PATH
export PATH=$HOME/.cabal/bin:$PATH
export PATH=$HOME/.gem/ruby/1.8/bin:$PATH
export PATH=$JAVA_HOME/bin:$PATH
export PATH=$HOME/.bin:$PATH
setopt null_glob
# source all files in zsh root
for include in $ZSH/*.zsh; do
source $include
done
# source all non-controlled files
for include in $ZSH/private/*.zsh; do
source $include
done
unsetopt null_glob
Then source ~/.zshrc to run in the current shell (or just start a new one) and you should be able to see that it is set with export | grep JAVA_HOME.
I also ended up running mkdir ~/.zsh to create the directory this is looking for and removing the .cabal and .gem lines as they were not needed for me.
I have just installed Mac OS Catalina Version 10.15 and found that environment variables such as JAVA_HOME and others that have been set in my .bash_profile :
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home
export PATH=$JAVA_HOME/bin:$PATH
export ANDROID_HOME=/Users/mynziak/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools
export M2_HOME=/usr/local/Cellar/maven/3.6.2/libexec
export M2=${M2_HOME}/bin
export PATH=${PATH}:${M2_HOME}/bin
are not set in fact!
I saw % in terminal instead of general $ that means you are using a zsh shell instead of bash shell. With Catalina zsh is now the default shell and bash will be completely gone in the future.
oh-my-zsh shell:
https://ohmyz.sh/
So you have to setup all environment variables in .zshrc file.
I just copy-pasted every variables from .bash_profile in to .zshrc and re-opened terminal.
Files .bash_profile and .zshrc are hidden (cmd+shift+. - show hidden files in finder) but can be found in path:
/Users/mynziak/.zshrc
but use own username!
When you set JAVA_HOME in a shell, then it is active and available only for that context, and it will be gone when you close that shell.
Instead either change global environment (or) your .bashrc to include it. So that every time you start a shell, the variable will be available.
edit the .profile or .bash_profile to include the JAVA_HOME.
export JAVA_HOME=`/usr/lib....`
and also below command will return the path for java home directory.
/usr/libexec/java_home -v 1.7
where 1.7 is the version you want.
export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
export PATH=$JAVA_HOME/bin:$PATH
Add above 2 lines in ~/.bashrc or ~/.zshrc and reload the file using source command.

How to load ~/.bash_profile when entering bash from within zsh?

I've used bash for two years, and just tried to switch to zsh shell on my OS X via homebrew. And I set my default (login) shell to zsh, and I confirmed it's set properly by seeing that when I launch my Terminal, it's zsh shell that is used in default.
However, when I try to enter bash shell from within zsh, it looks like not loading ~/.bash_profile, since I cannot run my command using aliases, which is defined in my ~/.bash_profile like alias julia="~/juila/julia", etc.. Also, the prompt is not what I set in the file and instead return bash-3.2$.
For some reasons, when I set my login shell to bash, and enter zsh from within bash, then ~/.zshrc is loaded properly.
So why is it not loaded whenever I run bash from within zsh? My ~/.bash_profile is symbolic linked to ~/Dropbox/.bash_profile in order to sync it with my other computers. Maybe does it cause the issue?
Open ~/.zshrc, and at the very bottom of the file, add the following:
if [ -f ~/.bash_profile ]; then
. ~/.bash_profile;
fi
Every time you open the terminal, it will load whatever is defined in ~/.bash_profile (if the file exist). With that, you can keep your custom settings for zsh (colors, and etc). And you get to keep your custom shell settings in .bash_profile file.
This is much cleaner than using bash -l IMO.
If you prefer putting your settings in .bashrc, or .bash_login, or .profile , you can do the same for them.
Similarly, you could also move the common profile settings to separate file, i.e. .my_common_profile, and add the following to both .bash_profile and .zshrc:
if [ -f ~/.my_common_profile ]; then
. ~/.my_common_profile;
fi
An interactive bash reads your ~/.bash_profile if it's a login shell, or your ~/.bashrc if it's not a login shell.
A typical .bash_profile will contain something like:
if [ -f ~/.bashrc ]; then . ~/.bashrc; fi
so .bashrc can contain commands to be executed by either login or non-login shells.
If you run bash -l rather than just bash, it should read your .bash_profile.
Reference: https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html
For those who have just installed zsh and want their alias from bash to work on zsh do the following
Open .zshrc file in vim like so
vi ~/.zshrc
Scroll to the bottom
click "i" to enable write mode
Tell zsh to load items from bash_profile when needed like so
source ~/.bash_profile
Write and quit like so
:wq
Refresh your zsh like so
source ~/.zshrc
That's it. Now all your saved alias in .bash_profile will be ready to use in zsh.
To complement #Keith Thompson's excellent answer:
macOS:
As #chepner puts it succinctly (emphasis mine):
In OS X, bash is not used as part of the initial [at boot time] login process, and the Terminal.app (or other terminal emulators) process exists outside any pre-existing bash sessions, so each new window [or tab - read: interactive bash shell] (by default) treats itself as a new login session.
As a result, some OSX users only ever create ~/.bash_profile, and never bother with ~/.bashrc, because ALL interactive bash shells are login shells.
Linux:
On Linux, the situation is typically reversed:
bash shells created interactively are [interactive] NON-login shells, so it is ~/.bashrc that matters.
As a result, many Linux users only ever deal with ~/.bashrc.
To maintain bash profiles that work on BOTH platforms, use the technique #Keith Thompson mentions:
Put your definitions (aliases, functions, ...) in ~/.bashrc
Add the following line to ~/.bash_profile
[[ -f ~/.bashrc ]] && . ~/.bashrc
Copy the contents from ~/.bash_profile and paste them at the bottom of ~/.zshrc file.
For ZSH users on MacOs, I ended up with a one liner.
At the very bottom of the ~/.zshrc I added the following line :
bash -l
What it does is simply load the .bash_profile settings(aliases, function, export $PATH, ...)
If you decide to get rid of ZSH and go back to plain BASH, you'll be back to normal with no hassle at all.
If this is something that you do infrequently, or it just isn't appropriate to make changes, you can also 'source' the .bash_profile after launching the child bash shell.
. ~/.bash_profile
This will pull in the settings you make in the .bash_profile script for the life of that shell session. In most cases, you should be able to repeat that command, so it's also an easy way to test any changes that you make without needing to do a full login, as well as bring all of your existing shell sessions up-to-date if you make upgrades to the .bash_profile &/or .bashrc files.
For macOS Big Sur (Version 11.5.2)
Open .zshrc
For example: sudo nano ~/.zshrc
At the end of the file add source ~/.bash_profile
Every time you open the terminal the contents inside the bash profile will be loaded.
Recently I installed oh-my-zsh on OS X and set zsh as default shell and faced the same problem.
I solved this problem by adding source ~/.bash_profile at the end of .zshrc file.
I am using a zsh framework called oh my zsh and I have tried most of the solutions listed here and it broke the format for my custom theme. However, these steps worked for me.
Add new alias(es) at the bottom of my .bash_profile
vi ~/.bash_profile
Make zsh to load items from .bash_profile
source ~/.bash_profile
Refresh zsh
source ~/.zshrc
Restart OSX Terminal app
Try your new alias!
If you'd like to be "profile-centric", you can create .profile as a single source of truth, then load it from both .bash_profile and .zprofile.
.profile
export PATH="/usr/local/opt/python/libexec/bin:$PATH"
# etc., etc.
.bash_profile and .zprofile
if [ -f ~/.profile ]; then
. ~/.profile;
fi
I found this helped bash scripts find the right PATH, etc., and helped me keep configuration in one place.

Is there anything in Zsh like .bash_profile?

Everytime I open the terminal, I have to source .bash_profile to enable the $JAVA_HOME or other variables.
Yes, it's called ~/.zshenv.
Here's how I have $JAVA_HOME set in ~/.zshenv:
export JAVA_HOME="$(/usr/libexec/java_home)"
Keep in mind, however, that zsh is not bash, so just 'cause you have to source your .bash_profile every time you open a terminal does not mean that you have to do that with zsh. With zsh, I only have to re-source my ~/.zshenv when I make changes to it, and then only for terminals which are already open: new terminals should have already sourced my new and improved ~/.zshenv.
NOTE
I often find it helpful, when trying to determine which of my zsh startup files I should place things in to consult zsh startup files.
A newer version of the documentation for startup files can be found here.
I know this is an old question, but I recently upgraded MacOs to Catalina which changed the default shell from bash to zsh.
I ended up doing this:
echo source ~/.bash_profile > ~/.zshenv && source ~/.zshenv
To have zsh source my original .bash_profile.
Recently, with the upgrade to macOS Catalina, the default shell changed to zsh, which uses ~/.zshrc as the resource file.
We usually had ~/.bash_profile inside user home directory the solution is to simply
Open ~/.bash_profile by running vim ~/.bash_profile
Open ~/.zshrc by running vim ~/.zshrc
Copy the content of ~/.bash_profile into ~/.zshrc
Open a new terminal window and run your previous aliases/scripts, which should work flawlessly.
Other simple alternative to continue using your .bash_profile is add this file to your .zshrc file:
Open your .zhsrc file > vim ~/.zshrc
Add this line to your .zshrc file > source ~/.bash_profile
with this simple solution you can continue adding your .bash_prifile if you like zhs.
Adding .bash_profile
There are five separate profile scripts that get executed (in the order given below) when we launch a zsh shell or close it out.
(1) .zshenv --> This is always sourced first but can be overridden by other
(2).zprofile --> This is equivalent for users coming from ksh experience
(3).zshrc --> This is for all of the interactive customizations of zsh
(4).zlogin --> This executes after first three are done
(5).zlogout --> This is executed when we logout of the zsh shell
it would be advisable to put your stuff in .zshenv or in .zshrc
It is not mandatory to have any one of these files. But if it is there, it will be sourced from and executed in the above order.
In Mac Catalina onwards osx versions, the terminal uses zsh. There is a system-wide profile /etc/zprofile.
cat /etc/zprofile
# System-wide profile for interactive zsh(1) login shells.
# Setup user specific overrides for this in ~/.zprofile. See zshbuiltins(1)
# and zshoptions(1) for more details.
if [ -x /usr/libexec/path_helper ]; then
eval `/usr/libexec/path_helper -s`
fi
it says , if you want to override then create ~/.zprofile.
touch ~/.zprofile.
update: macOS Monterey 12.4
yes - for Zsh, it is the file: .zshrc
add there your parameter.
In Mac Catalina, terminal uses zsh. Instead of having .bash_profile, good to have .zshenv and write your script there.
When you open terminal next every time, scripts inside .zshenv gets executed.
I was running into this issue and I followed Zack and Luke Schoen's answer, but my $PATH didn't look the same as what I had in bash.
This post explains what the different config files do:
https://unix.stackexchange.com/questions/71253/what-should-shouldnt-go-in-zshenv-zshrc-zlogin-zprofile-zlogout
I found that splitting my .bash_profile path exports into .zprofile and my aliases into .zshrc worked best for what I wanted.
I found why Zack and Luke Schoen's answer didn't work for me:
The path exports that I listed in .zshenv were executed first and /usr/libexec/path_helper was executed afterwards,
which prepended the paths listed in /etc/paths.
I found the profile file under /etc/zprofile location. This will be for zsh

Resources