lecture 8: shell. shell the shell acts as an interface between the user and the kernel. when the...
Post on 19-Dec-2015
216 views
TRANSCRIPT
Lecture 8:SHELL
SHELL
• The shell acts as an interface between the user and the kernel. When the user logs in, the login program checks the username and password, and then starts another program called the shell. The shell is a command line interpreter (CLI). It interprets the commands the user types in and arranges for them to be carried out. The commands are themselves programs: when they terminate, the shell gives the user another prompt.
Shell (cont.)• The user can customise his/her own shell and users can use
different shells on the same machine. Staff and students in the university have the tcsh shell by default
• By typing part of the name of a command, filename or directory and pressing the [Tab] key, the tcsh shell will complete the rest of the name automatically. If the shell finds more than one name beginning with those letters you have typed, it will beep, prompting you to type a few more letters before pressing the tab key again.
• The shell keeps a list of the commands you have typed in. If you need to repeat a command, use the cursor keys to scroll up and down the list or type history for a list of previous commands.
Command line structure
• The simplest command is a single word, usually naming a file for execution:
$ whoyou tty2 Sep 28 07:51jpl tty4 Sep 28 08:32
• A command usually ends with a newline, but a semicolon “;” is also a command terminator
$ date ; whoWed Sep 28 09:07:23 EDT 1983you tty2 Sep 28 07:51jpl tty4 Sep 28 08:32
$ date ; whoWed Sep 28 09:07:23 EDT 1983you tty2 Sep 28 07:51jpl tty4 Sep 28 08:32$ date ; who | wc3 16 89$ (date ; who) | tee save | wc3 16 89$ cat saveWed Sep 28 09:07:23 EDT 1983you tty2 Sep 28 07:51jpl tty4 Sep 28 08:32$ wc < save3 16 89
Command line structure (cont.)
Command line structure (cont.)• Another command terminator is the ampersand &. It is exactly like the semicolon or
newline, except that it tells the shell not to wait for the command to complete. Typically is used to run a long-running command “in the background” while you continue to type interactive commands:
$ long-running-command &5273$ • Given the ability to group commands, there are some more interesting uses of background
processes. The command sleep waits the specified number of seconds before exiting$ sleep 5$$ (sleep 5; date) & date5278Wed Sep 28 09:07:23 EDT 1983 //Output from second date$ Wed Sep 28 09:07:23 EDT 1983 //Prompt appears, then date 5 sec later
$ (sleep 300; echo Tea is ready) & Tea will be ready in 5 minutes5291A HANDY REMINDER MECHANISM!
Command line structure (cont.)• The & terminator applies to commands, and since pipelines are commands you do not need
parentheses to run pipelines in the background:$ pr file | lpr &• Arranges to print the file on the line printer without making you wait for the command to
finish. Parenthesising the pipeline has the same effect, but requires more typing:$ (pr file | lpr) &• Most programs accept arguments on the command line, such as “file” (an argument to “pr”)
in the above example. Arguments are words separared by blanks and tabs, that typically name files to be processed by the command, but they are strings that may be interpreted any way the program sees it. The various special characters interpreted by the shell, such as <, >, |, ; and & are not arguments to the programs the shell runs. They instead control how the shell runs them:
$ echo Hello > junk Tells the shell to run echo with the single argument Hello and place the output in the file
junk. The string > junk is not an argument to echo; it is interpreted by the shell and never seen by echo. In fact, it need not be the last string in the command:
$ > junk echo Hello Is identical but less obvious!
Try this at the lab:
• What are the differences among the following three commands?
$ cat file | pr
$ pr <file
$ pr file
(Over the years the redirection operator < has lost some ground to pipes; people seem to find “cat file |” more natural than “<file”).
Metacharacters• The shell recognises a number of other characters as special; the most commonly used is the
asterisk “*” which tells the shell to search the directory for filenames in which any string of characters occurs in the position of the “*”:
$ echo * //is a poor facsimile of ls. (ls looks at file names beginning with dot as well)$ ls.profilejunktemp$ echo *junk temp• Characters like * that have special properties are known as METACHARACTERS$ echo “***”***$ echo “Do not do that”Do not do that& echo ‘hello > world’helloworld
Metacharacters (cont.)• Quotes do not have to surround the whole argument$ echo x’*’yx*y$ echo ‘*’A’?’*A?$ ls x*yx*y not found Message from ls, the file does not exist$ > xyzzy Create xyzzy$ ls x*yxyzzy File matches xyzzy$ ls ‘x*y’x*y not found$ echo abc\> def\> ghiabcdefghi
Metacharacters> Prog >file direct standard output to file
>> Prog >>file append standard output to file
< Prog <file take standard input to file
| p1|p2 connect standard output of p1 to standard input of p2
<< str Here document: standard input follows, up to next str on a line by itself
* Match any string of zero or more characters in filenames
? Match any single character in filenames
[ccc] Match any single character from ccc in filenames; ranges like 0-9 or a-z are legal
; Command terminator; p1; p2 does p1 ,then p2
& Like ; but does not wait for p1 to finish
‘…’ Run sommands in …; output replaces ‘…’
(…) Run commands in … in a sub-shell
{…} Run commands in … in current shell (rarely used)
$1, $2 etc $0…$9 replaced by arguments to shell file
$var Value of shell variable var
${var} Value of var, avoids confusion when concatenated with text;
\ \c take character c literally, \newline discarded
# If # starts word, rest of line is a comment
var=value Assign to variable var
p1 && p2 Run p1; if successful, run p2
p1 | |p2 Run p1; if unsuccessful run p2
‘…’ Take.. Literally
“…” Take literally after $, ‘…’ and \ interpreted
Creating new commands• Given a sequence of commands that is to be repeated more than a few times, it
would be convenient to make it into a “new” command with its own name, so you can use it like a regular command
$ who | wc -1• The first step is to create an ordianry file that contains “who | wc –l”
$ echo ‘who | wc –l’ > nu$ cat nuwho | wc –l
$ sh nu //this child shell is called sub shell$ chmod +x nu$ nu• Users of nu from now on cannot tell, just by running it, that you implemented it in
this easy way!
Creating new commands (cont.)• As it stands, nu works only if it is in your current directory. To make nu part of
your repertoire regardless of what directory you are in, move it to your private bin directory, and add /osr/you/bin to your search path:
$ pwd/usr/you
$ mkdir bin$ echo $PATH:/usr/you/bin:/bin:/usr/bin
$ mv nu bin$ ls nunu not found
$ nu4
There are other simple commands that you might create this way to tailor your environment to your own taste:
• cs, which echoes the proper sequence of mysterious characters to clear the screen on your terminal (24 newlines is a fairly general implementation)
• what, which runs who and ps-a to tell who is logged on and what they are doing
• where, which prints the identifying name of the UNIX system you’re using – it’s handy if you use sevral regularly
Creating new commands (cont.)
Command arguments and parameters
• Suppose we want to make a program called cx to change the mode of a file to executable:
$ cx nu• Is a shorthand for chmod +x nu. Let’s look at the whole sequence of operations:$ echo ‘chmode +x $1’ > cx$ sh cx cx$ echo echo Hi, there! > hello$ hellohello: cannot execute$ cx hello$ helloHi there!$ mv cx/usr/you/bin$ rm hello
Command arguments and parameters
• With $* added to your repertoire, you can make some convenient shell files, such as lc or m:
$ cd /usr/you/bin
$ cat lc
# lc: count number of lines in files
wc –l $*
$ cat m
# m: a concise way to type mail
mail $*
Command arguments and parameters• Let’s make a directory assistance program, which we’ll
call 411 in honor of the telephone directory assistance number where we live:
$ echo ‘grep $* /usr/you/lib/phone-book’ >411$ cx 411$ 411 jokeDial-a-joke 212-976-3838Dial-a-prayer 212-246-4200Dial santa 212-976-3636
$ 411 ‘dow jones’Grep: can’t open jones
Program output as arguments• The output of any program can be placed in a command line
by enclosing the invocation in back quotes ‘…’:
$ echo At the tone the time will be ‘date’At the tone the time will be Thu Sep 29 00:02:15 EDT 1983
$ mail ‘cat mailinglist’ < letter$ cat mailinglistecho don whr ejs mb
$ cx mailinglist$ mailinglistdon whr ejs mb
Shell variables
• The shell has variables, which are called parameters
$ pwd/usr/you/bin$ dir = ‘pwd’$ cd /usr/mary/birf$ ln $dir/cx$ …$ cd $dir$ pwd/usr/you/bin
Shell variables (cont.)
• The value of a variable is associated with the shell that creates it, and is not automatically passed to the shell’s children
$ x = Hello$ sh$ echo $x$ ctl-d$$ echo $xHello
Shell variables (cont.)• The ‘.’ mechanism should be used to change the value of a variable permanently, while
in-line assignements should be used for temporary changes. Consider the searching /usr/games for commands, with the directory not in your path:
$ ls /usr/games grep fortfortune$ fortunefortune: not found$ echo $PATH:/usr/you/bin:/bin:/usr/bin$ PATH=/usr/games fortuneRing the bell; close the book; quench the candle.$ echo $PATH:/usr/you/bin:/bin:/usr/bin$ cat /usr/you/bin/gamesPATH=$PATH:/usr/games$ .games$ fortunePremature optimisation is the root of all evol – Knutch$ echo $PATH:/usr/you/bin:/bin:/usr/bin:/usr/games
More on I/O redirection• The standard error was invented so that error messages
would always appear on the terminal:
$ diff file1 file2 > diff.outdiff: file2: No such file or directory
• It is also possible to merge the two output streams:
$ time wc ch3.1 > wc.out 2>&1$ cat wc.out931 4288 22691 ch3.1Real 1.0User 0.4Sys 0.3
Shell I/O Redirections
>file Direct standard output to file
>>file Append standard output to file
<file Take standard input from file
p1|p2 Connect standard output of program p1 to input of p2
^ Obsolete synonym for |
n>file Direct output from fiel descriptor n to file
n>>file Append output from fiel descriptor n to file
n>&m Merge output from file descriptor n with file descriptor m
n<&m Merge input from file descriptor n with file descriptor m
<<s Here document: take standard input until next s at beginning of a line; substitute for $, ‘…’, and \
<</s Here document with no substitution
<<‘s’ Here document with no substitution
Looping in shell programs• Looping over a set of filenames is very common, and the shell’s for statement is the only
shell control-flow statement that you might commonly type at the terminal. The syntax is:for var in list-of-wordsdo
commandsdone• For example$ ls ch2.* | 5ch2.1 ch2.2 ch2.3 ch2.4 ch2.5 ch2.6 ch2.7$ for I in ch2.*> do> echo $I;> diff –b old/$I $I> echo> done | pr –h “diff ‘pwd’/old ‘pwd’ “ | lpr &> 3712
$ for i in $*
> do
> chmod +x $1
> done
Is inferior to:
chmod +x $*
Looping in shell programs
Lecture 9:Shell Programming
• Although most users think of the shell as an interactive command interpreter, it is really a programming language in which each statement runs a command.
• This lecture explains the basics of shell programming, but it is not a manual for the shell.
• That is in the manual page sh of the Unix Programmer’s Manual
• A major theme in shell programming is making programs robust so they can handle improper input and give helpful information when things go wrong.
Customising the cal command
• One common use of a shell program is to enhance or to modify the user interface to a program. Consider the cal command:
$ calUsage: cal [month] year$ cal october 1983Bad argument$ cal 10 1983October 1983…
Case statement
• The shell provides a case statement that is well suited for making decisions:
case word in
pattern) commands ;;
pattern) commands ;;
…
esac
• The case statement compares word to the patterns fromtop to bottom, and performs the commands associated with the first, and only the first, pattern that matches. The patterns are written using the shell’s pattern matching rules, slightly generalised from what is available for filename matching. Each action is terminated by the double semicolon ;;. (The ;; may be left off the last case but we often leave it in for easy editing)
Case statement$ cat cal# cal: nicer interface to /usr/bin/cal
case $# in0) set ‘date’; m=$2; y=$6 ;; #no args: use today1) m=$1; set ‘date’; y=$6 ;; #1 arg: use this year*) m=$1; y=$2 ;; #2 args: month and yearesaccase $m injan*|Jan*) m=1 ;;feb*|Feb*) m=2 ;;mar*|Mar*) m=3 ;;
apr*|Apr*) m=4 ;;may*|May*) m=5 ;;jun*|Jun*) m=6 ;;jul*|Jul*) m=7 ;;aug*|Aug*) m=8 ;;sep*|Sep*) m=9 ;;oct*|Oct*) m=10 ;;nov*|Nov*) m=11 ;;dec*|Dec*) m=12 ;;[1-9]|10|11|12) ;; #numeric year*) y=$m; m=“” ;; #plain yearesac/usr/bin/cal $m $y #run the real one$
Shell build in variables
$# The number of arguments
$* All arguments to shell
$@ Similar to $*
$- Options supplied to the shell
$? Return value of the last command executed
$$ Process-id of the shell
$! Process-id of the last command started with &
$HOME Default argument for cd command
$IFS List of characters that separate words in arguments
$MAIL File that, when changed, triggers “you have mail” message
$PATH List of directories to search for commands
$PS1 Prompt string, default ‘$’
$PS2 Prompt string for continued command line, default ‘>’
The first case statement has a couple of tricky lines..
$ date
Sat Oct 1 06:05:18 EDT 1983
$ set ‘date’
$ echo $1
Sat
$ echo $4
06:05:20
$
Shell pattern Matching Rules
* Match any string, including the null string
? Match any single character
[ccc] Match any of the characters in ccc.
[a-d0-3] is equivalent to [abcd0123]
“…” Match … exactly; quotes protect special characters. Also ‘…’
\c Match c literally
a|b In case expressions only, matches either a or b
/ In filenames, matched only by an explicit / in the expression; in case, matched like any other character
. As the first character of a filename, is matched only by an explicit . in the expression
Which command is which?$ cat which# which cmd: which cmd in PATH is executed version 1
case $# in0) echo ‘Usage: which command’ 1>&2; exit 2esacfor i in ‘echo $PATH | sed ‘s/^:/.:/
s/::/:.:/gs/:$/:./s/:/ /g’
doif test –f $i/$1 #use test –x if you canthen
echo $i/$1exit 0 #found it
fidoneexit 1 #not found$
Which command is which?
$ cat which# which cmd: which cmd in PATH is executed version 1
opath=$PATHPATH=/bin:/usr/bin
case $# in0) echo ‘Usage: which command’ 1>&2; exit 2esacfor i in ‘echo $PATH | sed ‘s/^:/.:/
s/::/:.:/gs/:$/:./s/:/ /g’
doif test –f $i/$1 #use test –x if you canthen
echo $i/$1exit 0 #found it
fidoneexit 1 #not found$
While and until loops
for i in list of words
do loop body, $1 set to successive elements of list
done
while command
do loop body executed as long as command returns true
done
until command
do loop body executed as long as command returns value
done
While and until loopswhile sleep 60 until who| grep marydo who| grep mary do sleep 60done done$ cat watchfor
# watchfor: watch for someone to log in
PATH=/bin:/usr/bin
case $# in0) echo ‘Usage: watchfor person’ 1>&2; exit 1esac
until who|egrep “$1”do sleep 60done
$cx watchfor$watchfor youyou tty0 Oct 1 08:01 It works$
Evaluation of Shell Variables
$var Value of var; nothing if var undefined
${var} Same; Useful if alphanumerics follow variable name
${var-thing} Value of var if defined; otherwise thing. $var unchanged
${var=thing} Value of var if defined; otherwise thing. If undefined, $var set to thing
${var?message) If defined, $var. Otherwise print message and exit shell. If message empty, print: var: parameter not set
${var+thing} Thing if $var defined, otherwise nothing
Traps: catching interrupts• The shell build in command trap sets up a sequence of commands to
be executed when a signal occurs
• Trap sequence-of-commands list of signal numbers
0 Shell exit (for any reason, including end of file)
1 Hangup
2 Interrupt (DEL key)
3 Quit (ctl-\; causes program to produce core dump)
9 Kill(cannot be caught or ignored)
15 Terminate, default signal generated by kill(1)
• Kill –9 process-id
THURSDAY 06.02.2003ARTS DAY
LECTURE CANCELLED