. cshrc and . login file
Most users run the C-shell ‘/bin/csh' as their login environment, or these days, preferably the `tcsh' which is an improved version of csh. When a user logs in to a UNIX system the C-shell starts by reading some files which configure the environment by defining variables like path.
The file .cshrc' is searched for in your home directory. i.e. ‘~/ . cshrc’. If it is found, its contents are interpreted by the C-shell as C-shell instructions, before giving you the command prompt.
If and only if this is the login shell (not a sub-shell that you have started after login) then the file'/.login' is searched for and executed.
With some thought, the ‘.login’ file can be eliminated entirely, and we can put every-thing into the .cshrc file. Here is a very simple example ‘.cshrc’ file.
# .cshrc - read in by every csh that starts.
Defining variables with set, setenv
We have already seen in the examples above how to define variables in C-shell. Let's formalize this. To define a local variable - that is, one which will not get passed on to programs and sub-shells running under the current shell, we write
set local = "some string" set myname ="whoami"
These variables are then referred to by using the dollar '$' symbol. i.e. The value of the variable 'local' is ‘$local’.
echo $local $ myname
Global variables, that is variables which all sub-shells inherit from the current shell are defined using `setenv'
setenv GLOBAL "Some other string" setenv MYNAME "who am i"
Their values are also referred to using the '$' symbol. Notice that set uses an ‘=’ sign while `setenv' does not.Variables can be also created without a. value. The shell uses this method to switch on and off certain features, using variables like `noclobber and `noglob'. For instance
nexus% set flag nexus% if ($?flag) echo 'Flag is set!' Flag is set! nexus% unset flag nexus% if ( $?flag ) echo 'Flag is set!' nexus%
The operator '$?variable' is 'true' if variable exists and 'false' if it does not. It does not matter whether the variable holds any information.
The commands 'unset' and `unsetenv' can be used to undefine or delete variables when you don't want them anymore.
A useful facility in the C-shell is the ability to make arrays out of strings and other variables. The round parentheses ' ( )' do this. For example, look at the following commands.
nexus% set array =( a b c d ) nexus% echo $array a nexus% echo $array b nexus% echo $array[$#array] d nexus% set noarray = ( "a b c d" ) nexus% echo $noarray abcd nexus% echo $noarray[$#noarray] abcd
The special operator ‘$#’ returns the number of elements in an array. This gives us simple way of finding the end of the array. For example
nexus% echo $#path 23
‘linux tee’ and ‘script’
Occasionally you might want to have a copy of what you see on your terminal sent to a file. 'tee' and 'script' do this. For instance,
find / -type 1 -print | tee myfile
sends a copy of the output of 'find' to the file `myfile'. 'tee' can split the output into as many files as you want:
command | tee file1 file2 . . . .
You can also choose to record the output an entire shell session using the 'script' command.
nexus% script mysession Script started, file is mysession nexus% echo Big brother is scripting you Big brother is scripting you nexus% exit exit
Script done, file is mysession
The file mysession. is a text file which contains a transcript of the session.
Subshell ( )
The C-shell does not allow you to define subroutines or functions, but you can create a local shell, with its own private variables by enclosing commands in parentheses.
#!/bin/csh cd /etc ( cd /usr/bin; ls * ) > myfile Pwd
This program changes the working directory to /etc and then executes a subshell which inside the brackets changes directory to /user/bin and lists the files there.The output of this private shell are sent to a file ‘myfile’.At the end we print out the current working directory just to show that the ‘cd’ command in brackets had no effect on the main program.
Tests and conditions
No programming language would be complete without tests and loops. C-shell has two kinds of decision structure: the 'if ..then..else' and the 'switch' structure. These are closely related to their C counterparts. The syntax of these is
If ( condition ) command If( condition) then Command Command.. Else Command Command.. Endif Switch ( string) Case one: Commands Breaksw Case two: Commands Breaksw ............. endsw
We shall consider some examples of these statements in a moment, but first it is worth listing some important tests which can be used in 'if' questions to find out information about files.
'-r file' True if the file exists and is readable
'-w file' True if the file exists and is writable
'-x file' True if the file exists and is executable
‘-e file' True if the file simply exists
'-z file' True if the file exists and is empty
'-f file' True if the file is a plain file
'-d file' True if the file is a directory
The simplest way to learn about these statements is to use them, so we shall now I. at some examples.
#!/bin/csh –f # Safe copy from <arg> to <arg > if ($#argv != 2) then echo "Syntax: copy <from-file> <to-file>" exit 0 endif if ( -f $argv ) then echo "File exists. Copy anyway?" switch ( $< ) # Get a line from user case y: breaksw default: echo "Doing nothing!" exit 0 endsw endif echo -n "Copying Sargy DJ to $argy  ..." cp $argv $argv echo done
This script tries to copy a file from one location to another. If the user does not type exactly two arguments, the script quits with a message about the correct syntax. Otherwise it tests to see whether a plain file has the same name as the file the user wanted to copy to. If such a file exists, it asks the user if he/she wants to continue before proceeding to copy.
Loops in csh and csh foreach
The C-shell has three loop structures: 'repeat', 'while' and `foreach'. We have already seen some examples of the `foreach' loop.
The structure of these loops is as follows
repeat number-of-times command while ( test expression ) commands end foreach control-variable ( list-or-array ) commands end
The commands 'break' and `continue' can he used to break out of the looms at any time. Here are some examples.
repeat 2 echo "Yo!" I write mark
This sends the message "Yo!" to mark's terminal twice.
repeat 5 echo 'echo "Shutdown time! Log out now" I wall ; sleep 30' ; halt:
This example repeats the command 'echo Shutdown time...' five times at 30 second intervals, before shutting down the system. Only the superuser can run this command! Note the strange construction with 'echo echo'. This is to force the repeat command to take two shell commands as an argument. (Try to explain why this works for yourself.)
Input from the user
# Test a user response
echo "Answer y/n (yes or no)" set valid = false while ( $valid == false ) switch ( $< ) case y: echo "You answered yes" set valid = true breaksw case n: echo "You answered no" set valid = true breaksw default: echo "Invalid response, try again" breaksw endsw end
Notice that it would have been simpler to replace the two lines
set valid - true breaksw
by a single line 'break'. breaksw' jumps out of the switch construction, after which the `while' test fails. 'break' jumps out of the entire while loop.