Advanced Unix - c shell

Download Report

Transcript Advanced Unix - c shell

Advanced UNIX
The C Shell
• Objectives of these slides:
• Introduce the C Shell
• Concentrate on features not in the Bourne
Shell (but many are in Bash)
1
Background
• Originally part of Berkeley UNIX
• More tolerant of mistakes than Bourne
• e.g. can avoid accidental logouts, overwrites
• Easier to configure
• e.g. alias, history, job control
• Some scripting improvements over Bourne:
• better variables, arrays, expressions
2
• Almost all the good ideas from the C Shell
have been added to Bash:
• e.g. history, aliases, job control, directory stacks
3
Entering & leaving the C Shell
• Check your default shell with ps
• Change shell using chsh or type csh
• Exit with: exit, logout
(control-D maybe)
csh is actually
tcsh on most
Linux versions
4
History
• A list of recently used command lines
(events) that can be reused.
• $ set history = 25
$ set savehist = 20
$ history
(record 25 events)
(remember 20 events
after logout)
(see history list)
5
Using the history list
• $ !!
(execute last event)
• $ !<number>
$ !3
(execute event no. <number>)
• $ !<initial-text> (execute most recent
command that starts with
initial-text)
$ !gcc
$ !loc
6
Bash History
• history
[ number ]
• lists the last number commands!
• Bash supports the same history list features:
• !!, !<number>, !<text>
• Relevant environment variables:
• HISTFILE=/home/ad/.bash_history
• HISTFILESIZE=500
• HISTSIZE=500
7
• In Bash, you can modify the prompt to
include the history number.
• Inside .bashrc:
PS1="\!.\u@\h$ "
\! includes the
history number
8
Alias
• Define new commands by using string
substitution.
• Format:
$ alias new-command executed-command(s)
• e.g.
$ alias ll ls -lg
$ ll
9
Examples
• $ alias ls ls -lg
redefining commands
is okay
• $ alias mi mv -i
• $ alias who ’who ; date’
10
Argument Substitution
• \!^
• \!*
the first argument of the new command
all the arguments of the new command
• $ alias wid ’who | fgrep \!^’
• $ wid igor
is the same as:
$ who | fgrep igor
11
Check your aliases
• $ alias
(list the current aliases)
• $ alias hd
(check hd alias)
• $ unalias hd
(cancel hd alias)
• $ \ls
(use original meaning of ls)
12
Bash Alias
• Bash alias works the same way at the
command line as in csh:
alias, unalias, \command
• Defining an alias in .bashrc is different:
alias name = value
• alias ls='/bin/ls -F'
• alias ll='ls -l'
• alias h="history 30"
13
• Aliases that require multiple commands or
arguments are defined as functions:
sgrep()
{
ps aux | grep $1 | grep -v grep
}
cs()
{
cd $1
ls
}
14
Job Control
• Move commands between foreground
and background; suspend commands.
• Each background job has a PID and a
job number.
15
Example
• $ spell glossary > glossary.out &
[1] 26025
$ date &
[2] 26028
Fri Jun 6 16:56:11 GMT+7 2000
[2] Done
date
$ gcc big.c &
[2] 26041
16
• $ jobs
[1] - Running
[2] + Running
spell glossary.out > glo
gcc big.c
• Other status messages:
• Stopped
• Stopped (tty input)
• Done
17
Background to Foreground
• $ fg %job-number
• Example:
$ fg %2
18
Foreground to Background
• $ control-Z
(suspends job and puts it
into the background)
• $ bg
(resumes the job)
• $ bg %job-number
(resumes job-number)
19
Stopping
• $ stop %job-number
• $ kill %job-number
(kills job-number)
• A job stopped for tty input must be brought
to the foreground (with fg).
20
State Change
• The C Shell prints a message at the next
prompt when the state of a job changes.
• Use notify to make the shell report a
change immediately:
$ notify %job-number
21
Home Directory Short Forms
• ~
(your home directory)
• ~name
(home directory of name)
e.g. ~ad
• Use:
$ cp idea.txt ~
$ ls ~ad/teach
22
Filename Completion
• $ set filec
(‘switch on’ file completion)
• $ cat trig1A
$ cat trig1A.txt
<press esc>
23
Control-D for help
• $ ls h*
help.hist
help.text
sometimes <tab>
help.trig.01
• $ cat h
<press esc>
$cat help. <beep> <press control-D>
help.hist help.text help.trig.01
$ cat help.
24
Directory Stacks
• Store a list of directories you are using
on a stack.
• Switch between directories by
referring to the stack.
cops_104
adv-unix
~
25
• $ pwd
/home/ad/
$ pushd ~/teach/adv-unix
~/teach/adv-unix
~
push the directory
onto the stack
and do a cd
$ pwd
/home/ad/teach/adv-unix
$ pushd ~/cops_104
~/cops_104
~/teach/adv-unix
~
$ pwd
/home/ad/cops_104
cops_104
adv-unix
~~
26
Change directories quickly
push the top directory
down and do a cd
• $ pushd
~/teach/adv-unix
~/cops_104
~
$ pwd
/home/ad/teach/adv-unix/
adv-unix
cops_104
~
27
push the top directory
down and do a cd
• $ pushd
~/cops_104
~/teach/adv-unix
~
$ pwd
/home/ad/cops_104
cops_104
adv-unix
~
28
Popd
• $ popd
~/teach/adv-unix
pop the top directory
and cd to the new top
~
$ pwd
/home/ad/teach/adv-unix/
adv-unix
~
29
Other Stack Commands
• $ dirs
(lists the directories on
the stack)
• $ pushd +number
• move the directory in position number to the
top (0), and cd to that directory
• the stack is numbered 0, 1, 2, ...
30
• $ popd +number
• pop off the directory at position number
• if number is not 0 then there is no change to
the present directory
31
Variables ( 4 types)
String Variables
Numerical Variables
Special Forms of User Variables
Shell Variables
32
String Variables
• $ set name = fred
(include spaces in
older csh's)
$ echo $name
fred
$ set
(list set variables)
$ unset name
(delete name var)
33
setenv (environment vars)
• $ setenv name fred
$ echo $name
fred
$ setenv
$ unsetenv name
no =
makes the variable visible to any
scripts called from the shell (or from the
script containing the setenv).
• setenv
34
Arrays of String Vars
• $ set colours = (red green blue orange)
$ echo $colours
red green blue orange
$ echo $colours[3]
blue
$ echo $colours[2-4]
green blue orange
35
• $ set shapes = (’’ ’’ ’’ ’’ ’’)
$ echo $shapes
$ set shapes[4] = square
$ echo $shapes[4]
square
36
Braces
• Use {...} to distinguish a variable from
surrounding text.
• $ set prefix = Alex
$ echo $prefix is short for {$prefix}ander.
Alex is short for Alexander.
• Can also write $prefix{ander}
37
Numeric Variables
• Use the @ command for variables holding numbers.
• $
$
0
$
$
7
$
$
0
@ count = 0
echo $count
(or set count = 0)
@ count = ( 5 + 2 )
echo $count
@ result = ( $count < 5 )
echo $result
Remember
the space
after the @
38
• $ @ count = $count + 5
$ echo $count
12
• Could write:
$ @ count += 5
• $ @ count++
$ echo $count
13
39
Operators
• Most of the C numerical operators:
•
•
•
•
Arithmetic:
Relational:
Logical:
etc.
+ - * / %
> < >= <= != ==
&& || !
40
Arrays of Numeric Vars
• $ set ages = (0 0 0 0 0)
$ @ ages[2] = 15
$ @ ages[3] = ( $ages[2] + 4 )
$ echo $ages[3]
19
$ echo $ages
0 15 19 0 0
41
Bourne Shell Equivalents
• The Bourne Shell only has string variables.
• It uses expr to switch string variables into
numbers:
$ number=5
(Bourne)
$ number=‘expr $number + 2‘
$ @ number = 5
$ @ number = $number + 2
(C Shell)
42
Special Forms of User Variables
• $#VAR
(returns number of elements
in VAR array)
• $?VAR
(returns 1 if VAR is declared;
0 otherwise)
43
• $ set days = (mon tues wed thurs fri)
$ echo $#days
5
$ echo $?days
1
days is declared
$ unset days
$ echo $?days
0
days is not declared
44
Shell Variables
• Shell variables can be initialized in three
ways:
• by the shell
• by the environment
• by the user with set or setenv
45
• There are two types of shell variable:
• shell variables that take values;
• shell variables that act as switches
• they have the value 0 or 1
46
Shell Vars that take Values
• $argv[0] or $0
• $argv[1] or $1
command name
first argument
of command
• Also $2,$3,...
• no upper limit; no need for shift
• $argv[*] or $*
• $#argv
array of all arguments
number of arguments
47
• $HOME
pathname to user’s
home directory
• $PATH
array of pathnames
to commands
$ setenv PATH (/usr/bin /usr/ucb /bin ~/bin)
• $status
exit status of last command
• etc...
48
Shell Vars that act as Switches
• $filec
turns on file completion
• $ignoreeof
disables ctrl-D as logout
• $noclobber
stops file overwriting with >
• $notify
immediate notification about
background job changes
• etc...
Use:
$ set ignoreeof
49
Automated Scripts
• At login, the C Shell executes a range of
scripts automatically:
• /etc/csh.login, /etc/csh.cshrc
• .login in your home directory
• .cshrc in your home directory
• At logout, it executes:
• /etc/csh.logout
• .logout in your home directory
50
• When a shell script is called, the shell will
execute the cshrc scripts first.
• The cshrc scripts are also executed
whenever a new window is created in a XWindows session.
51
Examples
• $ cat .login
setenv TERM vt100
stty erase ‘^X’ kill ‘^U’ -lcase -tabs
echo “This is who is on the machine:”
who
52
Only set is needed
(not setenv), since
.cshrc is executed at
the start of every script.
• $ cat .cshrc
set noclobber
set ignoreof
set history = 100
set prompt = “! % “
set PATH = (/usr/bin /usr/ucb /bin ~/bin)
alias h history
alias ll ls -lg
53
• $ cat .logout
echo Switch off the air-conditioner
sleep 10
54
Script Programming
Executing a C Shell Script
Branching
Looping
Recursion
Interrupt Handling
55
Executing a C Shell Script
• Put #!/bin/csh as the first line
• may need #!/bin/csh -f to switch off the
default initial execution of the cshrc scripts
• Or execute:
$ csh script
• Or make csh your default shell.
56
Branching
• if-then
• File Test Expressions
• Switch
57
if-then
• Formats:
if (expression) then
commands
endif
if (expression) then
commands
else
commands
endif
58
if (expression) then
commands
else if (expression) then
commands
:
else
commands
endif
59
• $ cat if_else1
#!/bin/csh -f
# Set class depending on argument value
set number = $argv[1]
if ($number < 0) then
@ class = 0
else if ($number >= 0 && $number < 100) then
@ class = 1
else if ($number >= 100 && $number < 200)then
@ class = 2
else
@ class = 3
endif
echo The number $number is in class $class
60
Usage
• Due to the #!/bin/csh line, the script can be
executed from the Bourne/Bash command
line:
$ if_else1 55
The number 55 is in class 1
$
61
File Test Expressions
• These occur in the expression part of ifthen and other control structures.
-d
-f
-e
-z
file
file
file
file
-r file
-w file
-x file
file
file
file
file
is a directory
is a file
exists
is 0 bytes long
file is readable
writable
executable
62
Switch
• Format:
switch (string variable)
case pattern:
commands
breaksw
case pattern:
commands
breaksw
:
default:
commands
breaksw
endsw
63
Example
Usage:
$ switch_1 yes
Argument 1 is yes
$
• $ cat switch_1
#!/bin/csh -f
# See if first argument is yes or no.
# Deal with a mix of upper and lower case.
# Does argv[1] exist?
if ($#argv == 0) then
echo “Usage: switch_1 [yes | no]”
exit 1
endif
:
64
switch ($argv[1])
case [yY][eE][sS]:
echo Argument 1 is yes
breaksw
case [nN][oO]:
echo Argument 1 is no
breaksw
default:
echo Argument 1 is neither yes or no
breaksw
endsw
65
Looping
• Foreach
• While
66
foreach
• Format:
foreach loop-index (argument-list)
commands
end
67
Example 1
Usage:
$ refname CPP C
• $ cat refname
#!/bin/csh -f
# Usage: rename arg1 arg2
#
# Changes the string arg1 to arg2
# in the filenames of every file in
# the current working directory.
if ($#argv != 2) then
echo Usage: refname arg1 arg2
exit 1
endif
:
68
foreach i (‘ls‘)
set newname = ‘echo $i | sed s/$1/$2/‘
mv $i $newname
end
VERY
DANGEROUS
The text in i
that matches $1 is
changed to $2
69
Example 2
Usage:
$ foo-six a b c
• $ cat foo-six
#!/bin/csh -f
# Assign up to 6 command line args
# to the buffer array. Execute foo
# with buffer as its arguments
set buffer = (0 0 0 0 0 0)
@ count = 1
if ($#argv > 6) then
echo “Usage: foo-six [up to 6 args]”
exit 1
endif
:
70
expands to $argv[0],
$argv[1], etc.
foreach arg ($argv[*])
set buffer[$count] = $arg
@ count++
end
echo There were $count arguments
exec foo $buffer[*]
exit 0
expands to $buffer[0],
$buffer[1], etc.
VERY
DANGEROUS
71
while
• Format:
while (expression)
commands
end
72
Example
Usage:
$ while_1 20
The sum is 210
• $cat while_1
# Sum the numbers between 1 and
# the value in argv[1]
@ limit = $argv[1]
@ index = 1
@ sum = 0
while ($index <= $limit)
@ sum += $index
@ index++
end
echo The sum is $sum
73
Recursion
• The script cppc visits every directory below
the one supplied as its argument and
renames any files ending with “.CPP” to end
with “.c”
• e.g.
foo.CPP --> foo.c
• usage: $ cppc code/
• cppc
could be implemented with find
74
cppc
#!/bin/csh -f
# cppc “ replace all .CPP extensions with .c
if ($#argv != 1) then
echo “Usage: $0 directory”
exit(1)
endif
VERY
DANGEROUS
foreach file ($1/*)
# files in directory
if (-f $file) then
if ($file:e == ‘CPP’) then
mv $file $file:r.c
echo Modifying $file to $file:r.c
endif
else if (-d $file) then
$0 $file
# recursive call
endif
end
75
Notes
• Pulling apart a filename that has an extension
(e.g. foo.bar)
$ set var = foo.bar
$ echo var:r
foo
# name without extension
$ echo var:e
bar
# just the extension
76
A Standard Shape
• Most recursive scripts have the
following 'shape':
foreach file ($1/*)
# files in
directory
if (-f $file) then
# do something to the file
else if (-d $file) then
$0 $file
# recursive call
endif
end
77
Title Words in Web files
• The wtitle script examines each “.html” file in
the directories below the one supplied as its
argument.
• If outputs the title words on each Web page
• e.g
if it sees:
<title>My Home Page</title>
then it prints:
My
Home
Page
78
wtitle
#!/bin/csh -f
# wtitle: list the title words in HTML files
if ($#argv != 1) then
echo Usage: $0 directory
exit(1)
endif
foreach file ($1/*)
if ((-f $file) && ($file:e == “html”)) then
grep -i title $file |
\
awk -F\> ’{print $2}’ |
\
awk -F\< ’{print $1}’ |
\
tr ’ ’ ’\n’ | tr ’A-Z’ ’a-z’
else if (-d $file) then
$0 $file
# recursive call
endif
end
79
Notes
• grep -i title $file
gets a title tag line:
<title>My Home Page</title>
separates the line
using ‘>‘ and prints the second part:
• awk -F\> ’{print $2}’
My Home Page</title>
separates the line
using ‘<‘ and prints the first part:
• awk -F\< ’{print $1}’
My Home Page
80
Usage
• $ wtitle caine/
michael
caine
caine
picture
caine
:
sorted and
duplicates
removed
• $ wtitle caine/ | sort | uniq
caine
michael
picture
:
81
Interrupt Handling
• Not as good as Bourne
• only interrupt is supported
• the control flow is hard to understand
• much improved in tcsh
• Format:
onintr label
• The script must have a line:
label:
82
Usage:
• $ cat onintr_1
#!/bin/csh -f
onintr close
while (1)
echo Program is running.
sleep 2
end
$ onintr_1
Program is running
Program is running
:
:
End of Program
ctrl-C
typed
close:
echo End of Program
83
The End
• Practice writing scripts in different shells
• You will figure out that environments
support a subset of commands from the
others.
• Bourne is still the default and most popular
for most linux distributions.
84