| Introduction | Getting Started | Using Unix | Your Environment |
The Unix System | Starting a Shell | Shell Functionality | Which Shell
The shell is a command programming language through which the user interacts with the 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:
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.
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.
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:
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.
> 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*'.
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.
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.
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.
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.
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 | |
| Security, Privacy, Legal | |
| Last modified: May 07, 2004 11:20:15 AM CDT | |