I've just installed zsh on my Ubuntu system. It seems zsh isn't executing ~/.profile on init. To my best understanding, this should be an automatic behavior. What am I missing?
~/.profile, when it is invoked as a login shell. The reason is that zsh has enough incompatibilities with standard shells to break scripts.
Zsh does run
~/.profile if it is called as
ksh. But if your objective is to get a zsh prompt when you log in, that's no help.
You can make
/bin/sh your login shell and include
export SHELL=/bin/zsh in your
~/.profile. Then when you open a terminal, the terminal will launch zsh (except for a few terminal emulators don't obey the
$SHELL setting). But you will still have
sh when you log in over ssh. This can be remedied by including
exec zsh at the end of
~/.profile (this replaces the running shell by zsh), but you need to be careful only to do that for interactive logins and not when
~/.profile is included from other scripts such as the X session start (a good test is the name of the parent process obtained by
ps -o comm= $PPID: if it's
su, then it's safe to
The easiest solution to both work with zsh and run
~/.profile is to create a
~/.zprofile that enters sh emulation mode while it runs
emulate sh . ~/.profile emulate zsh
If you have a recent enough zsh (on Ubuntu, that means since lucid, I think), you can simplify this to
emulate sh -c '. ~/.profile'.
~/.profile is loaded by login shells. The login shell is the first process that is started when you log in in text mode, for example on a text console or via ssh. By default, on most Linux machines, the login shell is bash, but you can change it with the
chsh command, or through some other tool such as the “User Settings” in Ubuntu. When it's a login shell, bash reads
~/.bash_profile if it exists and
~/.profile, whereas zsh reads only
~/.zprofile (because its syntax is not completely compatible with a traditional sh). Under most configurations,
~/.profile is also loaded by the X session startup scripts when you log in in a graphical display manager.
When you start a terminal emulator and get a shell prompt, or when you start a shell explicitly, you get a shell that is not a login shell. Since
~/.zprofile) is for commands that you want to execute when you log in, a non-login shell doesn't read this file. Instead, when you start an interactive zsh, it reads
~/.zshrc. (Zsh reads
~/.zshrc in all interactive shells, whether they are login shells are not; bash, strangely, never reads
~/.bashrc in login shells.)
~/.profile contains environment variable definitions, and might start some programs that you want to run once when you log in or for the whole session;
~/.zshrc contains things that must be done for every shell instance, such as alias and function definitions, shell option settings, completion settings, prompt settings, key bindings, etc.
Short answer for impatient people:
~/.profileis not loaded by
~/.zshrcwhen starting a new terminal session.
Need more info? Look at Gilles' superb answer!
In addition to Gilles's answer, with a reasonably recent version of zsh you can do this:
[[ -e ~/.profile ]] && emulate sh -c 'source ~/.profile'
...Which will source the .profile file with zsh's sh-mode in effect. And it's only active during the source. So you do not have to save the current option state in order to replay it again after sourcing.
.zprofile compatible with
.profile (contains only PATH changes), hence only needing:
ln -s .profile .zprofile
The zsh documentation I have on hand only mentions
~/.profile for login shells in sh/ksh compatibility mode.
% zsh --version zsh 4.3.10 … % cat ~/.profile echo 'Running ~/.profile...'
Native mode login shell (argv starts with
-) does not use
~/.profile (it will use
% zsh -c 'exec -a -zsh zsh' </dev/null
sh/ksh compatability mode login shells uses .profile:
% zsh -c 'exec -a -sh zsh' </dev/null Running ~/.profile... % zsh -c 'exec -a -ksh zsh' </dev/null Running ~/.profile...