
. 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.
Arrays
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[1]
a
nexus% echo $array[2]
b
nexus% echo $array[$#array]
d
nexus% set noarray = ( "a b c d" )
nexus% echo $noarray[1]
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[1]> to <arg [2]>
if ($#argv != 2) then
echo "Syntax: copy <from-file> <to-file>"
exit 0
endif
if ( -f $argv[2] ) 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 [2] ..."
cp $argv[1] $argv[2]
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.