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 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.

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. A -- by itself, without any options, instructs a command to expect a file name, rather than an option.

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

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:

variable_name=variable_value

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

All variables are shell variables, and some shell variables are also environment variables, like SHELL. Environment variables govern aspects of child processes (e.g., subshells), 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 example_function_name() {
  example_commands
}

For example, this simple function outputs a greeting:

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

You call the function by using 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 file name 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 example_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 superuser, the shell you specify must be listed in /etc/shells.

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.

Aliases and functions are not inherited by subshells, so they are good candidates for being placed in your ~/.bashrc file. Shell variables that are not environment variables and customize the shell's behavior (e.g., HISTSIZE, PS1) and shell options 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

set

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

set -o example_option

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

set +o example_option

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

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

declare

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 example_variable=example_integer

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

declare +i example_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.

shopt

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.

env

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 example_variable.

export

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

export example_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.

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

Avatar

Enjoyed this post?

Subscribe to the feed for the latest updates.