What's GNU: Bash - The GNU Shell

While originally written by Brian Fox of the Free Software Foundation, bash is now maintained by Chet Ramey. In this article, Chet explains the nhistory of shells and then goes on to explore features specific to bash.
Features not in the Bourne Shell

There are a number of minor differences between Bash and the version of sh present on most other versions of Unix. The majority of these are due to the POSIX standard, but some are the result of Bash adopting features from other shells. For instance, Bash includes the new “!” reserved word, the command builtin, the ability of the read builtin to correctly return a line ending with a backslash, symbolic arguments to the umask builtin, variable substring removal, a way to get the length of a variable, and the new algorithm for the test builtin from the POSIX.2 standard, none of which appear in sh.

Bash also implements the “$(...)” command substitution syntax, which replaces the sh `...` construct. The “$(...)” construct expands to the output of the command contained within the parentheses, with trailing newlines removed. The sh syntax is accepted for backwards compatibility, but the “$(...)” form is preferred because its quoting rules are much simpler and it is easier to nest.

The Bourne shell does not have such features as brace expansion, the ability to have a variable and a function with the same name, local variables in shell functions, the ability to enable and disable individual builtins or write a function to replace a builtin, or a means to export a shell function to a child process.

Bash has closed a long-standing shell security hole by not using the $IFS variable to split each word read by the shell, but splitting only the results of expansion (ksh and the 4.4 BSD sh have fixed this as well). Useful behavior such as a means to abort execution of a script read with the “.” command or automatically exporting variables in the shell's environment to children is also not present in the Bourne shell. Bash provides a much more powerful environment for both interactive use and programming.

Bash-specific Features

This section details a few of the features which make Bash unique. Most of them provide improved interactive use, but a few programming improvements are present as well. Full descriptions of these features can be found in the Bash documentation.

Startup Files

Bash executes startup files differently than other shells. The Bash behavior is a compromise between the csh principle of startup files with fixed names executed for each shell and the sh “minimalist” behavior. An interactive instance of Bash started as a login shell reads and executes ~/.bash_profile (the file .bash_profile in the user's home directory), if it exists. An interactive non-login shell reads and executes ~/.bashrc. A non-interactive shell (one begun to execute a shell script, for example) reads no fixed startup file, but uses the value of the variable $ENV, if set, as the name of a startup file. The ksh practice of reading $ENV for every shell, with the accompanying difficulty of defining the proper variables and functions for interactive and non-interactive shells or having the file read only for interactive shells, was considered too complex. Ease of use won out here.

New Builtin Commands

There are a few builtins which are new or have been extended in Bash.

  • The enable builtin allows builtin commands to be turned on and off arbitrarily. To use the version of echo found in a user's search path rather than the Bash builtin, “enable -n echo” suffices.

  • The help builtin provides quick synopses of the shell facilities without requiring access to a manual page.

  • Builtin is similar to command in that it bypasses shell functions and directly executes builtin commands. Access to a csh-style stack of directories is provided via the pushd, popd and dirs builtins.

  • Pushd and popd insert and remove directories from the stack, respectively, and dirs lists the stack contents.

  • On systems that allow fine-grained control of resources, the ulimit builtin can be used to tune these settings. Ulimit allows a user to control, among other things, whether core dumps are to be generated, how much memory the shell or a child process is allowed to allocate, and how large a file created by a child process can grow.

  • The suspend command will stop the shell process when job control is active; most other shells do not allow themselves to be stopped like that.

  • Type, the Bash answer to which and whence, shows what will happen when a word is typed as a command:

$ type export export is a shell builtin $ type -t export builtin $
type bash bash is /bin/bash $ type cd cd is a function cd () {
    builtin cd ${1+"$@"} && xtitle $HOST: $PWD

Various modes tell what a command word is (reserved word, alias, function, builtin, or file) or which version of a command will be executed based on a user's search path. Some of this functionality has been adopted by POSIX.2 and folded into the command utility.