There is almost no difference between syntax of csh and tcsh statements which are useful in scripts; the two shells differ mostly in the interactive features (such as capabilities of command completion). There are Unix systems which contain csh but not tcsh. Every Unix system which contains tcsh, either also contains csh, or csh could be added to it just by creating a symbolic link called csh which points to tcsh. Tcsh is an extension of csh, compatible with csh. (When tcsh is invoked through a link called csh, the tcsh notices this fact and assumes the exact behavior of csh.???) For these reasons most programmers write just csh scripts, not tcsh scripts.
The first line of every csh script should contain #!/bin/csh or #!/bin/csh -f , preceded by no spaces or tabs. This is more than just a comment -- this line tells the system how to call the interpreter which will execute the script. The -f option causes that the csh which executes the script does not read (ANY OR USER'S ???) initialization files.
Debugging
The following statements, individually or together, are useful during the
development of the script:
set echo
set verbose
When the script is executed, they will cause that a trace of execution will be
printed on the screen.
Shell variables.
By convention names of shell variables are not capitalized.
set VARNAME = VALUE
set aa = Hello
set bb = 'Hello world'
set aa = "$aa my friend"
set outputFile = ~/csc319/out.txt
set user1 = abcd1234
set nn = 345
set ee
unset bb
Remember to put spaces around the = symbol.
Shell list (array) variables.
There are only lists of strings; there are no lists of lists.
set users = ($user1 bcde2345)
set users = (root $users cdef3456)
set $users[0] = defg4567
Command line parameters
$0 -- the name through which the script was invoked
$1, $2, ..., $9 -- the first, second, ..., ninth parameter with which the script
was invoked.
$* -- the list of all command line parameters, (excluding the name of the
script).
$#argv -- the number of command line parameters.
It is useful to use :q operation, in case if the parameters escaped contained
white space.
If the user of a script wants to specify a parameter string which contains white
space, every white space character must be preceded by \. If the user
typed myscript fff\ ggg, in the script the following values would be received:
$1 would have value fff
$2 would have value ggg
$* would have value (fff ggg)
$1:q would have value 'fff ggg'
$*:q would have value ('fff ggg')
Input
Every time user presses Enter, special variable $< is updated to store
one line of users input; the line break is not a part if the string in $<.
WHAT IF USER TYPES CTRL-D ?
Output
echo '
echo "cc = $cc"
-- echo adds a line break after the string.
echo "$bb\n $cc"
-- Use \n to specify an additional line break.
echo -n "$aa $bb $cc"
-- With -n, echo will not add a line break.
echo $aa > $outputFile
echo $cc >> $outputFile
echo "$nn+$nn"
-- addition not performed.
cat << ENDLABEL
-- this outputs all the text up to but excluding ENDLABEL.
...
You can use MESSAGE1_END, etc as the end label.
...
This feature is called a "here document"
ENDLABEL
String operations
There is no concatenation operator. To concatenate strings, put them one next to
the other.
set newstring = aaa$string1${string2}bbb
Notice that curly braces can be used to delimit the variable name (so that the
shell does not think the variable name is string2bbb.)
set myfile = /usr/users/abcd1234/sorter.c
set head = $myfile:h -- gets value /usr/users/abcd1234
set tail = $myfile:t -- gets value sorter.c
set root = $myfile:r -- gets value /usr/users/abcd1234/sorter
set extension = $myfile:e -- gets value c
Boolean expressions
$?VARIABLE -- test if VARIABLE is defined
== -- test if two strings are equal
!= -- test if two strings are diferent
=~ -- test if the string on the left matches the string pattern on the right
(the expression can can contain *, meaning "any string ofs characters, of
length 0 or more")
!~ --test if the string on the left does not match the string pattern on the
right
-e $file -- test if $file exists
-d $file -- test if $file exists and is a directory
-f $file -- test if $file exists and is a regular file
-r $file -- test if $file exists and is readable by the current process
-w $file -- test if $file exists and is writable by the current process
-x $file -- test if $file exists and is executable by the current process
Boolean expressions can be combined using && (conjunction), ||
(disjunction) and ! (negation).
Arithmetic operations
set aa = 2+2 -- variable aa gets value '2+2'
@ aa = 2+2 -- variable aa gets value 4
@ a++
-- now, aa has value 5.
Arbitrary arithmetic expressions with +, -, *, /, ++, -- are allowed.
One line conditional statement
if (BOOLEAN-EXPESSION) COMMAND
if (-r comments.txt) cat comments.txt >> summary.txt
Notice that there are no words "then" or "end".
Notice that the statement must be on a the same line (unless line breaks are
escaped).
If-then-else statement
if (EXPR1) then
...
...
else if (EXPR2) then
...
...
else
...
...
endif
There can be any number else-if parts.
Else-if and else parts are optional.
Switch-case statement
switch (EXPR)
case STRINGPATTERN1:
...
...
breaksw
case STRINGPATTERN2:
case STRINGPATTERN3:
...
...
breaksw
default:
...
...
endsw
Foreach loop
foreach VARNAME LIST
...
...
end
For instance:
foreach user ($users)
grep $user /etc/passwd
end
foreach file (csc*)
if (! -d $file) chmod o-r $file
end
While loop
while (EXPR)
...
...
end
Other features
If you use a file pattern with a wildcard (e.g. csc*), the pattern will expand to a list of files whose names match the pattern.
There are no functions, procedures, methods, subroutines in csh or tcsh. Instead, one can use aliases with parameters and goto statements.
To obtain output of a command for processing in the script, enclose the
command in backquotes:
set fileInfo = `ls -l project.java`
C and TC shell initialization
There are login and non-login shells and interactive and non-interactive
shells as explained in the chart below.
Users can customize their shell behavior by placing shell commands in files ~/.cshrc and ~/.login. The commands in these files are executed by new shells, as described in the chart. Executing commands in these files should be contrasted with executing the files themselves -- executing the files would mean that the shell forks and spawns a child shell which executes the commands in file -- these would not initialize the parent shell. Executing commands in in a file by a shell is called sourcing the file.
| Interactive shell (one which displays prompt) |
Non-interactive shell (one which executes commands in a script) |
|
| Login shell (the first shell in a new session) |
sources ~/.cshrc then sources ~/.login |
sources ~/.cshrc ??? TEST IT |
| Non-login shell (any subsequent shell in a session) |
sources ~/.cshrc | sources ~/.cshrc -- if specified as #!/bin/(t)csh no initialization if specified as #!/bin/(t)csh -f |
After you edit ~/.cshrc and /.login to test the changes in the login shell, you need either to logout and login again, or force the login shell to source them:
login_shell% source ~/.cshrc
Environment variables are inherited by every child process. In particular, environment variable definitions sourced by the login shell will be known in all the subsequent interactive and non-interactive shells -- it is enough to define environment variables in ~/.login file which is sourced only by the login shell.
Aliases and shell variables sourced by the login shell are not inherited by subsequent shells. An appropriate pace for aliases and shell variable definitions is ~/.cshrc.
More information on (t)csh initialization can be found in $custom/etc/readme.txt.
Changing shell
Your default shell is specified in your entry in file /etc/passwd
To change your default shell, use chsh command.