Page Body

The Bash Shell Environment

A shell is a command line interpreter that provides a user interface for terminal windows. This interface encloses the operating system it is running on, like a shell, and hides the operating system from view. Graphical desktops, like GNOME, are also shells, but instead of reading text commands from the keyboard, they read graphical commands via a mouse or trackpad.

The Bourne or Bourne-like shells are the:

  • Bourne Shell (sh)
  • Bourne-Again Shell (bash)
  • Korn Shell (ksh)
  • Z Shell (zsh)

The C or C-Shell-like shells are the:

  • C Shell (csh)
  • Tenex C shell (tcsh)

Note: If you are not familiar with the GNU/Linux command line interface, review the Conventions page before proceeding.

The Bash Shell

The Bash shell (the Bourne-Again shell) is the default shell for many GNU/Linux distributions. It was designed as a free alternative to UNIX's Bourne shell.

bash represents the return of the traditionally C-shell-using BSD world to the Bourne concepts.

Shell Command Format

The format for a shell command is:

command options arguments

For example, you can determine which shell you are currently using by running the echo ${SHELL} command, which outputs the contents of the SHELL environment variable.

Options are switches that turn specific aspects of a command on or off. Most options start with a dash (-) and can be aggregated behind a single dash (e.g., -abc). Long options start with two dashes (--) and cannot be aggregated.

Arguments are the values that commands act on. Options can have their own arguments, as well.

For some commands (e.g., tar, paste), a - by itself can be used to represent the standard input as an argument. A -- by itself, without any options, instructs a command to expect a filename, rather than an option (i.e., it represents the end of options).

Internal and External Commands

Internal commands are made available to the shell itself and are built-in commands. These commands can be viewed with the help command. The type command, which tells you how a command will be interpreted by the shell, will tell if you a command is a built-in command (an alternative to type is the command -V command).

External commands are executable files that exist outside of the shell within the file system.

Shell Variables

Shell variables govern various aspects of a shell's behavior. In a shell, a variable consists of a name and a value. A variable's name consists of a sequence of letters, digits, and underscores (_), and must start with a letter or underscore.

You can declare a variable like so:


Make sure that there are no spaces around the assignment operator (=).

To use a variable on the command line and have its name substituted for its value, you can surround the variable name with curly braces ({}) and prefix it with a dollar sign ($).

echo ${ex_variable}

All variables are shell variables, and some shell variables are also environment variables, like SHELL. Environment variables govern aspects of child processes (e.g., programs started from the shell), as well as those of the shell itself. By convention, internal shell variable and environment variable names are capitalized.

Shell Functions

Shell functions are blocks of code that you can repeatedly call by invoking the name of the function. In Bash, you can create a function as follows:

function ex_function_name() {

For example, this simple function outputs a greeting:

function hello_world() {
  echo 'Hello, world!'

You call the function by using its name, hello_world.

Shell Options

Shell options are settings you can toggle to change the shell's behavior. For example, there are shell options that can help you debug shell scripts, and to enable/disable shell features like brace expansion and filename expansion.

Shell Types

There are three forms of shells:

  1. Login shells
  2. Interactive shells
  3. Non-interactive shells

Login Shells

The login shell is the shell that you immediately obtain after logging into your system. The program that starts the login shell passes the shell a - as the first character of its program name. You can use this fact to determine if your current shell is a login shell.

For example, running echo ${0} will display the value of the ${0} special variable, which contains the name of the shell (or shell script). If the first character you see is a -, your shell is a login shell.

You can determine your user's login shell by running the following command:

getent passwd ex_username | cut -d: -f7

getent passwd searches the /etc/passwd file for a user line that matches the username you specify. The output of that command is sent to the cut command via a pipeline. cut -d: -f7 returns the 7th field in the colon-delimited line for the specified user account from /etc/passwd. That field contains your user's login shell.

You can view the login shells available on your system by running the ls $(cat /etc/shells) 2> '/dev/null' command. If a shell listed in /etc/shells is not installed on your system, the ls command will generate an error for that entry, and that error will be suppressed by being redirected to /dev/null, i.e., a bit bucket (comment lines in /etc/shells will be suppressed, too).

If you are not using a restricted login shell, you can change the login shell for your account with the chsh -s command:

chsh -s /full/path/to/example/shell

Running the chsh command by itself will start it in interactive mode, where you will need to provide the full path to your new login shell. Unless you are using this command as the root user, the shell you specify must be listed in /etc/shells.

If you are acting as root, you can change the login shell for any user account:

# chsh -s /full/path/to/example/shell ex_username

You can open a login shell for a user account by using sudo -i or su -l:

  • sudo -i ex_username
  • su -l ex_username

If you do not specify a username, the root user (superuser) is assumed.

You can open a non-login shell for a user account by using sudo -s or su:

  • sudo -s ex_username
  • su ex_username

Again, if you do not specify a username, the root user (superuser) is assumed.

Interactive Shells

If you use bash without any arguments, and its standard input and standard output channels are connected to a terminal, it will see itself as an interactive shell. If you are using a GNU/Linux system with a graphical environment, the terminal emulators that you open on your desktop are interactive shells.

Non-Interactive Shells

Non-interactive shells are shells that do not process any files when started or terminated. A shell is non-interactive if it is used to execute a shell script, or if a program uses a shell to run another program.

The Shell Environment

Your shell has an environment, i.e., a variety of variables, aliases, functions, and options that are available to it. This environment is established by executing commands from various files in a specific order, based on the kind of shell you are using.

You can load the commands from a file using the source or . commands (e.g., . /path/to/example/file).

The Login Shell Environment

For login shells, the file sourcing order is (where ~ represents the user's home directory):

  1. /etc/profile
  2. /etc/profile.d files
  3. ~/.bash_profile or ~/.bash_login or ~/.profile
  4. ~/.bashrc
  5. ~/.bash_logout (upon quitting a login shell, and only if the file exists)

The Non-Login Shell Environment

For non-login shells, the file sourcing order is:

  1. /etc/bash.bashrc or /etc/bashrc (which file is used depends on your GNU/Linux distribution)
  2. ~/.bashrc

When you quit an interactive non-login shell, no files are processed.

Shell Environment Configuration

Settings that apply to all system users can be placed into /etc/profile, and either /etc/bash.bashrc or /etc/bashrc, depending on your GNU/Linux distribution. These files are sourced from their user-specific equivalent files. Settings specific to your user account can go in your user-specific files.

Generally, environment variables (e.g., PATH, SHELL) are set once, so it is sufficient to define them in either ~/.bash_profile, ~/.bash_login, or ~/.profile.

Shell variables that are not environment variables and customize the shell's behavior (e.g., HISTSIZE, PS1), and shell options, are good candidates for being placed in your ~/.bashrc file. Aliases and functions can go here, too.

To have these user-specific items available in login shells, you can have your login shell configuration file (i.e., ~/.bash_profile or ~/.bash_login or ~/.profile) source your ~/.bashrc file.

Shell Environment Commands

There are several commands that will show you your shell's environment:

set or declare
Display all shell variables and functions.
env or printenv or export
Display all environment variables.


You can set and unset shell options with the eponymous set command. To set a shell option, you use the -o option:

set -o ex_option

To unset a shell option, you use the +o option:

set +o ex_option

set can also be used to set Bash's positional parameters:

$ set a b c d
$ echo "${2}"


By itself, the declare command displays the attributes and values of all variables. When provided a variable name, it can also be used to set variable values and attributes.

For example, you can declare an integer variable as follows:

declare -i ex_variable=ex_integer

To unset the integer attribute on the variable above, you can use the +i option:

declare +i ex_variable

If you want to see your environment's functions and their contents, you can use the declare -f command. If you only want to see the function names, use declare -F, instead.

When declare is used in a function, it makes variables local, unless you use the -g option.


The shopt command also allows you to set shell options. Here, the -s option is used to set a shell option, and the -u option is used to unset one.

You can view all the shell options that you can configure with the shopt command by entering shopt at the command line.


You can undue your environment changes and start with an empty environment with the env -i command (-i is short for --ignore-environment). You can remove a variable (or function) from the environment by using the env -u command, e.g., env -u ex_variable (some variables/functions can also be removed from the environment with the unset command).


You can promote a shell variable into an environment variable with the previously mentioned export command:

export ex_variable...

Afterwards, subprocesses will be able to modify the value of the exported variable. However, the parent shell will not see the subprocess's changes, i.e., exported variables are not shared, they are only copied and inherited. Unless your export command is placed in a shell environment configuration file, your change will not be permanent.

To convert a promoted variable back into a shell variable, you can use export's -n option.


For more information on the topics discussed here, refer to the Linux User's Manual, either at the command line or online.


Enjoyed this post?

Subscribe to the feed for the latest updates.