Defining and redefining commands

Shell aliases and shell functions

In bash, an alias can be defined using the following syntax:

    alias ALIASNAME=COMMANDSTRING

e.g.:

    alias rm='rm -i'

Once this alias has been defined, you can type rm at the shell prompt, and then the shell will expanded it to rm -i and execute it. To remove an alias, use:

    unalias ALIASNAME


Also shell functions can be defined by users in most shells (except csh/tcsh). Shell aliases and functions play similar roles, however functions can take parameters while aliases cannot (csh/tcsh aliases are an exception -- they can take parameters, and for that reason functions are neither needed nor available in csh/tcsh).

The alias or function definition is remembered by the current shell, but it is not inherited by its subshells, and it will not persist after the current shell terminates. To define an alias or function for all the interactive bash shells, place its definition in the files which initialize them (notice that for bash, interactive login shell and the interactive non-login shells are initialized from different files.)  Aliases and functions defined in bash initialization files will, of course, not work in other shells (such as tcsh or zsh); you would need to define them as well  in initialization files of tcsh and zsh, using tcsh and zsh specific syntax; a better solution is suggested later in this section.

UNIX utilities

UNIX utilities, such as /bin/ls are just executable files. Most commonly such files are either compiled C programs or Perl or shell scripts, but other languages can be used as well. For defining new UNIX utilities, Perl is preferred by system administrators over C and shell languages, because of its simplicity and the wide range of constructs which include pattern matching and file, process and network operations.

If you wish to define a command to be used under different shells, rather than defining an alias or function for every type of shell, create a UNIX utility, place it in ~/bin and add ~/bin to your $PATH.  

Every UNIX utility is executed as a subprocess; for this reason a UNIX utility cannot change the state of the parent shell. This implies that a UNIX Utility cannot be used to perform operations such as cd, umask or setting values of environment variables.

As shell built-in always overrides a UNIX utility with the same name, UNIX utilities cannot be used to redefine shell built-ins; when overriding a shell built-in is needed, use an alias or a shell function.

Shell built-in commands

Certain commands are executed by the shell without using a subprocess. In most cases such commands change the state of the current shell.  For instance, when you type cd DIR, the shell will remember DIR as your present working directory and will subsequently interpret relative paths as starting at DIR; when you type umask VALUE, the shell process changes the value of its umask attribute; when you  set values of shell  variables or environmental variables the shell remembers these values.

Summary of types of commands

In summary, a command typed at the shell prompt, can refer to any of the following:

To check how a particular command COMMAND is defined, enter in the bash shell:

    type -a COMMAND

When you type a command the shell performs a number of expansions, which have an effect of checking if:

  1. it is a path to an executable file,
  2. otherwise, if it is a shell alias, 
  3. otherwise, if it is a keyword (such as "if", "for", "function"),
  4. otherwise, if it is a shell function,
  5. otherwise, if it is a shell built-in,
  6. otherwise, it is a name of an executable file in a directory listed in the value of environment variable $PATH (Directories listed in $PATH are checked in their order; the search stops after the first match.)

These checks are performed in the order given above -- this implies the precedence principle in the next subsection.
 

Defining and redefining commands

Defining and redefining commands is based on the following general principles:

  1. Precedence principle:
  2. Subprocess principle:
    Every UNIX utility, even a shell script, is executed as a subprocess and therefore cannot change the state of its parent shell.

 

Aliases and functions defined in bash initialization files will, of course, not work in other shells (such as tcsh or zsh); you would need to define them as well  in initialization files of tcsh and zsh, using tcsh and zsh specific syntax -- for that reason the system administrator who wishes to provide new commands to users of all shells may prefer to define them as UNIX utilities -- this will be possible in all cases except when the command is supposed to change the state of the current shell (as it is with cd, umask or setting values of environment variables) or to override a shell built-in.