See shells for an introduction to the shell syntax.
There is (almost ?) no difference between the syntax of csh and tcsh statements used in scripts; the two shells differ mostly in their interactive features (such as capabilities of command completion). There are UNIX/Linux systems which contain csh but not tcsh. Every UNIX/Linux system that contains tcsh, either also contains csh, or csh could be added to it just by creating a symbolic link called csh that 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 syntax of csh, unlike bash, is somewhat similar to that of the C language.
The first line of every csh script should
be
#!/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 shell
that 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 a script:
set echo
set verbose
When the script is executed, they will cause that a trace of execution will be
printed on the screen.
Whitespace
Line breaks and spaces
in csh scripts do
matter! If a construct
you typed does not work,
check again if it is
formatted the same way
as in the examples
below.
Data
The only type of
scalar data is string.
There are no integers,
floats, etc. Whenever we
use something that looks
like an integer, a
string that contains
decimal digits is
created. There is a way
to create an arithmetic
context, in which
integer-like strings are
converted to actual
integers and arithmetic
operations can be
performed; the result of
such operations are
strings containing
decimal digits. Besides
strings, list-arrays of
strings are available.
Shell variables.
By convention names of shell variables are not capitalized."
Remember to put spaces around the = symbol.
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
unset bb
The following are
equivalent:
set ee
set
ee = ''
Shell list-array
variables.
There are only lists of
strings; there are no
lists of lists
-- no nested lists.
set users = ($user1 bcde2345)
set users = (root $users cdef3456 ghij7890)
set $users[0] = defg4567
set
numberOfUsers =
$#users
set users2to4 =
"$users[2-4]"
set allUsers =
"$users[*]"
set lastUser = $users[$]
# last element
Command line parameters
$0 -- the name through which the script was invoked
(test what happens if
you invoke a script
through a symbolic link)
$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 "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 different
=~ -- test if the string
on the left matches the
string pattern on the
right (the expression
can contain *, meaning "any string of
0 or
more characters.")
!~ --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
0 and
empty string both serve as
value false (although
they are not equal); 0
is the default value for
false; 1
serves as value true.
Boolean expressions can be combined using && (conjunction), ||
(disjunction) and ! (negation).
Integer 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 +, -, *, /, ++, --, %
(remainder)
and
parentheses 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:
set
users = (aaaaa111,
bbbbb222, ccccc333)
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 in the present working directory whose names match the pattern.
There are no functions, procedures, methods, subroutines in csh or tcsh. Instead, one can use aliases with parameters or goto statements.
To obtain
the
output of a
command
and
to process
it in the script, enclose the
command in back-quotes:
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 is not the same as executing the files themselves -- executing the files would mean that the shell forks and spawns a child shell that executes the commands in file -- these would not initialize the parent shell. Executing commands in a file by a shell is called sourcing the file.
Interactive shell (one that displays a prompt) |
Non-interactive shell (one that 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 does not source it 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. It is recommended to place
for alias and shell
variable definitions
in ~/.cshrc,
and it is recommended to
use #!/bin/(t)csh -f
at the top of all csh
scripts to prevent them
from sourcing ~/.cshrc.
Changing shell
Your default shell is specified in your entry in file /etc/passwd
To change your default shell, use the chsh command.
Next see: Defining and redefining commands.