UNIX/Linux & C Programming:
Chapter 5: The UNIX Shell
Coverage: [UPE] Chapter 3
Introduction
- shell definition: interface between the user and the operating system
- different shells (targeted toward different uses and applications)
- we are using the Korn (ksh) shell
- ksh is a superset of the Bourne shell
- allows access to prior (history) commands with the
j, k
keys (after <esc>)
- starting and exiting
- ksh creates a new instance of the Korn shell
- $ exit closes the window or logout (equivalent to
<ctrl-d>)
we have vi at the command-line
the shell is fully programmable
interpreted
will read from standard input or file input;
interacting with system vs. shell programming
UNIX shells
- Bourne (sh)
- original UNIX shell
- default prompt $
- Korn (ksh)
- superset of Bourne
- default prompt $
- default shell for CPS444/544
- C (csh)
- has a C-like syntax
- default prompt %
- Bash (bash)
- bourne again shell
- superset of Bourne
- default prompt bash$
- tcsh, zsh, ...
- develop your own!
Relationships between Linux Shells
Basic shell setup
(regenerated from [ATT] with minor modifications)
Shell commands vs. UNIX commands
some commands are built in to the shell
and others are native UNIX commands
Kernel metacharacters
- erase (^?): deletes previous character
- kill (^U): deletes entire line
- eof (^D): end of file
- intr (^C): kills current foreground process
- suspend (^Z)
- stop (^S)
- start (^Q)
- lnext (^V): literal next, escapes special meaning of
following kernel metacharacter
- and others
- stty -a (displays them)
- tset
stty command
- get/set kernel metacharacters
- remember that a command does not receive its arguments until
shell has interpreted all shell metacharacters
- analogously, shell does not receive command line until
kernel has interpreted all kernel metacharacters
- these settings control standard input from and output to the
terminal, not the shell
- how to redefine erase to # (be careful)?
$ stty erase # this not work, why?
$ stty erase '#' # are the single quotes necessary? will double quotes work just as well?
$ stty erase \# # why must we protect the hash?
$ stty erase ^? # why doesn't backspace need to be quoted?
stty sane
access/modification of terminal attributes through C
- tcgetattr and tcsetattr functions
- struct terminos
Korn shell metacharacters
- filename wildcard meta-characters:
character |
meaning |
# |
start of a comment to eol |
; |
command separator |
~ |
home directory |
* |
match any characters; alone expands to all files in current
directory |
? |
match any single character |
| |
pipe or logical "or" between patterns |
< |
redirect standard input |
> |
redirect standard output |
$ |
get value of variable following |
`<command>` |
command substitution; called grave quotes |
$(<command>) |
command substitution |
\ |
escapes next shell metacharacter;
allows long command-lines to be split across multiple lines |
' ... ' |
... protected from shell interpretation |
" ... " |
... protected from shell interpretation,
except for $, \, " ", or
$( ) (or ` `) |
[ |
begin a character group |
] |
end a character group |
- |
denotes a character range |
! |
negate a character group |
?(<pattern>) |
match zero or one instance of <pattern> |
*(<pattern>) |
match zero or more instances of <pattern> |
+(<pattern>) |
match one or more instances of <pattern> |
@(<pattern>) |
match exactly one instance of <pattern> |
!(<pattern>) |
match any strings which do
not contain <pattern> |
- examples:
$ ls p*.c (lists all files which start with p and end in .c)
$ ls prog?.c (lists all files which start with prog followed by any
one character and end in .c)
$ ls prog[0-9].c (lists all files which start with prog and
end in .c with any single digit as the
fifth character)
$ ls prog+([0-9]).c (lists all files which start with prog followed
by one or more digits and end in .c)
$ ls prog*([0-9])@(.f|.c) (lists all files which start with
prog, followed by zero or more digits, followed by .f or
.c)
- is . a shell metacharacter?
Protecting metacharacters from
multiple levels of interpretation
- kernel
- shell
- echo, grep, ...
Command substitution
$(<command>) is literally replaced by the output from
command (the Bourne shell syntax for this uses grave quotes:
`<command>`)
$ print "The date and time is $(date)."
The date and time is Tue Sep 2 13:38:02 EDT 2008.
$ print "There are $(who | wc -l) users logged onto $(hostname)."
There are 4 users logged onto sun131-31.cps.udayton.edu.
$ echo "You have $(ls | wc -l) files in $(pwd)."
You have 4 files in /home/cps444-n1.19.
Shell metacharacter interpretation
examples
$ echo hello
hello
$
$ echo hello how are you
hello how are you
$
$ echo *
$
$ echo *.c
$
$ cat on the wall
$
$ touch mickey mouse
$
$ # is whitespace a shell metacharacter?
$ touch mickey\ mouse
$
$ touch \"hello
$
$ echo HOME
HOME
$
$ echo $HOME
/home/cps444-n1.19
$
$ echo '$HOME'
$HOME
$
$ echo \$HOME
$HOME
$
$ echo "$HOME"
/home/cps444-n1.19
$
$ echo 'Single quotes "protect" double quotes'
Single quotes "protect" double quotes
$
$ # ref. [UIAN] (p. 4-4)
$ echo "Well, isn't that \"special\"?"
Well, isn't that "special"?
$
$ echo "The value of \$PWD is $PWD"
The value of $PWD is /home/cps444-n1.10/homeworks
$
# is newline a shell metacharacter?
$ # use \ or quotes for escape newline for line continuation
$ echo Howdy Tom, Dave, Robert, Paul, Sarah, \
> Lucy, Linus, Linda, and Larry
Howdy Tom, Dave, Robert, Paul, Sarah, Lucy, Linus, Linda, and Larry
$
$ echo "Howdy Tom, Dave, Robert, Paul, Sarah,
> Lucy, Linus, Linda, and Larry"
Howdy Tom, Dave, Robert, Paul, Sarah,
Lucy, Linus, Linda, and Larry
$
$ echo 'Howdy Tom, Dave, Robert, Paul, Sarah,
> Lucy, Linus, Linda, and Larry'
Howdy Tom, Dave, Robert, Paul, Sarah,
Lucy, Linus, Linda, and Larry
$
$ echo "Hello, how are you
> today?"
Hello, how are you
today?
$
$ echo 'Go $HOME'
Go $HOME
$ echo "$5.00 is too much!"
.00 is too much!
$ echo $(who | wc -l) users is not very many
2 users is not very many
$
$ ./a.out one two three four
argc is 5
argv[0] is ./a.out
argv[1] is one
argv[2] is two
argv[3] is three
argv[4] is four
$
$ ./a.out one "two three" four
argc is 4
argv[0] is ./a.out
argv[1] is one
argv[2] is two three
argv[3] is four
$
$ # how can we create a file named -r
$ # how can we remove a file named -r (be careful)
Shell scripts
$ cat > ourscript # can be done with vi as well
print Beginning of long file listing
ls -l
echo End of long file listing
return 0
^D
$ ksh < ourscript # standard I/O
Beginning of long file listing
...
$ ksh ourscript # file I/O
Beginning of long file listing
...
End of long file listing
making a script standalone and executable:
References
[UPE] |
B.W. Kernighan and R. Pike. The UNIX Programming Environment.
Prentice Hall, Upper Saddle River, NJ, Second edition, 1984.
|
[USP] |
K.A. Robbins and S. Robbins.
UNIX Systems Programming: Concurrency, Communication, and Threads.
Prentice Hall, Upper Saddle River, NJ, Second edition, 2003. |
|