Calling this section "Shell Programming" is sort of misleading. Strictly speaking, any command that works with the shell can be part of a shell script. The commands are featured here because they are rarely used outside of a script.
The commands covered in this section deal primarily with the flow of control statements, for example, if, case, while, and foreach. Also covered are statements such as eval, which deal with the evaluation of arguments.
First Line
By convention, UNIX shell scripts should all begin with a line like the following:
#!/bin/tcsh
The first two characters (#!) tell the operating system that the contents of this file are intended to be a shell script. The remaining characters are the absolute path of the shell under which that script is intended to run.
Note that the topic of shell scripting is fairly vast, much too large to cover in a single chapter. A number of good books have been written on the topic.
Also by convention, the file in which the script is saved should have an extension, indicating the shell under which it is to be run. In the case of the TC shell, that extension is .tc, for example,
shellscript.tc
The relevant commands are as follows:
@
@ name = expr
@ name[index] = expr
@ name|--
@ name[index]|--
Display or assign the value of shell variables.
Example: To increment the shell variable n, use
@n++;
break
Causes execution to resume after the end of the nearest enclosing foreach or while.
Example: To interrupt the following while loop when the value of $good is not 1, use
while (1)
# Actual commands go here
if ($good != 1) break;
end
breaksw
The breaksw statement is used in conjunction with the switch and case statements. The idea is that when a switch statement finds a match and executes the corresponding case statement block, you put the breaksw statement at the end of the block to tell the switch statement to stop looking for more matches.
Example: To terminate the execution of a switch statement when a match is found, use the following breaksw statement:
switch($value)
case 1:
# Do stuff
breaksw
case 2:
# Do other stuff
breaksw
default:
# Do default stuff
breaksw
endsw
case
label::
The case statement is used in conjunction with a switch statement to test a single variable against a range of possible values. After the switch statement has been used to specify the variable, a sequence of case statements is used to spell out the range of possible values. The variable in the switch statement will be tested against the values in the case statement. When matches are found, the corresponding statements are executed.
Example: The following switch statement will test the value of the variable a and print out a message indicating at which level a match was found:
switch($a)
case 1:
echo "Match found a value = 1"
breaksw
case 2:
echo "Match found at value = 1"
breaksw
default:
echo "Match found at default"
endsw
continue
Continues execution of the nearest enclosing while or foreach. The rest of the commands on the current line are executed.
Example: Let's pretend for a moment that the command "statement1" is a real statement instead of a syntax error. To execute statement 1, but skip the execution of statements 2, 3, and 4 when the value of $a is not equal to 1, use a continue statement as shown here:
while(a!=b)
statement1; # Executed
set a=1;
if($a!=1) continue;
statement2; # Skipped
statement3; # Skipped
statement4; # Skipped
end;
default
Labels the default case in a switch statement. It should come after all case labels. Although syntactically permissible, it is a terrible idea to omit the use of the default statement.
Example: See the example provided in the aforementioned case command.
eval arg
Treats the arguments as input to the shell and executes the resulting command(s) in the context of the current shell. This is usually used to execute commands generated as the result of command or variable substitution, since parsing occurs before these substitutions.
Example: To evaluate and execute the command sequence 'ls a', use
eval ls -a
foreach name ((wordlist))
end
Successively sets the variable name to each member of wordlist and executes the sequence of commands between this command and the matching end.
Example: To display the contents of all the files in the current working directory, use
foreach fn ('ls')
cat $fn
end
Note that the single quote used in this example is the one that, when shifted, becomes a tilde "~". If you use the other single quote, the one which, when shifted, becomes a double quote, it won't work.
filetest -op file
Applies one of the following operators to each file and returns the results as a space-separated list. The result is 1 if the specified property exists, 0 otherwise.
-op | Meaning |
r | Read access |
w | Write access |
x | Execute access |
X | Executable in the path or shell built-in. |
e | Existence |
o | Ownership |
z | Zero size |
s | Nonzero size |
f | Plain file |
d | Directory |
l | Symbolic link * |
b | Block special file |
c | Character special file |
p | Named pipe (fifo) * |
S | Socket special file * |
u | Set-user-ID bit is set |
g | Set-group-ID bit is set |
k | Sticky bit is set |
t | File (which must be a digit) is an open file descriptor for a terminal device |
R | Has been migrated (convex only) |
L | Applies subsequent operators in a multiple operator test to a symbolic link rather than to the file to which the link points * |
Example: The following command returns a 1 if the file somefile is executable, a 0 otherwise:
filetest x somefile
goto word
word is filename and command substituted to yield a string of the form 'label'. The shell rewinds its input as much as possible, searches for a line of the form 'label:', possibly preceded by blanks or tabs, and continues execution after that line.
Example:
if ((expr)) command
If the expression evaluates true, execute the specified command.
Example: To display the word executable when the file somefile is executable (for more on the x operator, see the afforementioned op list in the filetest command):
if ( filetest x somefile) echo "Executable"
if ((expr)) then
...
else if ((expr2)) then
...
else
...
endif
Evaluate the specified expressions and execute commands as appropriate.
Example: To display the word Executable when the file somefile is executable and the words "Not Executable" when it is not, use
if ( x somefile) then
echo "Executable";
else
echo "Not Executable";
end if
repeat count command
Repeats the specified command the specified number of times.
Example: To execute the date command 1,000 times, use
repeat date 1000
shift
[variable]
Without arguments, discards argv[1] and shifts the members of argv to the left. It is an error for argv not to be set or to have less than one word as value. With variable, performs the same function on variable.
Example: This handy example cycles through the argument list passed in to the current shell script and displays them as it goes:
while ($#argv)
echo $argv[1]
shift
end
switch ((string))
case str1::
...
breaksw
...
default::
...
breaksw
endsw
Matches each string (str1, str2, ) against the base string. The switch string is first command and filename expanded. When matches are found, any commands associated with that case statement are executed. The breaksw command causes execution to continue after the endsw statement.
See also: breaksw, case.
Example: See the earlier example for the case statement,
while
((expr))
end
Executes the commands between the while and the matching end as long as the specified expr evaluates as a true expression (see the section on expressions for details).
Example: The following loop will iterate 10 times, printing the value of the index as it goes:
set ndx=1;
while ($ndx <= 10)
echo $ndx;
@ndx ++;
end