Expressions involving variables

Last revision August 6, 2004

Expressions can be used in assigning values to new variables; as substitutions in command lines in the script; and in flow-of-control statements: if, foreach, while, and switch.

Expressions are always enclosed in a pair of parentheses ( and ). Note that you should put blanks (white space) around the parentheses and the operators within them to insure proper parsing.

Arithmetic expressions

Standard arithmetic operators (+ - * /) can be used to operate on integer variable values. To save the results in another variable, however, you should use the @ command rather than the set command for the new variable. For example, you can increment a sum with the value of an argument like this:

    @ sum = 0 # initialize
    @ sum = ( $sum + $1 )

Note that there must be a space between the @ command and the name of the variable that it is setting.

The C-shell cannot do floating point (decimal) arithmetic, for example, 1.1 * 2.3. However, you can invoke the bc calculator program from within a shell script to perform decimal arithmetic. Probably the simplest way to do that is to define an alias, called for example, "MATH", that performs decimal arithmetic via the bc program on the variables or constants passed to the alias. For example, you can define this alias in your script

    # Set MATH alias - takes an arithmetic assignment statement
    # as argument, e.g., newvar = var1 + var2
    # Separate all items and operators in the expression with blanks
    alias MATH 'set \!:1 = `echo "\!:3-$" | bc -l`'

This says that the word "MATH" will be replaced by a set command which will set the variable given as the first word following the alias equal to the result of a math calculation specified by the remainder of the words following the alias, starting with the third word (skips the = sign), which is piped to the bc program to perform.

For example, you can use this MATH alias in a shell script to multiply two floating point values like this:

    set width = 20.8
    set height = 5.4
    MATH area = $width * $height
    echo $area

Note to experts: normally, you would quote the asterisk character in a command line like the one shown above, so the shell does not try to interpret it as the filename wildcard matching character. But the alias expansion is done first, before filename matching, and as a result, the asterisk becomes protected by the quotes in the alias.

Logical expressions

These are usually used in if statements for conditional execution. Logical expressions always evaluate to either the value 1 if true, or value 0 if false. The result of a logical expression can also be assigned to another variable with the @ operator.

These expressions test whether a variable equals another, or a constant value, or is greater than or less than another value. There are some special advanced tests, but the basic ones are indicated by the following operators, with a variable or constant on either side. To get a variable's value, you must, of course, use the $ operator. Character constants should be enclosed in a pair of quote characters. Use either single (') or double (") quotes, as long as you use the same type on both ends of the constant. If the variable being tested may contain blanks or other special shell characters as part of its value, then it must also be enclosed in quotes, but only double quotes can be used for variables, e.g., "$a".

      ( $a < $b )
Tests if the numeric value of variable a is less than the numeric value of variable b. You will get an error message if either variable does not contain a numeric string.

      ( $a <= 5 )
Tests if numeric value of variable "a" is less than or equal to numeric value 5. You will get an error message if the variable a does not contain a numeric string.

      ( $a > $b )
"Greater than" works the same as "less than". There is also a "greater than or equal" test, using the operator >= Again, you will get an error message if either variable does not contain a numeric string.

      ( $a == 5 )
Tests if the numeric value of variable a is exactly equal to numeric value 5. Again, you will get an error message if the variable a does not contain a numeric string.

      ( "$c" == "yes" )
Tests if the string value of variable c is exactly equal to the character string constant yes.

Logical expressions can be modified by the "NOT" (!) operator or combined with the "OR" (||) or "AND" (&&) operators. Examples:

     ( ! "$c" == "yes" )
The logical NOT operator -- the exclamation point -- can be put at the front of any expression (inside the parentheses) to reverse the result of the expression. That is, whenever the expression would normally give a "true" result, it now gives a "false" result, and vice-versa. In this example, the overall expression is true whenever the value of the variable c is not equal to the constant string "yes".

      ( $a > 1 && $a < 5 )
Tests if the value of variable a is greater than numeric value 1 and also less than numeric value 5. Both cases have to be true for the expression to evaluate "true".

      ( $c == "yes" || $c == "YES" )
Tests if value of variable c is either the character string constant yes or the string constant YES (remember that upper and lower case are not the same). If it is equal to either one, then the expression evaluates "true".

Built-in logical tests for file existence.

The C-shell has built in tests for existence or characteristics of a file. These tests are made with a special form of a logical expression in which a variable substitution or constant string is preceded by a one letter operator introduced with the minus sign. For example, the expression
     ( -f "junk" )
evaluates to "true" if there is an existing plain file (not a directory or special file) in the current directory with the name junk. Similarly, if the first shell script argument was the string subdir, then the expression
     ( -d $1 )
evaluates to "true" if subdir is the name of a existing directory (not a plain file) in the current directory.

The complete list of these operators, and what they test for, is:

-e tests if a file exists (it can be any type of file)
-f tests for an existing plain file
-d tests for an existing directory
-z tests for an existing plain file of zero size (that is, an empty file)
-r tests if you have read access to a file
-w tests if you have write access to a file
-x tests if you have execute access to a file
-o tests if you own a file

Pattern matching expressions.

A more advanced feature allows you to test if a variable value matches a pattern instead of just whether it is an exact match to a character string. Read about this in the C-shell reference manual.

Comments or Questions?