C Shell Programming

Shell-scripts

# ... comment; special meaning when used as first symbol in first line

First Line of a Script


# execute the shell denoted by the variable shell
#!/bin/sh execute Bourne shell (BSD)
#!/bin/csh execute C shell
#!/bin/csh -f fast C shell startup = do not read the ~/.cshrc-file (BSD)
[^#]* if the first symbol in the first line is not #, then execute the Bourne shell
#!/.../program execute program with this script as stdin

Conditional Statements


    if (expr) cmd
  
    if (expr) then
      cmd(s)
    endif
  
    if (expr) then
      cmd(s)
    else
      cmd(s)
    endif
  
    if (expr) then
      cmd(s)
    else if (expr) then
      cmd(s)
    else
      cmd(s)
    endif
  

Looping and Control


    foreach var (wordlist)
      cmd(s)
    end
  
    while (expr)
      cmd(s)
    end

    repeat count cmd
  

break exit from innermost loop
continue continue with next iteration of innermost loop
shift shift variable argv one position
shift name shift variable name one position
goto name branch to label name
name: label

Interrupts


onintr default interrupt handling (terminate shell script)
onintr - ignore interrupts
onintr label branch to label if interrupt occurs

Selection


    switch (str)
    case pattern1:
      cmd(s)
      breaksw
    case pattern2:
      cmd(s)
      breaksw
    default:
      cmd(s)
      (breaksw)
    endsw
  

Example 1:
If variable number has the value 1 or there is a file beginning with a or b and ending with x then say "ok"

% if (($number == 1) || (-e [ab]*x)) echo ok

It is not possible to ask for files "not beginning/ending/... with ..." (but see example 4 and 5!)

Example 2:
If there is a file file1 and its length is greater than 0 increment variable i


  % ls
  file1 file2 file3 file4
  % @ i = 0
  % if (-e file1 && !(-z file1)) @ i ++
  % echo $i
  1
  
Example 3:
Add up numbers in a text file

  % cat result
  100
  200
  300
  400
  % @ sum = 0
  % foreach number (`cat result`)
  ? @ sum += $number
  ? end
  % echo $sum
  1000
  
Example 4:
If there are files not beginning with an a or a d then print ok

  % alias adf 'ls|grep -v "^[ad]">/dev/null;if ($status==0) echo ok'
  
make a file listing; pipe the output into grep and search for lines not beginning with a or d (you have to quote the brackets!) and throw away the output of grep.
If all of this was ok ($status is quoted by the leading ', otherwise it would be the status of the last command: echo $sum from example 3), then print ok.

Example 5:
If there are ... (see 4)

% set first = "ja" (to get only one ok)
% foreach file (`ls`)
? if (($file !~ [ad]*) && ($first == "ja") then
? set first = "nein"
? echo ok
? endif
? end
% unset first

Example Scripts


  % cat /bin/SEARCH
  #!/bin/csh -f
  # SEARCH: searches for patterns in requested files.
  #         Uses grep to look for specified patterns in each file.
  #         Reports filename and line number where pattern is found.
  # Usage:  SEARCH pattern(s)
                                                  
  set com = $0                                    #
  if ($#argv == 0) then                           # must have at least
   echo "Usage: $com:t pattern(s)"                # 1 argument
   exit 1                                         #
  endif                                           #
                                                  #
  set flist =  " "                                #
  set plain = `ls -a | grep '^\.*[#0-9a-zA-Z].*'` # get list of plain files
  foreach file ($plain)                           #
   file $file | grep "text" > /dev/null || \      # get list of ASCII files
   file $file | grep "script" > /dev/null || \    #
   file $file | grep "command" > /dev/null        #
   set ok = $status                               #
   if ($ok == '0') set flist = "$flist $file"     # add text-file
  end                                             #
                                                  #
  foreach pattern ($argv[*]:q)                    # loop over quoted patterns
   echo " "                                       # extra line for read-
   echo "$pattern":                               # ability; display pattern
   echo '-------------------------------'         #
   grep -n "$pattern" $flist                      # search all files for pattern
  end
  % cat /bin/SHOW_FILES
  #!/bin/csh -f
  # to display plain files (links)
  # usage: SF (pattern)
  #
  ls -l $* | grep ^- | tee '.file(s)' | more      # display plain files and
  echo '       ---------------'                   # write them to '.file(s)'
  mv '.file(s)' 'file(s)'                         # rename '.file(s)'
  echo -n '           '                           #
  wc -l 'file(s)'                                 # count lines in 'file(s)'
  rm 'file(s)'                                    #
  ls -l $* | grep ^l | tee '.link(s)' | more      # display links and write them
  set num = `wc -l '.link(s)' | awk '{print $1}'` # to '.link(s)', count lines
  mv '.link(s)' 'link(s)'                         # rename '.link(s)'
  if ($num != '0') then                           # if number of links > 0 then
   echo '       ---------------'                  # write number to screen
   echo -n '           '
   wc -l 'link(s)'
  endif
  rm 'link(s)'
  % cd /F90
  % SHOW_FILES
  -rwxr-----   1   peter  edvz   3340  libf90.a
  -rwxr--r--   1   peter  edvz  67862  program
  -rw-rw-r--   1    root  edvz   2346  program.f90
  -rw-rw----   1   peter  edvz  25478  program.o
         ---------------
             4 file(s)
  %