How-to: Terminal/profile startup files in macOS

There are two default shells commonly used with macOS:

zsh (Z shell) is the default shell for all newly created user accounts, starting with macOS Catalina. zsh is highly compatible with the Bourne shell (sh) and mostly compatible with bash, with some differences. This is the default for licensing reasons.

bash is the default shell in macOS Mojave and earlier.

The default shell can be changed with chsh or in System Preferences ➞ Users and Groups

To view the current default shell, use: dscl . -read ~/ UserShell
To view the current shell, use: echo $SHELL

Startup files

On a brand new user account, none of these files will exist, they can be created with any suitable text editor (e.g. BBedit) that is capable of creating plain UTF8 text files with no BOM and Unix style (LF) line endings. Save them into your home folder (~/).
By default these system files will not be displayed by Finder, use the command line or a text editor.

  zsh bash
At login .zprofile .bash_profile
Environment for interactive shells
(Run Commands)
.zshrc .bashrc*
Set environment variables. .zshenv Use .bash_profile but also see $BASH_ENV

* .bashrc is not used in macOS, though you can create it and source from .bash_profile allowing things to be setup like Linux.

e.g. add this to the end of .bash_profile to source .bashrc:

if [ -f ~/.bashrc ]; then
source ~/.bashrc

Most mac users running bash will put everything into .bash_profile.

For mac users running ZSH, the ~/.zshrc file is evaluated every time a shell is launched. The ~/.zprofile file is only evaluated when you login to your mac user account.

The .zprofile should be used for any commands and variables which need to be set once or which don’t need to be updated frequently. After editing .zprofile Exit and relaunch the terminal or run: exec zsh --login

The .zshrc (environment for interactive shells) should be used for parameters like $PROMPT, aliases, functions, options, history variables and bind keymappings you would like to have in both login and interactive shells.

.zshenv is sourced on all invocations of the shell, unless the -f option is set. It should contain commands to set the command search $PATH, plus other important environment variables.


If you are using the bash shell and want to have the same auto-complete as zsh, create a ~/.inputrc configuration file containing the following:

# Ignore case for auto-complete
set completion-ignore-case on

Order of reading startup files in bash:

/etc/profile → .bash_profile → .bash_login → .profile

When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable.
The --noprofile option may be used when the shell is started to inhibit this behavior.

Order of reading startup files in zsh:

.zshenv → .zprofile → .zshrc → .zlogin

.zshenv is sourced on all invocations of the shell, unless the -f option is set.
.zshenv should not contain commands that produce output or assume the shell is attached to a tty.

.zlogin is sourced in login shells. It should contain commands that should be executed only in login shells.

.zprofile is similar to .zlogin, except that it is sourced before .zshrc. .zprofile is meant as an alternative to .zlogin for ksh fans; the two are not intended to be used together, although this could certainly be done if desired. .zlogin is not the place for alias definitions, options, environment variable settings, etc.; as a general rule, it should not change the shell environment at all. Rather, it should be used to set the terminal type and run a series of external commands (fortune, msgs, etc).

macOS is unusual in that it runs each terminal session as a login shell. Typically, most other versions of Unix and Linux will encounter a login shell only if either:

Sourcing files

If you have a lot of shell configurations, you may want to split them out into several subfiles and use the source builtin to load them:
source ~/.bash-options
source ~/.bash-aliases
source ~/.bash-functions

Alternatively, to ensure the files actually exist before loading

if [ -f ~/.bash-aliases ]; then
. ~/.bash-aliases

The command . ~/.bash-aliases will source ~/.bash-aliases in the context of the currently running shell.

This is particularly useful for adding aliases, the separate file makes it easier to re-load them when you make changes.

Prior to 10.3 (Panther) OSX used tcsh as the default shell.

Related macOS commands

Terminal ➞ Preferences ➞ General ➞ 'Shells open with' — set to "Default login shell"
- example .bash_aliases.
bashrc_dispatch - use symlinks to reorganise .bashrc, .bash_profile and .profile.
alias - Create an alias.
macOS How To

Copyright © 1999-2024
Some rights reserved