W. Joy - An Introduction to the C shell (794270), страница 8
Текст из файла (страница 8)
This is useful for writing shell scripts that are interactive, reading commands from the terminal,or even writing a shell script that acts as a filter, reading lines from its input file. Thus the sequenceecho ’yes or no?\c’set a=($<)would write out the prompt ‘yes or no?’ without a newline and then read the answer into the variable ‘a’.In this case ‘$#a’ would be ‘0’ if either a blank line or end-of-file (ˆD) was typed.One minor difference between ‘$n ’ and ‘$argv[n ]’ should be noted here.
The form ‘$argv[n ]’ willyield an error if n is not in the range ‘1−$#argv’ while ‘$n’ will never yield an out of range subscript error.----USD:4-26An Introduction to the C shellThis is for compatibility with the way older shells handled parameters.Another important point is that it is never an error to give a subrange of the form ‘n−’; if there areless than n components of the given variable then no words are substituted. A range of the form ‘m−n’likewise returns an empty vector without giving an error when m exceeds the number of elements of thegiven variable, provided the subscript n is in range.3.5.
ExpressionsIn order for interesting shell scripts to be constructed it must be possible to evaluate expressions inthe shell based on the values of variables. In fact, all the arithmetic operations of the language C are available in the shell with the same precedence that they have in C. In particular, the operations ‘==’ and ‘!=’compare strings and the operators ‘&&’ and ‘| |’ implement the boolean and/or operations. The specialoperators ‘=˜’ and ‘!˜’ are similar to ‘==’ and ‘!=’ except that the string on the right side can have patternmatching characters (like *, ? or []) and the test is whether the string on the left matches the pattern on theright.The shell also allows file enquiries of the form−? filenamewhere ‘?’ is replace by a number of single characters. For instance the expression primitive−e filenametell whether the file ‘filename’ exists.
Other primitives test for read, write and execute access to the file,whether it is a directory, or has non-zero length.It is possible to test whether a command terminates normally, by a primitive of the form ‘{ command}’ which returns true, i.e. ‘1’ if the command succeeds exiting normally with exit status 0, or ‘0’ if the command terminates abnormally or with exit status non-zero. If more detailed information about the executionstatus of a command is required, it can be executed and the variable ‘$status’ examined in the next command.
Since ‘$status’ is set by every command, it is very transient. It can be saved if it is inconvenient touse it only in the single immediately following command.For a full list of expression components available see the manual section for the shell.3.6. Sample shell scriptA sample shell script which makes use of the expression mechanism of the shell and some of its control structure follows:----An Introduction to the C shellUSD:4-27% cat copyc## Copyc copies those C programs in the specified list# to the directory ˜/backup if they differ from the files# already in ˜/backup#set noglobforeach i ($argv)if ($i !˜ *.c) continue # not a .c file so do nothingif (! −r ˜/backup/$i:t) thenecho $i:t not in backup...
not cp\´edcontinueendifcmp −s $i ˜/backup/$i:t # to set $statusif ($status != 0) thenecho new backup of $icp $i ˜/backup/$i:tendifendThis script makes use of the foreach command, which causes the shell to execute the commandsbetween the foreach and the matching end for each of the values given between ‘(’ and ‘)’ with the namedvariable, in this case ‘i’ set to successive values in the list. Within this loop we may use the commandbreak to stop executing the loop and continue to prematurely terminate one iteration and begin the next.After the foreach loop the iteration variable (i in this case) has the value at the last iteration.We set the variable noglob here to prevent filename expansion of the members of argv.
This is agood idea, in general, if the arguments to a shell script are filenames which have already been expanded orif the arguments may contain filename expansion metacharacters. It is also possible to quote each use of a‘$’ variable expansion, but this is harder and less reliable.The other control construct used here is a statement of the formif ( expression ) thencommand...endifThe placement of the keywords here is not flexible due to the current implementation of the shell.†The shell does have another form of the if statement of the form†The following two formats are not currently acceptable to the shell:if ( expression )thencommand...endif# Won’t work!andif ( expression ) then command endif# Won’t work----USD:4-28An Introduction to the C shellif ( expression ) commandwhich can be writtenif ( expression ) \commandHere we have escaped the newline for the sake of appearance.
The command must not involve ‘ | ’, ‘&’ or‘;’ and must not be another control command. The second form requires the final ‘\’ to immediately precede the end-of-line.The more general if statements above also admit a sequence of else−if pairs followed by a singleelse and an endif, e.g.:if ( expression ) thencommandselse if (expression ) thencommands...elsecommandsendifAnother important mechanism used in shell scripts is the ‘:’ modifier. We can use the modifier ‘:r’here to extract a root of a filename or ‘:e’ to extract the extension. Thus if the variable i has the value‘/mnt/foo.bar’ then% echo $i $i:r $i:e/mnt/foo.bar /mnt/foo bar%shows how the ‘:r’ modifier strips off the trailing ‘.bar’ and the the ‘:e’ modifier leaves only the ‘bar’.Other modifiers will take off the last component of a pathname leaving the head ‘:h’ or all but the last component of a pathname leaving the tail ‘:t’.
These modifiers are fully described in the csh manual pages inthe User’s Reference Manual. It is also possible to use the command substitution mechanism described inthe next major section to perform modifications on strings to then reenter the shell’s environment. Sinceeach usage of this mechanism involves the creation of a new process, it is much more expensive to use thanthe ‘:’ modification mechanism.‡ Finally, we note that the character ‘#’ lexically introduces a shell comment in shell scripts (but not from the terminal). All subsequent characters on the input line after a ‘#’ arediscarded by the shell.
This character can be quoted using ‘´’ or ‘\’ to place it in an argument word.3.7. Other control structuresThe shell also has control structures while and switch similar to those of C. These take the formswhile ( expression )commandsend‡ It is also important to note that the current implementation of the shell limits the number of ‘:’ modifiers on a ‘$’ substitution to 1. Thus% echo $i $i:h:t/a/b/c /a/b:t%does not do what one would expect.----An Introduction to the C shellUSD:4-29andswitch ( word )case str1:commandsbreaksw...case strn:commandsbreakswdefault:commandsbreakswendswFor details see the manual section for csh. C programmers should note that we use breaksw to exit from aswitch while break exits a while or foreach loop. A common mistake to make in csh scripts is to usebreak rather than breaksw in switches.Finally, csh allows a goto statement, with labels looking like they do in C, i.e.:loop:commandsgoto loop3.8.
Supplying input to commandsCommands run from shell scripts receive by default the standard input of the shell which is runningthe script. This is different from previous shells running under UNIX. It allows shell scripts to fully participate in pipelines, but mandates extra notation for commands which are to take inline data.Thus we need a metanotation for supplying inline data to commands in shell scripts. As an example,consider this script which runs the editor to delete leading blanks from the lines in each argument file:% cat deblank# deblank −− remove leading blanksforeach i ($argv)ed − $i << ´EOF´1,$s/ˆ[ ]*//wq´EOF´end%The notation ‘<< ´EOF´’ means that the standard input for the ed command is to come from the text in theshell script file up to the next line consisting of exactly ‘´EOF´’.
The fact that the ‘EOF’ is enclosed in ‘´’characters, i.e. quoted, causes the shell to not perform variable substitution on the intervening lines. In general, if any part of the word following the ‘<<’ which the shell uses to terminate the text to be given to thecommand is quoted then these substitutions will not be performed. In this case since we used the form‘1,$’ in our editor script we needed to insure that this ‘$’ was not variable substituted. We could also haveinsured this by preceding the ‘$’ here with a ‘\’, i.e.:----USD:4-30An Introduction to the C shell1,\$s/ˆ[ ]*//but quoting the ‘EOF’ terminator is a more reliable way of achieving the same thing.3.9.
Catching interruptsIf our shell script creates temporary files, we may wish to catch interruptions of the shell script sothat we can clean up these files. We can then doonintr labelwhere label is a label in our program. If an interrupt is received the shell will do a ‘goto label’ and we canremove the temporary files and then do an exit command (which is built in to the shell) to exit from theshell script. If we wish to exit with a non-zero status we can doexit(1)e.g.
to exit with status ‘1’.3.10. What else?There are other features of the shell useful to writers of shell procedures. The verbose and echooptions and the related −v and −x command line options can be used to help trace the actions of the shell.The −n option causes the shell only to read commands and not to execute them and may sometimes be ofuse.One other thing to note is that csh will not execute shell scripts which do not begin with the character‘#’, that is shell scripts that do not begin with a comment.
Similarly, the ‘/bin/sh’ on your system may welldefer to ‘csh’ to interpret shell scripts which begin with ‘#’. This allows shell scripts for both shells to livein harmony.There is also another quotation mechanism using ‘"’ which allows only some of the expansion mechanisms we have so far discussed to occur on the quoted string and serves to make this string into a singleword as ‘´’ does.----An Introduction to the C shellUSD:4-314. Other, less commonly used, shell features4.1. Loops at the terminal; variables as vectorsIt is occasionally useful to use the foreach control structure at the terminal to aid in performing anumber of similar commands.