Fermilab

Unix at D0

Introduction Getting Started Using Unix Your Environment

The UNIX Shell

The Unix System | Starting a Shell | Shell Functionality | Which Shell

Shell

The shell is a command programming language through which the user interacts with the system.

The UNIX system

To understand better the concept of a shell it is necessary to know a bit about the UNIX system architecture. UNIX system consists of two groups of programs:

the kernel
This is the real operating system. It is loaded into memory at the boot time. Typically, user never interacts with the kernel directly.
the utilities
this are the programs which are stored on disk. When invoked they are loaded into memory by kernel.

It is important to understand that the shell is an utility, from the UNIX point of view. It is run in the user mode and does not have any system privileges.

Starting a shell

A shell is started by a login process. What shell? It is defined by the last field of an entry in the /etc/passwd file. For example:

ls /etc/passwd

 guest:*:998:998:Guest Account:/usr/people/guest:/bin/csh
 adm:*:5:3:Accounting Files Owner:/var/adm:/bin/sh
 demos:*:993:997:Demonstration User:/usr/demos:/bin/my_demo
 auditor:*:11:0:Audit Activity Owner:/auditor:/bin/tcsh

When a user guest (adm, demos, auditor) logs in, the login process will invoke the program /bin/csh (/bin/sh, /bin/my_demo, /bin/tcsh) and transfer the control to it. The invoked program takes over the control and provides all user interface. It shows its readiness to listen to you by displaying a prompt at your terminal.

At any point in your session you may invoke another copy of the shell, or even different shell.

In such a case the execution of the original shell is suspended (shell is put to sleep) and the new shell take over the control. Once you quit the new shell, the old one wakes up and assumes control of your session.

In general, when you execute a script, a new shell is created and the script is invoked in the new shell. When the script terminates, the new shell terminates too and the control is returned to the original shell.

Note: the above paragraph explains why an execution of a script does not affect the parent shell environment. (for the exception of this rule see source)

Notice also that the invoked script runs in general in a different environment(new shell) than the one in which it was invoked.

Shell's Functionality

Everything you type at the terminal is interpreted (after you hit return key) by the shell and is causing some action to be taken. Shell provides the following functions:

program execution
when you type a line and hit the return key, the shell tries to interpret your line as,

program-name arguments

where the program name and arguments are separated by (any number of) spaces or tabs.

If the program invoked is one of the shell commands (cd, pwd or echo, the shell executes it, otherwise the shell invokes the UNIX kernel to initiate the execution of the program.

Parsing of the command line is done by the shell and arguments are passed to the program, therefore any information about the whitespaces is lost. For example:

      myprog   arg1      arg2 arg3      arg  4
      
will initiate the execution of myprog and pass to it as arguments
      arg1 arg2 arg3 arg 4
      
To prevent parsing the string by shell and pass the meaningful blanks as and part of the argument string - enclose it in quotes.

Variable and File Name Substitution
Shell allows you to define variables. They can be referenced by prefixing them with a $ sign.
          > set num = 10
          > echo $num
          10
          >
      
Shell scans the command line for file name substitution characters, and performs the required substitution before invoking the requested program. Suppose we have two files
      > ls
      file1
      file2
      >
      
Invocation
      > myprog  file*
      
will cause the shell to expand file* to file1 file2 and to start program myprog with two arguments: file1 file2. The two lines:
      > myprog file*

      > myprog file1 file2
      
are totally equivalent from the myprog point of view. In particular, notice that in the first example the program myprog never 'sees' the string 'file*'.

I/O redirection

Under UNIX, all input/output is performed through files. When a shell command is executed, three files are opened automatically and associated with the command:
         File descriptor          Name             Description
         ---------------          ----             -----------
              0                   stdin            Keyboard
              1                   stdout           Terminal
              2                   stderr           Terminal
     

By default, all programs accept input from stdin, write output to stdout and write error messages to stderr. These defaults can be overridden using special I/O redirection characters: < and >. Thus program myprog invoked via:

     myprog < my_input > my_output
     
will read its input data from the file my_input and write its output to my_output, whereas
     myprog
     
would accept input from the keyboard, and send output to the terminal.

Pipeline Hookup

UNIX provides a very powerful mechanism of interprocess communication via pipes. When the shell receives a line invoking several processes separated by a pipe symbol '|', it starts the requested processes and establishes communication between them.

Each process in the pipeline reads from its standard input and writes to its standard output. The standard input and standard output from each adjacent command is connected by a pipe special file. For example:

       ls | grep .f | wc -l
      
will count number of *.f files in the current directory: output of ls command is searched for '.f' string, and wc -l counts the resulting lines.

Environment Control

Shell maintains several variables defining the programming environment, as well as provides commands to customize the environment (setenv, unsetenv). Do:
      printenv | more
      
to see your current environment. Environmental variables are usually defined in .cshrc (or .kshrc, etc...) file. They can be modified, or new variables can be added during the session. It is important to remember that such modifications are propagated to daughter shells, but changes of the environment in the daughter shell do not affect the parent shell. For example, let env.csh be:
       #! /bin/csh -f
       #!
       #!   check the environment
       #!

       setenv DAUGHTER "I'm a daughter shell"
       echo $DAUGHTER

       echo $PARENT
       
than the following might happen:
       > setenv PARENT "I'm a parent shell"
       > echo $PARENT
       I'm a parent shell
       > env.csh
       I'm a daughter shell
       I'm a parent shell
       > echo $DAUGHTER
       DAUGHTER: Undefined variable.
       

Interpreted Programming Language

the shell has its own programming language. This language is interpreted, rather than compiled. It means that every statement is analyzed, one line at a time, and then executed.

As most interpreted languages, the shell programs are usually easy to write and to debug, but not very efficient.

Different shells differ somewhat in the syntax and in the functionality provided, but all of them support local variables (sometimes arrays), looping constructs, decision-making statements, as well as a variety of built-in commands and functions.

Which shell?

There are several shells available. Whereas the choice of a shell to work with is mostly a matter of a personal preference, it is worth mentioning that at the present time csh and tcsh are the most popular at D0.

The tcsh is a superset of csh, and it offers VMS-style editing of the commands using arrrow keys.

d0web-support@fnal.gov
Bar
Security, Privacy, Legal Fermi National Accelerator Laboratory
Last modified: May 07, 2004 11:20:15 AM CDT