|
|
1.1 root 1: .\" Copyright (c) 1980 Regents of the University of California.
2: .\" All rights reserved. The Berkeley software License Agreement
3: .\" specifies the terms and conditions for redistribution.
4: .\"
5: .\" @(#)csh.3 6.1 (Berkeley) 5/23/86
6: .\"
7: .nr H1 2
8: .NH
9: Shell control structures and command scripts
10: .NH 2
11: Introduction
12: .PP
13: It is possible to place commands in files and to cause shells to be
14: invoked to read and execute commands from these files,
15: which are called
16: .I "shell scripts."
17: We here detail those features of the shell useful to the writers of such
18: scripts.
19: .NH 2
20: Make
21: .PP
22: It is important to first note what shell scripts are
23: .I not
24: useful for.
25: There is a program called
26: .I make
27: which is very useful for maintaining a group of related files
28: or performing sets of operations on related files.
29: For instance a large program consisting of one or more files
30: can have its dependencies described in a
31: .I makefile
32: which contains definitions of the commands used to create these
33: different files when changes occur.
34: Definitions of the means for printing listings, cleaning up the directory
35: in which the files reside, and installing the resultant programs
36: are easily, and most appropriately placed in this
37: .I makefile.
38: This format is superior and preferable to maintaining a group of shell
39: procedures to maintain these files.
40: .PP
41: Similarly when working on a document a
42: .I makefile
43: may be created which defines how different versions of the document
44: are to be created and which options of
45: .I nroff
46: or
47: .I troff
48: are appropriate.
49: .NH 2
50: Invocation and the argv variable
51: .PP
52: A
53: .I csh
54: command script may be interpreted by saying
55: .DS
56: % csh script ...
57: .DE
58: where
59: .I script
60: is the name of the file containing a group of
61: .I csh
62: commands and
63: `\&...' is replaced by a sequence of arguments.
64: The shell places these arguments in the variable
65: .I argv
66: and then begins to read commands from the script.
67: These parameters are then available through the same mechanisms
68: which are used to reference any other shell variables.
69: .PP
70: If you make the file
71: `script'
72: executable by doing
73: .DS
74: chmod 755 script
75: .DE
76: and place a shell comment at the beginning of the shell script
77: (i.e. begin the file with a `#' character)
78: then a `/bin/csh' will automatically be invoked to execute `script' when
79: you type
80: .DS
81: script
82: .DE
83: If the file does not begin with a `#' then the standard shell
84: `/bin/sh' will be used to execute it.
85: This allows you to convert your older shell scripts to use
86: .I csh
87: at your convenience.
88: .NH 2
89: Variable substitution
90: .PP
91: After each input line is broken into words and history substitutions
92: are done on it, the input line is parsed into distinct commands.
93: Before each command is executed a mechanism know as
94: .I "variable substitution"
95: is done on these words.
96: Keyed by the character `$' this substitution replaces the names
97: of variables by their values.
98: Thus
99: .DS
100: echo $argv
101: .DE
102: when placed in a command script would cause the current value of the
103: variable
104: .I argv
105: to be echoed to the output of the shell script.
106: It is an error for
107: .I argv
108: to be unset at this point.
109: .PP
110: A number of notations are provided for accessing components and attributes
111: of variables.
112: The notation
113: .DS
114: $?name
115: .DE
116: expands to `1' if name is
117: .I set
118: or to `0'
119: if name is not
120: .I set.
121: It is the fundamental mechanism used for checking whether particular
122: variables have been assigned values.
123: All other forms of reference to undefined variables cause errors.
124: .PP
125: The notation
126: .DS
127: $#name
128: .DE
129: expands to the number of elements in the variable
130: .I name.
131: Thus
132: .DS
133: % set argv=(a b c)
134: % echo $?argv
135: 1
136: % echo $#argv
137: 3
138: % unset argv
139: % echo $?argv
140: 0
141: % echo $argv
142: Undefined variable: argv.
143: %
144: .DE
145: .PP
146: It is also possible to access the components of a variable
147: which has several values.
148: Thus
149: .DS
150: $argv[1]
151: .DE
152: gives the first component of
153: .I argv
154: or in the example above `a'.
155: Similarly
156: .DS
157: $argv[$#argv]
158: .DE
159: would give `c',
160: and
161: .DS
162: $argv[1\-2]
163: .DE
164: would give `a b'. Other notations useful in shell scripts are
165: .DS
166: $\fIn\fR
167: .DE
168: where
169: .I n
170: is an integer as a shorthand for
171: .DS
172: $argv[\fIn\fR\|]
173: .DE
174: the
175: .I n\|th
176: parameter and
177: .DS
178: $*
179: .DE
180: which is a shorthand for
181: .DS
182: $argv
183: .DE
184: The form
185: .DS
186: $$
187: .DE
188: expands to the process number of the current shell.
189: Since this process number is unique in the system it can
190: be used in generation of unique temporary file names.
191: The form
192: .DS
193: $<
194: .DE
195: is quite special and is replaced by the next line of input read from
196: the shell's standard input (not the script it is reading). This is
197: useful for writing shell scripts that are interactive, reading
198: commands from the terminal, or even writing a shell script that
199: acts as a filter, reading lines from its input file. Thus the sequence
200: .DS
201: echo 'yes or no?\ec'
202: set a=($<)
203: .DE
204: would write out the prompt `yes or no?' without a newline and then
205: read the answer into the variable `a'. In this case `$#a' would be
206: `0' if either a blank line or end-of-file (^D) was typed.
207: .PP
208: One minor difference between `$\fIn\fR\|' and `$argv[\fIn\fR\|]'
209: should be noted here.
210: The form
211: `$argv[\fIn\fR\|]'
212: will yield an error if
213: .I n
214: is not in the range
215: `1\-$#argv'
216: while `$n'
217: will never yield an out of range subscript error.
218: This is for compatibility with the way older shells handled parameters.
219: .PP
220: Another important point is that it is never an error to give a subrange
221: of the form `n\-'; if there are less than
222: .I n
223: components of the given variable then no words are substituted.
224: A range of the form `m\-n' likewise returns an empty vector without giving
225: an error when \fIm\fR exceeds the number of elements of the given variable,
226: provided the subscript \fIn\fR is in range.
227: .NH 2
228: Expressions
229: .PP
230: In order for interesting shell scripts to be constructed it
231: must be possible to evaluate expressions in the shell based on the
232: values of variables.
233: In fact, all the arithmetic operations of the language C are available
234: in the shell
235: with the same precedence that they have in C.
236: In particular, the operations `==' and `!=' compare strings
237: and the operators `&&' and `|\|\||' implement the boolean and/or operations.
238: The special operators `=~' and `!~' are similar to `==' and `!=' except
239: that the string on the right side can have pattern matching characters
240: (like *, ? or []) and the test is whether the string on the left matches
241: the pattern on the right.
242: .PP
243: The shell also allows file enquiries of the form
244: .DS
245: \-? filename
246: .DE
247: where `?' is replace by a number of single characters.
248: For instance the expression primitive
249: .DS
250: \-e filename
251: .DE
252: tell whether the file
253: `filename'
254: exists.
255: Other primitives test for read, write and execute access to the file,
256: whether it is a directory, or has non-zero length.
257: .PP
258: It is possible to test whether a command terminates normally,
259: by a primitive of the
260: form `{ command }' which returns true, i.e. `1' if the command
261: succeeds exiting normally with exit status 0, or `0' if the command
262: terminates abnormally or with exit status non-zero.
263: If more detailed information about the execution status of a command
264: is required, it can be executed and the variable `$status' examined
265: in the next command.
266: Since `$status' is set by every command, it is very transient.
267: It can be saved if it is inconvenient to use it only in the single
268: immediately following command.
269: .PP
270: For a full list of expression components available see the manual
271: section for the shell.
272: .NH 2
273: Sample shell script
274: .PP
275: A sample shell script which makes use of the expression mechanism
276: of the shell and some of its control structure follows:
277: .DS
278: % cat copyc
279: #
280: # Copyc copies those C programs in the specified list
281: # to the directory ~/backup if they differ from the files
282: # already in ~/backup
283: #
284: set noglob
285: foreach i ($argv)
286:
287: if ($i !~ *.c) continue # not a .c file so do nothing
288:
289: if (! \-r ~/backup/$i:t) then
290: echo $i:t not in backup... not cp\e\'ed
291: continue
292: endif
293:
294: cmp \-s $i ~/backup/$i:t # to set $status
295:
296: if ($status != 0) then
297: echo new backup of $i
298: cp $i ~/backup/$i:t
299: endif
300: end
301: .DE
302: .PP
303: This script makes use of the
304: .I foreach
305: command, which causes the shell to execute the commands between the
306: .I foreach
307: and the matching
308: .I end
309: for each of the values given between `(' and `)' with the named
310: variable, in this case `i' set to successive values in the list.
311: Within this loop we may use the command
312: .I break
313: to stop executing the loop
314: and
315: .I continue
316: to prematurely terminate one iteration
317: and begin the next.
318: After the
319: .I foreach
320: loop the iteration variable
321: (\fIi\fR in this case)
322: has the value at the last iteration.
323: .PP
324: We set the variable
325: .I noglob
326: here to prevent filename expansion of the members of
327: .I argv.
328: This is a good idea, in general, if the arguments to a shell script
329: are filenames which have already been expanded or if the arguments
330: may contain filename expansion metacharacters.
331: It is also possible to quote each use of a `$' variable expansion,
332: but this is harder and less reliable.
333: .PP
334: The other control construct used here is a statement of the form
335: .DS
336: \fBif\fR ( expression ) \fBthen\fR
337: command
338: ...
339: \fBendif\fR
340: .DE
341: The placement of the keywords here is
342: .B not
343: flexible due to the current implementation of the shell.\(dg
344: .FS
345: \(dgThe following two formats are not currently acceptable to the shell:
346: .sp
347: .in +5
348: .nf
349: \fBif\fR ( expression ) # \fBWon't work!\fR
350: \fBthen\fR
351: command
352: ...
353: \fBendif\fR
354: .fi
355: .in -5
356: .sp
357: and
358: .sp
359: .in +5
360: .nf
361: \fBif\fR ( expression ) \fBthen\fR command \fBendif\fR # \fBWon't work\fR
362: .in -5
363: .fi
364: .FE
365: .PP
366: The shell does have another form of the if statement of the form
367: .DS
368: \fBif\fR ( expression ) \fBcommand\fR
369: .DE
370: which can be written
371: .DS
372: \fBif\fR ( expression ) \e
373: command
374: .DE
375: Here we have escaped the newline for the sake of appearance.
376: The command must not involve `\||\|', `&' or `;'
377: and must not be another control command.
378: The second form requires the final `\e' to
379: .B immediately
380: precede the end-of-line.
381: .PP
382: The more general
383: .I if
384: statements above also admit a sequence of
385: .I else\-if
386: pairs followed by a single
387: .I else
388: and an
389: .I endif,
390: e.g.:
391: .DS
392: \fBif\fR ( expression ) \fBthen\fR
393: commands
394: \fBelse\fR \fBif\fR (expression ) \fBthen\fR
395: commands
396: \&...
397:
398: \fBelse\fR
399: commands
400: \fBendif\fR
401: .DE
402: .PP
403: Another important mechanism used in shell scripts is the `:' modifier.
404: We can use the modifier `:r' here to extract a root of a filename or
405: `:e' to extract the
406: .I extension.
407: Thus if the variable
408: .I i
409: has the value
410: `/mnt/foo.bar'
411: then
412: .sp
413: .in +5
414: .nf
415: % echo $i $i:r $i:e
416: /mnt/foo.bar /mnt/foo bar
417: %
418: .sp
419: .in -5
420: .fi
421: shows how the `:r' modifier strips off the trailing `.bar' and the
422: the `:e' modifier leaves only the `bar'.
423: Other modifiers will take off the last component of a pathname leaving
424: the head `:h' or all but the last component of a pathname leaving the
425: tail `:t'.
426: These modifiers are fully described in the
427: .I csh
428: manual pages in the User's Reference Manual.
429: It is also possible to use the
430: .I "command substitution"
431: mechanism described in the next major section to perform modifications
432: on strings to then reenter the shell's environment.
433: Since each usage of this mechanism involves the creation of a new process,
434: it is much more expensive to use than the `:' modification mechanism.\(dd
435: .FS
436: \(dd It is also important to note that
437: the current implementation of the shell limits the number of `:' modifiers
438: on a `$' substitution to 1.
439: Thus
440: .sp
441: .nf
442: .in +5
443: % echo $i $i:h:t
444: /a/b/c /a/b:t
445: %
446: .in -5
447: .fi
448: .sp
449: does not do what one would expect.
450: .FE
451: Finally, we note that the character `#' lexically introduces a shell
452: comment in shell scripts (but not from the terminal).
453: All subsequent characters on the input line after a `#' are discarded
454: by the shell.
455: This character can be quoted using `\'' or `\e' to place it in
456: an argument word.
457: .NH 2
458: Other control structures
459: .PP
460: The shell also has control structures
461: .I while
462: and
463: .I switch
464: similar to those of C.
465: These take the forms
466: .DS
467: \fBwhile\fR ( expression )
468: commands
469: \fBend\fR
470: .DE
471: and
472: .DS
473: \fBswitch\fR ( word )
474:
475: \fBcase\fR str1:
476: commands
477: \fBbreaksw\fR
478:
479: \& ...
480:
481: \fBcase\fR strn:
482: commands
483: \fBbreaksw\fR
484:
485: \fBdefault:\fR
486: commands
487: \fBbreaksw\fR
488:
489: \fBendsw\fR
490: .DE
491: For details see the manual section for
492: .I csh.
493: C programmers should note that we use
494: .I breaksw
495: to exit from a
496: .I switch
497: while
498: .I break
499: exits a
500: .I while
501: or
502: .I foreach
503: loop.
504: A common mistake to make in
505: .I csh
506: scripts is to use
507: .I break
508: rather than
509: .I breaksw
510: in switches.
511: .PP
512: Finally,
513: .I csh
514: allows a
515: .I goto
516: statement, with labels looking like they do in C, i.e.:
517: .DS
518: loop:
519: commands
520: \fBgoto\fR loop
521: .DE
522: .NH 2
523: Supplying input to commands
524: .PP
525: Commands run from shell scripts receive by default the standard
526: input of the shell which is running the script.
527: This is different from previous shells running
528: under \s-2UNIX\s0. It allows shell scripts to fully participate
529: in pipelines, but mandates extra notation for commands which are to take
530: inline data.
531: .PP
532: Thus we need a metanotation for supplying inline data to commands in
533: shell scripts.
534: As an example, consider this script which runs the editor to
535: delete leading blanks from the lines in each argument file:
536: .DS
537: % cat deblank
538: # deblank \-\- remove leading blanks
539: foreach i ($argv)
540: ed \- $i << \'EOF\'
541: 1,$s/^[ ]*//
542: w
543: q
544: \&\'EOF\'
545: end
546: %
547: .DE
548: The notation `<< \'EOF\''
549: means that the standard input for the
550: .I ed
551: command is to come from the text in the shell script file
552: up to the next line consisting of exactly `\'EOF\''.
553: The fact that the `EOF' is enclosed in `\'' characters, i.e. quoted,
554: causes the shell to not perform variable substitution on the
555: intervening lines.
556: In general, if any part of the word following the `<<' which the
557: shell uses to terminate the text to be given to the command is quoted
558: then these substitutions will not be performed.
559: In this case since we used the form `1,$' in our editor script
560: we needed to insure that this `$' was not variable substituted.
561: We could also have insured this by preceding the `$' here with a `\e',
562: i.e.:
563: .DS
564: 1,\e$s/^[ ]*//
565: .DE
566: but quoting the `EOF' terminator is a more reliable way of achieving the
567: same thing.
568: .NH 2
569: Catching interrupts
570: .PP
571: If our shell script creates temporary files, we may wish to catch
572: interruptions of the shell script so that we can clean up
573: these files.
574: We can then do
575: .DS
576: onintr label
577: .DE
578: where
579: .I label
580: is a label in our program.
581: If an interrupt is received the shell will do a
582: `goto label'
583: and we can remove the temporary files and then do an
584: .I exit
585: command (which is built in to the shell)
586: to exit from the shell script.
587: If we wish to exit with a non-zero status we can do
588: .DS
589: exit(1)
590: .DE
591: e.g. to exit with status `1'.
592: .NH 2
593: What else?
594: .PP
595: There are other features of the shell useful to writers of shell
596: procedures.
597: The
598: .I verbose
599: and
600: .I echo
601: options and the related
602: .I \-v
603: and
604: .I \-x
605: command line options can be used to help trace the actions of the shell.
606: The
607: .I \-n
608: option causes the shell only to read commands and not to execute
609: them and may sometimes be of use.
610: .PP
611: One other thing to note is that
612: .I csh
613: will not execute shell scripts which do not begin with the
614: character `#', that is shell scripts that do not begin with a comment.
615: Similarly, the `/bin/sh' on your system may well defer to `csh'
616: to interpret shell scripts which begin with `#'.
617: This allows shell scripts for both shells to live in harmony.
618: .PP
619: There is also another quotation mechanism using `"' which allows
620: only some of the expansion mechanisms we have so far discussed to occur
621: on the quoted string and serves to make this string into a single word
622: as `\'' does.
623: .bp
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.