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?
5 Answers
.profile
vs. .zprofile
Zsh runs ~/.zprofile
, not ~/.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 sh
or 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 sshd
or su
, then it's safe to exec
).
The easiest solution to both work with zsh and run ~/.profile
is to create a ~/.zprofile
that enters sh emulation mode while it runs ~/.profile
:
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'
.
.zprofile
vs. .zshrc
The file ~/.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 ~/.profile
(or ~/.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.)
Typically, ~/.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.
-
Great answer! I've created ~/.zprofile and put the line as you suggested, but it doesn't seem to do anything. Perhaps I should put it in .zshrc? Commented Sep 13, 2010 at 12:21
-
1@shmichael: Given your reaction, I may not have interpreted your question the way you intended it. Does the second section I've added to my answer help? Commented Sep 13, 2010 at 18:11
-
yes, hit the spot. So if I understand correctly I would want e.g. PATH declarations on .zprofile and aliases on .zshrc. Commented Sep 15, 2010 at 15:19
-
@user1419674 Thank you for the correction, but do not add a change log to posts. The site has a built-in revision history. Commented Mar 17, 2014 at 8:28
-
1@alper Yes. You aren't running a login shell, and whatever that non-login shell is, you're telling it to run the command
zsh
. If you want to read.zprofile
, tell zsh that it's a login shell:ssh -Y4t user@IP zsh --login
Commented Jul 7, 2020 at 21:55
Short answer for impatient people:
~/.profile
is not loaded byzsh
at login.zsh
loads~/.zprofile
at login.zsh
loads~/.zshrc
when starting a new terminal session.
Need more info? Look at Gilles' superb answer!
-
13
-
1
-
ok, for the comments, what does load
.profile
if not zsh? Commented Dec 1, 2021 at 19:29 -
@AlexanderMills Traditional
sh
reads the file~/.profile
at startup when it's a login shell. For info onsh
vs.bash
look here: stackoverflow.com/questions/5725296/… Commented Jan 4, 2022 at 9:53
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.
-
I have this in my ~/.zprofile, but for some reason the statements in ~/.profile are not available in my shell. Ubuntu 15.04; zsh 5.0.7 Commented Sep 15, 2015 at 11:08
-
-
I just tried again, and it looks like it is working now. Not sure if it was fixed at some point or what happened. zsh version is 5.1.1 now. Commented Mar 28, 2016 at 3:41
-
To be able to source the file, it must not only exist, but also be readable. Thus, the test should be
[[ -r ~/.profile]]
.– Mårten WCommented Apr 11 at 14:35
I have .zprofile
compatible with .profile
(contains only PATH changes), hence only needing:
ln -s .profile .zprofile
-
1
The zsh documentation I have on hand only mentions /etc/profile
and ~/.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[0] starts with -
) does not use ~/.profile
(it will use ~/.zprofile
though):
% zsh -c 'exec -a -zsh zsh' </dev/null
(no output)
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...