Chapter 7: Tips and Tricks

Neat-o unix commands

The unix command line

The unix "shell"

X-windows cut-and-paste

"Re-directing" input and output

Keeping Logs

"backgrounding" stuff





filename completion and <Ctrl>-D

nice command prompt

changing over from csh to tcsh

Simple awk commands that everyone should have

Tricks for your shell scripts

Starting a csh script

Command-line arguments

Variable substitution

Command substitution

Reading from the keyboard

"if" statements

    Even simple shell scripts will probably need a little flow control in them. For example, when using command-line arguments, something like this is almost always a good idea:

    set mtz_input = "$1"
    if("$1" == "") then
        echo "usage: $0 input.mtz"
        exit 9

    this will remind you if you forget to type something on the command line, (instead of giving you some kind of weird, cryptic error message somewhere deeper in the script). Notice the strucrure of the "if" statement: the "if" line must end with a "then", and the "if" condition applies until a matching "endif" is found. You don't have to indent the way I do, but I find it makes the statements easier to read.

    The csh "if" statement is a little finicky, and can easily crash the whole script if you make a syntax error, or provide unexpected input to it at run-time. But, once you get the hang of it, it can be a very powerful addition to your scripts. You can "man csh" or "man tcsh" for the detailed description of the "if" rules, (as well as everything else the shell can do), but I have a few rules that I find apply to crystallographic applications:

    1. always put text-valued variables in double-quotes ("${variable}"). This way, even if they are empty, the "if" won't crash.
    2. put plenty of spaces around numbers: if(1+2==3) will crash csh on some systems, but if( ( 1 + 2 ) == 3 ) will always work.
    3. decimal numbers do not work in "if" statements: if(3.5 > 3) will crash with a "badly formed number" error.
    4. make sure you never treat a string like a number: if $hires is "2A", then if($hires > 3) will crash. A neat trick to make sure this never happens is to use awk. Instead of set hires = $1, use set hires = `echo $1 | awk '{print $1+0}'`, this will always be a pure number.

    As another example:

    if(-e "${filename}") then
        ls -l ${filename}
        echo "${filename} does not exist! "
        exit 9

    will execute the command: "ls -l ${filename}" only if the filename contained in the variable value ${filename} actually exists, otherwise, the statement in quotes following the "echo" command will be printed out on to the screen. you can also do "wildcard" comparisons in csh "if" statements:

    if("$1" =~ *.mtz) then
        set mtzfile = "$1"

    will set the value of the shell variable "$mtzfile" to the first word on the command line if that word ends in ".mtz". You can also put more complex logic into an "if" statement:

    if((("$1" =~ *.mtz) && (-e "$1")) || (-e "$default_mtz")) then
        echo "okay"

    will print "okay" only if either the first argument on the command line ends in ".mtz", and is an actual, existing file, or if the string stored in the default_mtz variable is an existing file.

Directory tree transfer

Most of us still use FTP to transfer files, but ftp has some serious security problems. It sends your passord, as clear text, in an unencrypted packet that any computer connected to your network segment can read, and get your password. Bad, eh? FTP is also not very good at transferring a whole tree-structured directory in one go.

A popular solution to the cleartext password problem is ssh, which encrypts the password before its sent. Unfortunately, only ssh version 2.x has an ftp program, and most synchrotrons don't have ssh 2.x, and probably won't for the forseeable future (since they have to pay big licenseing fees for it). Some users resort to logging in with ssh to temporarily change their password, do the FTP transfer, and then change their password back. This works (sort of), but can be complicated on remote systems that have slow NIS password updates.

A more direct (and portable) alternative is to send your files directly through an ssh login session. A nice, packaged version of this for x-ray images is in sendhome, but you might want more flexibility for, say, transferring data processing directories from here to there. The following command:

unix% tar cBf - processing | compress -c | ssh "cd /bigdisk/user; uncompress -c | tar xBvf -"

will move the local directory "processing" (and everything in it) to /bigdisk/user/processing (provided /bigdisk/user exists!) using "user"'s account on the remote computer: The files are compressed during the transfer, so this is actually faster than FTP! The command to "pull" files the other way is this:

unix% cd /bigdisk/user
unix% ssh "cd /data/mcfuser/yourname ; tar cBf - . | compress -c" | uncompress -c | tar xvBf -

will move all the files and directories in "/data/mcfuser/yourname" on the remote computer to /bigdisk/user/ on the local machine.

Back to the Elves Manual Table of Contents.

This page is not finished. It will never be finished, and neither will yours. Admit it.

James Holton <>