UNIX shells

When you login to UNIX/Linux, you see a prompt ending in % or $. This is a prompt of a shell. The shell is an intermediary between the user and the kernel of the operating system. The shell processes your commands and makes requests on your behalf to the operating system. The shell loops endlessly displaying a prompt, reading a command from the input, and interpreting/executing the command. Some commands can be executed by the shell without any participation of the operating system -- these are called shell commands. For instance

echo 'Hello Ann'

pwd

are shell commands. On the other hand, ls (if not aliased to some shell command) is not a shell command, it is a UNIX command which refers to an executable file /usr/bin/ls. In the case of complex commands involving pipes (|) and I/O redirection (>) the shell makes appropriate requests to the operating system. These requests are made by means of so called system calls. System calls are available in languages such as C, C++, Perl.

UNIX/Linux users choose one shell  from among many. (This should not be surprising: if you can chose from among many text editors, why not shells.) Here are seven most popular shells.

sh (Bourne shell) csh (C shell)
/ \ |
ksh (Korn shell)        |       |
| | |
zsh (Z shell) bash tcsh (TC shell)

bash, bash2, ksh (Korn shell) and zsh are extensions of sh (Bourne shell).  zsh is a greatly improved version of ksh. For all practical purposes one can think that tcsh is an extension of csh with only interactive features added. The language of csh and tcsh is distinctly different from the language of sh.

Here is our (subjective) perception of the quality of these shells. They are listed with the best on the top.

Shells which are available on your computer, are listed in the file /etc/shells. Every user has a default shell which is listed in the file /etc/passwd. The default shell is the first shell the user gets after the login. To change the default shell, use the chsh command. If you wish to try a particular shell without changing the default, just start it by typing its name, for instance, whatever your current shell you can type zsh to start the Z shell; after you finished, type exit to terminate zsh and to return to your original shell. 

At a basic level the syntax of commands in all the shells is the same; the difference shows only in advanced commands. The diagram above shows how certain shells extend others. sh and csh are most basic, they agree in the syntax of most basic commands but use a different syntax for advanced commands. ksh extends sh: every sh command is valid also in ksh. zsh extends ksh. bash extends sh. tcsh extends csh. Shells which are not on the same branch in our diagram are not compatible: there exits commands in the first one which are not valid in the second one and vice versa. For instance ksh and bash are not compatible, and the same about tcsh and bash. zsh, bash and tcsh are most advanced among the seven shells above. In author's subjective opinion zsh is the best among them, tcsh comes second and bash third. 

In every shell built-in commands and constructs (such as wildcards, echo, pwd, |, >) are part of a broader programming language with variables, conditional statements, loops, etc. Every statement of this language can be executed in the interactive mode. 

Here is an example of a loop in the language of csh/tcsh.

    % foreach dir (*)
          cd $dir
          cat *.txt > summary.doc
          cd ..
      end

Here is an example of a loop in the language of bash.

     $ for dir in *
       do
           cd $dir
           cat *.txt > summary.doc
           cd ..
       done

(This command uses a wildcard * which will expand to a list of items in the current directory. The parameter dir will go over this list. We will go to every directory dir, concatenate all the files with extension .txt into a new file summary.doc and come back to the original directory to continue the loop.)

Shell variables, and programming constructs such as loops are seldom used in the interactive mode. The predominant use is in programs, called shell scripts

Here is an example of a C shell script. The code is stored in an executable text file called get-info.

    #!/bin/csh
    date # Display date and time
    who  # Display info about users who are currently logged in

Every csh script must start with #!/bin/csh and this cannot be proceeded by any spaces or blank lines. This text tells the system that the remaining part of the file is to be processed by /bin/csh. Note that the script can be created in any text editor, but you must remember to make the resulting file executable by means of chmod command. A script starting with #!/bin/csh will work independently of what is user's current or default shell; the only thing it requires is that /bin/csh exists.

Here is an example of a bash shell script. The code is stored in an executable text file called get-info.

#!/bin/bash
date   # Display date and time
who    # Display info about users who are currently logged in

Every bash script must start with #!/bin/bash and this cannot be proceeded by any spaces or blank lines. This text tells the system that the remaining part of the file is to be processed by /bin/bash. Note that the script can be created in any text editor, but you must remember to make the resulting file executable by means of chmod command. A script starting with #!/bin/bash will work independently of what is user's current or default shell; the only thing it requires is that /bin/bash exists.

Shell scripts
Every shell, besides interactive features and built-in commands, has a language equipped with conditional and loop constructs, etc. These constructs are seldom used in the interactive mode -- they are commonly used in programs, called shell scripts which are stored in files. 

To create a bash script, place the following as the very first thing in a file:

#!/bin/bash

There must be no blanks or blank lines before these symbols. Scripts meant for other shells begin with #!/bin/csh,   #!/bin/sh, etc. In general, if an executable text file starts with #!PATH, the system will treat PATH as a path to an interpreter which can execute the command in the file; for instance Perl scripts start with #!/bin/perl. 

There are almost no differences between tcsh and csh scripts. Both csh and tcsh allow the -f option while invoked as a script interpreter; with this option the shell which interprets the script will not read initialization files, such as ~/.cshrc. 

You can find examples of shell scripts in directory /usr/local/custom/bin. See emacs, netscape, swap. Although small shell scripts are easy to write, bigger or more complex tasks benefit from using a richer and more flexible language; most system administrators now use Perl scripts instead of shell scripts. 

When you invoke a shell script at the prompt of a shell:

interactive_shell%  shell_script

the interactive shell will fork and spawn a non-interactive child shell which will execute the commands from the script file. This implies that the interactive shell will remain unaffected by the commands in the script. For instance a cd command in a script will change the directory only for the non interactive shell which executes these commands but not for the original interactive shell. Similarly, the original interactive shell will remain unaware of any aliases and shell or environment variables defined in a script. If you wish to redefine a command which affects the state of the current shell, such as cd, this cannot be done by a shell script or a UNIX utility -- the only way is through an alias or shell  function. 

Aliases are also useful while defining commands with names which have a special meaning to the shell, such as . (the period).

Shell variables

          $ echo $VARIABLENAME     -- see the value of VARIABLENAME

$ set    -- see the list of all the shell variables and environment variables defined

$ VARIABLENAME=VALUE    -- define/redefine a shell variable

$ unset VARIABLENAME  -- remove a variable.

Shell variables are not inherited unless they are turned into environment variables by means of the export command. Although it is not required, customarily names of shell variables are in lowercase.

Shell scripts, in general

The language of every shell is rich enough to construct programs which can be stored in files. They are called shell scripts.  Shell scripts are commonly used for automating system administration tasks.

To create an proper perspective let us mention that in 1990's Perl and Python scripting languages were introduced, and proved to be more convenient and more versatile tools for system administration than shell languages. However shell languages are still important for the following reasons:

The following holds for all major shell languages (sh, ksh, bash, zsh, csh, tcsh):

Next see: bash or csh/tcsh