A shell is a command line interpretor. It takes commands and executes them. As such, it
implements a programming language. The Bourne shell is used to create shell scripts -- ie.
programs that are interpreted/executed by the shell. You can write shell scripts with the C-
shell; however, this is not covered here.
Suppose you often type the command
and you'd rather type a simple command, say
Create a shell script
This quick example is far from adequate but some observations:
1. Shell scripts are simple text files created with an editor.
2. Shell scripts are marked as executeable
4. Should be located in your search path and ~/bin should be in your search path.
5. You likely need to rehash if you're a Csh (tcsh) user (but not again when you login).
6. Arguments are passed from the command line and referenced. For example, as $1.
All Bourne Shell scripts should begin with the sequence
From the man page for exec(2):
!"
#
$
%&
'(
)*&
Comments are any text beginning with the pound (#) sign. A comment can start anywhere on
a line and continue until the end of the line.
All shell scripts should include a search path specifica- tion:
!"#$ % %& !"#
A PATH specification is recommended -- often times a script will fail for some people
because they have a different or incomplete search path.
+&
'
,
,
A good shell script should verify that the arguments sup- plied (if any) are correct.
'
(&
)*+,
%-./.
+0
This script requires three arguments and gripes accordingly.
All Unix utilities should return an exit status.
1
2
'1
.-1
+-..(&
)*+3
451
45
+0
!
6
7
-
A non-zero exit status indicates an error condition of some sort while a zero exit status
indicates things worked as expected.
&'-
!
.
'
Exit codes are important for those who use your code. Many constructs test on the exit status
of a command.
+
/
&
For example,
1&
8
94:;
Your code should be written with the expectation that others will use it. Making sure you
return a meaningful exit status will help.
Standard input, output, and error are file descriptors 0, 1, and 2. Each has a particular role and
should be used accordingly:
1
2
'1
.-1
+-..(&
)*+3
451
45 1
+0
761<
1
=6
>
10>
-?
@&&
?
"
&&
Error messages should appear on stderr not on stdout! Output should appear on stdout. As for
input/output dialogue:
<
9
A
1&
"9
<
B
/7
2&
55
BCDB?
E
&
-&&
F@$5
5
F@$5
5
Note: this code behaves differently if there's a user to communicate with (ie. if the standard
input is a tty rather than a pipe, or file, or etc. See tty(1)).
For loop iteration
' ,
,
0/
<
9
For example:
>G/HI>
<"/;!3
<
JJK
Alternatively you may see:
< 9 & &
•
Case
'
9
'
'C
(?
&&(
For example:
51
5
'-.('-.(?
1
$.L1
M
1
$>
1
.->
&&
'-.('-.('-.('-.(?
1
$>
1
.->
&&
B?
)*+3
451
45
+0
&&
•
Conditional Execution
+
'
(
For example:
'
(&
)*+,
%-./.
+0
Alternatively you may see:
& &' &(
•
While/Until Iteration
10
L9
CM
For example:
6
1
9
'
(&
N
Alternatively you may see:
9 & &
•
Variables
2
3
+
,
4444
5
,
% 046(
,
o
Variable Assignment
" , , , 7, /
!"#$ % %& !"#
or
"/;!3$>O 4> 4>& ?>
o
Exporting Variables
2 0
P
@,I"<
;QI G!3
<
<
'5;QI G!35$55(&
1&
5;QI G!3O>
>%--?245&
;QI G!3
'5;QI G!35$55(&
;QI G!3$>
>%--
;QI G!3
Likewise, for variables like the PRINTER which you want hon- ored by lpr(1).
From a user's .profile:
FQD"8F$ I & FQD"8F
Note: that the Cshell exports all environment variables.
o
Referencing Variables
84, % 49, :( ,
@ R< 9
'5,I8F5$5
5(&
!"#$#/@8% !"#
!"#$
%
% !"#
The braces are required for concatenation constructs.
N-
The value of the variable "p_01".
LMN-
The value of the variable "p" with "_01" pasted onto the end.
o
Conditional Reference
o
L< 9 M
If the variable has been set, use it's value, else use word.
/I"ISFQ "$L /I"ISFQ " I
M&
/I"ISFQ "
L<
%9
M
If the variable has been set and is not null, use it's value, else use word.
+
,
;
,
,
)
0
%6(
<1;5+=1,
,
0
L< %29 M
If variable is set use it's value, else print out word and exit. Useful for bailing
out.
o
Arguments
) , /
-66
The command and arguments. With $0 the command and the rest the
arguments.
The number of arguments.
B6T
All the arguments as a blank separated string. Watch out for "$*" vs. "$@".
And, some commands:
Shift the postional variables down one and decrement number of arguments.
Set the positional variables to the argument list.
) /
9
'
(&
A use of the set command:
91
"/;!3$>O
4>
4>&
?>
I //G
>G/HI>
<"/;!3
<
JJK
o
Special Variables
o
Current process id. This is very useful for constructing temporary files.
$ -
5
+5
+U
)
2
The exit status of the last command.
F
'2
A-(
•
Quotes/Special Characters
' /
&*O?C:V) 9
These are for command sequences, background jobs, etc. To quote any of these use a
backslash (\) or bracket with quote marks ("" or '').
> 3
3
0+
%LM% C97E%RL MR
Double Quotes
>
3
,,
%
(
% ?@
3
(+
'5L
M5(&
$L
ML
ML
M
Back Quotes
&03
'5>
>5$55(&
$55
$545
$55
$55
and
"/;!3$>O 4> 4>& ?>
•
Functions
! '
O?
L
M
For example:
1
N
O?
L
1
'(&
%D
1)*+
M
Within a function the positional parmeters $0, $1, etc. are the arguments to the
function (not the arguments to the script).
>
/
9
6
N
O?
L
9
N
M
7
O
?
'55$55(&
CN
N
•
Sourcing commands
" /
+
'
/
. command
+ /
F
What are the virtues of each? What's the difference? The second form is useful for
configuration files where environment variable are set for the script. For example:
#/I"#/I"I&
2
'
LW!SX, #/@8ML#/I"M(&
LW!SX, #/@8ML#/I"M
Using configuration files in this manner makes it possible to write scripts that are
automatically tailored for differ- ent situations.
•
Test
+ %6(
&
and (note the matching bracket argument)
'
(&
On System V machines this is a builtin (check out the com- mand /bin/test).
&'- % 0'(
A
8 /
L96 666M
is file writeable, readable, executeable, empty, etc?
L A6 66M+
are numbers equal, not equal, greater than, etc.?
L$6$M+
Are strings the same or different?
L6M+
Binary or; binary and; use ! for unary negation.
'1
.-1
+-..(&
)*+3
451
45
+0
Learn this command inside out! It does a lot for you.
•
String matching
+
,
"
0
9
'
(&
B?
$>
C>&&
?&
$&&
B?
$>
C>&&
?&
$&&
B?
,
&
&&
B?7$B&
7&&
Of course getopt would work much better.
•
SysV vs BSD echo
&'- ! /
/7 2&
On SysV systems you'd say:
/7 24&
In an effort to produce portable code we've been using:
97
'5>
>5$55(&
$55&$545
$55&$55
/7
2&
•
Is there a person?
+8
3
=
$
8 ! 3 !
Q
R
6
1&
8
94:;
The tradition also extends to output.
Q
6
<
1V*&
<
$
<
$
Beware: just because stdin is a tty that doesn't mean that stdout is too. User prompts
should be directed to the user terminal.
Q
R
6
1&
8
94:;)*-
Have you ever had a program stop waiting for keyboard input when the output is
directed elsewhere?
•
Creating Input
>! /
7
O
?
'55$55(&
CN
N
alternatively, redirection from a file:
7
O
?
'55$55(&
N
V
N
You can also construct files on the fly.
V
%
%VT
99)
%
IY
%I+
+,
E
,P/
A
8/E
Note: that variables are expanded in the input.
•
String Manipulations
! ' 0
"Q@8$>
C+.>
"Q@8$>
C
RBBB4OB4?BB4R>
"Q@8$>
C97RL
KMR>
"Q@8$>
4>
4>&
K>
"Q@8$>
CO
<91Z&
?>
With some care, redefining the input field separators can help.
<
Q
O?
L
>QEI$55&
>
K+
M
'
(&
)*+,
%1 Q
+0
$>
>
7VV8/EC
55C
RB$R
1
$1
8/E
•
Debugging
+ 0 /
1 ! ;=0
-
!
;
!
,