Overview of Bash

The powerful Unix shell.

This article provides an overview of the Bash shell, detailing its startup behaviour across different environments (Linux, macOS, Windows). It explains the initialization files involved in configuring the shell, the differences between login and non-login shells, and the sequence of events that occur when starting a Bash session. Additionally, it includes a flowchart to visually represent the Bash startup process.


Bash Startup Overview (1.0)

The behaviour of Bash when starting up depends on the environment, whether you are on Linux, macOS, or Windows. For more on Bash scripting, refer to the Advanced Bash Scripting Guide.

Linux Environment (1.1)

How Bash starts up in a Linux environment:

  1. Launch Terminal: You open a terminal emulator (e.g., GNOME Terminal, Konsole, xterm).
  2. Terminal Emulator Starts: The terminal emulator application initializes and creates a window for user interaction.
  3. Login Shell: The terminal starts a login shell process, often Bash by default. A login shell is a shell session that begins with a user login, typically in a multi-user environment rather than when working solo.
  4. Environment Initialization: Bash reads and executes initialization files (/etc/profile, ~/.bash_profile, ~/.bash_login, ~/.profile) in this order to configure the environment.
  5. Prompt Displayed: The prompt (e.g., user@hostname:~$) appears, indicating that the shell is ready to accept user commands.

Now the terminal is ready with the Bash shell running. You can start typing commands and scripts.

bash
Bash Overview

Bash Startup (1.2)

When you type bash in a terminal, a new instance of Bash is started, if not started by default. Here’s what happens:

  1. Command Execution: You type bash and press Enter. The current shell interprets this command and executes it.
  2. New Bash Instance: A new instance of Bash is started as a subshell within the current shell session.
  3. Non-Login Shell: Unlike the login shell, this new Bash instance is a non-login shell, which means it skips some of the initialization files.
  4. Environment Initialization: The non-login shell reads and executes the ~/.bashrc file to configure the environment.
  5. Prompt Displayed: The prompt for the new Bash instance appears, ready for input.

Initialization Files (1.3)

  • /etc/profile: System-wide configuration script executed for login shells.
  • ~/.bash_profile: User-specific configuration script executed for login shells.
  • ~/.bash_login: Alternative to ~/.bash_profile, executed if ~/.bash_profile is not found.
  • ~/.profile: Another alternative, executed if neither ~/.bash_profile nor ~/.bash_login are found.
  • ~/.bashrc: Executed for non-login shells to configure user-specific environment settings.

Background Processes (1.4)

  • Process Creation: The terminal emulator creates a new process for the shell using system calls like fork() and exec().
  • TTY Allocation: The terminal emulator allocates a pseudo-terminal (PTY) for the shell process to handle input and output.
  • Environment Variables: Environment variables are set up, including $PATH, $HOME, and others defined in the initialization files.

Important Files in macOS (1.5)

These files play key roles in defining the environment for Bash in macOS:

  • ~/.profile: Loaded each time the Terminal app launches; sets up user-specific environment preferences.

  • ~/.bashrc: Contains export statements and environment configurations specific to Bash sessions.

  • /etc/paths: The main file listing default system paths that build the PATH environment variable across users.

  • ~/.bash_profile: Only read once upon logging in, making it specific to login sessions.

    Note: Non-terminal applications in macOS do not inherit the system-wide PATH and MANPATH variables that Terminal does. To set environment variables for GUI applications, use ~/.MacOSX/environment.plist as recommended by Apple (see Technical Q&A QA1067).

How These Files Are Loaded (1.6)

As documented on Wikipedia, Bash reads configuration files in a specific order depending on the session type (login vs. non-login):

  • ~/.bash_profile: Executed when you log in; it often sources ~/.bashrc.
  • ~/.bashrc: Primarily for setting up interactive, non-login shells.
  • ~/.bash_login, ~/.bash_logout, and ~/.bash_history: Used for login/logout events and storing command history.

When a user logs in, Bash runs ~/.bash_profile, which often sources ~/.bashrc. While ~/.bashrc is not a login initialization file by itself, it sets up shell-specific configurations that ~/.bash_profile can reference.

Conclusion (1.7)

    flowchart TD
	%% Node Definitions with Different Shapes
	A(["Open Terminal Emulator"]):::terminal --> B{Initialize Terminal Emulator}:::process
	B -->|Login| C["Start Login Shell"]:::shell
	B -->|Non-Login| E(["Start Non-Login Shell by typing bash"]):::shell
	
	%% Sequential Flow for Login Shell
	C --> D[/Read /etc/profile/]:::file
	C --> F{{Read ~/.bash_profile}}:::file
	F --> G{{Read ~/.bash_login if ~/.bash_profile is not found}}:::file
	G --> H{{Read ~/.profile if ~/.bash_profile and ~/.bash_login are not found}}:::file
	
	%% Sequential Flow for Non-Login Shell
	E --> I[/Read ~/.bashrc/]:::file
	
	%% Conclusion
	D --> J(["Shell Ready"]):::ready
	H --> J
	I --> J
	J --> K{Prompt Displayed}:::displayed
	
	%% Class Definitions for Styles
	classDef terminal fill:#f9f,stroke:#333,stroke-width:2px;
	classDef process fill:#bbf,stroke:#333,stroke-width:2px;
	classDef shell fill:#aff,stroke:#333,stroke-width:2px;
	classDef file fill:#f99,stroke:#333,stroke-width:2px;
	classDef ready fill:#9f9,stroke:#333,stroke-width:2px;
	classDef displayed fill:#ff9,stroke:#333,stroke-width:2px;

Deepen Your Knowledge

Want to master Bash scripting? The Linux Command Line by William Shotts is a highly recommended book for going from beginner to advanced shell user.