![]() |
|||||
|
|||||
| Updated 15 February 2009 |
If you're using a Unix based operating system such as Linux then you're going to need to know your way around a unix shell. The shell is where you manage your files, and run utilities and applications.
As an artist you may think you don't need to know about the shell, that it is 'too techie' or a waste of your time. However, the truth is that with a bit of basic knowledge you'll be able to get your work done much more efficiently than you ever could with a GUI based file manager, especially when dealing with image sequences. And with OSX now providing the option of a slick interface over the top of a Unix core and shell, you can have the best of both worlds.
This guide starts at the very basics, but there are some nifty 'power tips' later on, some real time savers I wish I had known earlier. So if you've already got some experience with unix shells don't be afraid to skip forward.
This tutorial is written for the 'tcsh' shell, which is not the default unix shell, but seems to be very popular, particularly in the VFX industry, and it is the shell I prefer because of a few handy features. Other shells include the original 'sh', and 'bash' which is the default shell under most Linux systems. The shell you use is a setting stored along with your password, which is either in the /etc/passwd file or on a special server on your network (ask your sysadmins for help here).
To find out which shell you are currently using, run echo $SHELL, which should then report something like '/bin/tcsh' or '/bin/bash'.
Most things work exactly the same between all the shells, but certain things such as setting environment variables are slightly different.
The shell has a 'current directory' that you are working in. The commands you execute will assume you're operating on the files contained within the current directory (unless you supply full path names). To see what directory you are currently in, use the pwd command (pwd is short-hand for 'print working directory' - most unix commands have very short names as you are frequently typing them). When you execute pwd it will display the full path name of the directory you're currently working in. When you start a new shell the current directory will be set to your home account directory.
You navigate to other directories using the cd command (change directory). If you run this command by itself it will return you to your account's home directory, otherwise you specify a path name after the command to move to that location, for example: cd /usr/local/aw/maya6.0. That example used an 'absolute path' which is a full path name starting from the root directory (i.e. the path starts with the '/' character, which is the top of your directory tree). You can also cd by a 'relative path', which is a partial path name relative to your current directory. For example, if you were in a directory and it contained a sub-directory called 'shots' you could do: cd shots and you would then be in that directory.
There are two special directory names used in relative paths. The first one is '..' (two dots) which represents the parent directory, and the other is '.' (single dot) which represents the current directory. So, in our previous example you had moved into a sub-directory named 'shots' and you wanted to go back one level you simply type: cd ... There is another handy directory name called '~' (tilda) which represents your home account, so running 'ls ~' lists the files in your home directory. You can also add a username to this to represent someone else's home account, for example '~jsmith'. Note though, that the '~' character only has meaning within the shell, so you won't be able to use it in file browsers of applications.
Finally, there is a handy shortcut for returning to the directory you were previously in, which is cd -. For example, if you are in your home account, then do cd /usr/local/aw/maya6.0, you can then type cd - and you will be returned to your home account again.
You list files with the ls command, which by default shows you a list of all non-hidden files in the current directory. You can also give it a directory as an argument (e.g. ls /tmp), and it will show you the files in that directory instead.
The listing will only contain file and directory names by default, so to get more info you add the -l flag (for 'long' output), which will then show you file sizes, last modification dates, file owner and permissions:
-rw-r--r-- 1 chapman liquidmaya 9707 Mar 30 2004 liquid.jpg -rw-r--r-- 1 chapman liquidmaya 5076 Mar 30 2004 sflogo.png
You can also sort the list based on most of these attributes. The most common one I end up using is 'ls -ltr' which lists the files with all their details (-l), in order of their time/date stamp (-t) but listed in reverse order (-r), so you can see the most recently modified files at the bottom of the list.
The file sizes are shown in bytes by default, all very technical, precise and unixy, but not so helpful, so try adding the -h flag, for 'human' mode, which will show you file sizes in kilobytes, megabytes and gigabytes.
Finally, if a file starts with the period/dot character, it is considered to be a hidden file, and isn't normally shown in an ls listing. If you want to see these files, add the -a (all) flag. Most configuration files are 'dot files'.
To copy a file from one place to another, use the cp command (short for copy), with two arguments, the first is the source file, the second is the destination directory or filename. You can copy more than one file at a time, in this case the last argument must be a directory, and any preceding filenames are the source files to copy. See the section on wildcard matching below for specifying many files to copy by pattern matching.
If you want to copy whole directories, including all the files and subdirectories they contain, you need to specify the -R argument to copy, e.g. 'cp -R /tmp/some_directory /home/users/me/'
If you want to move files instead of copying them, just substitute mv (short for move) instead of cp.
To delete files, use the rm command (short for remove), with one or more names of files to delete as arguments. To delete an empty directory, use the rmdir command. To recursively delete a directory and everything under it, use rm -rf and one or more files or directories as arguments. The flags passed here are -r for recursive, and -f for force, which will delete all files, even if they are write protected.
Most unix commands can take multiple files as arguments, and rather than listing each filename you can specify a pattern to match, known as a wildcard. You might already be familiar with the simplest form of wildcard, the asterisk (*) which matches everything, most commonly used to list, delete or copy all files with a certain extension, e.g. 'rm *.jpg' will delete all files with the jpg extension.
It is important to understand though, that the commands themselves do not usually know anything about wildcards, they just know how to accept multiple filenames as arguments. It is the shell itself that expands the wildcards into a list of filenames, and passes that list off to the commands. This idea is commonly overlooked, but helps to explain a lot of things and makes the process of dealing with wildcards a lot easier to understand in the long run, for example knowing when to wrap your wildcards in quotes so that they are not expanded on their way to the commands, such as with the find command mentioned below.
Here is a quick outline of the most common forms of wildcard matching, and some examples:
| Symbol | Meaning | Example |
| * | any characters, any number of times | 'ls *.jpg' lists all JPG files (like wah.jpg, foo.jpg, my_cool_picture.jpg, hot_wet_llama.jpg, etc) |
| ? | any single character | 'ls my_maya_scene_v??.ma' lists all Maya scenes starting with 'my_maya_scene_v', then two characters, then '.ma' (like my_maya_scene_v01.ma, my_maya_scene_v02.ma, etc) |
| [abc] | any character listed in the braces | 'ls [abc].jpg' lists any files matching 'a.jpg', 'b.jpg' or 'c.jpg' |
| [a-z] | any character in the range specified | 'ls blah_0[1-4].jpg' lists all files starting with 'blah_0' then one of the numbers 1 to 4, then ending with '.jpg' (e.g. blah_01.jpg, blah_02.jpg, etc). [a-z] and [0-9] are commonly used to match a single letter or single digit |
| [^abc] | any character not in the list | 'ls [^b]ar.jpg' would match car.jpg, far.jpg, tar.jpg but not bar.jpg |
Any combination of the above symbols can be strung together to create some quite complex wildcard patterns. Note however, that these wildcard expressions are quite simple, and vary considerably compared to regular expressions (or just regexps) which can be used to match very complex expressions, usually in search and replace functions of text editors or scripting languages. We won't be covering regexps in this article though.
If you're making anything but the simplest pattern to match files for deletion or something else that is potentially destructive, you should always test the match with an ls command first.
You can print the contents of a file to the shell with the cat command. However unless it is a very short file, it is most likely going to scroll off the top of the terminal and you'll only see the end of it. If you want to view a file a screenfull at a time, and be able to move back and forth, and search for things then use either less or more. I'm sure at one point there was major feature differences between these, but they seem pretty interchangeable to me these days. When you first run either one on a file, you'll see the first 'page' (screen or terminal window full) of the file. Press the up/down keys to move a line at a time, or the space key to go a page at a time. The 'q' key will quit out. If you want to search or jump to some known text, hit the forward slash key ('/') and enter some text and press return.
If you're only interested in the first few lines of a file you can run the head command on the file, and it will show you the first dozen lines. You can give it a -NN flag, where 'NN' is a number, and it will show you that many lines instead. The tail command works exactly the same way, but shows you the end section of a file, very useful when looking at output/error logs.
If you want to know if two files are the same, you can run the diff command, listing both files as arguments. This will tell you if the contents of the two files match, and show you any differences in a pretty cryptic way. Most systems now have a graphical diff utility installed, such as xxdiff or kompare which will show you the two files side by side, with the differences highlighted in a more intuitive way. Diffing is pretty handy when you have one thing that you know works, and one that doesn't, and you want to see what the difference is (for example, an ascii RIB file that renders correctly and one that produces a black frame).
You can create or modify text files with one of the many text editors installed on a unix system (it seems everyone has their own favourite). There are two types of editors: those that run within the shell, and those that bring up a new window and can be used with the mouse. You start all editors the same way, with the name of the editor, and the name of the file to create or edit, e.g. 'nedit some.rib'
One of the simplest and most widely available graphical editors is nedit. Anyone familiar with Windows or the Mac OS should be able to use nedit with no problems at all, but if you look through the menus you'll find it also has some quite advanced functionality .
If you're running Linux with the KDE desktop installed, then a good alternative is kate, which I prefer, as it allows you to have many different files open at once, and easily move between them.
If you don't have one of these two editors installed, or if you need a non-graphical editor, then you'll have to use one of the "old-school" unix text editors. Although quite powerful, they can be very difficult for new unix users. The standard editor is vi, and a much more elaborate editor is emacs. Both of these are very powerful, but rely on the user knowing how to switch between text input and command modes, and various keyboard shortcuts for running commands, which is all a bit daunting when you're just starting out. There is a very simple alternative, which is the pico editor, installed on most systems.
If you're looking for a file somewhere on disk, you can use the find command to locate it. This command is a little tricker to use than you might expect, because it is very flexible, and can be used to find files based on all sorts of attributes, not just their name. To use it to find files by name, use the syntax 'find DIR -name 'NAME'', where 'DIR' is the name of a directory to start the search from (use '.' for the current directory), and 'NAME' is an exact filename or wildcard pattern. Because we want the wildcard pattern to be passed through to the command, rather than being expanded in the shell and passed through as multiple filenames we wrap it in single or double quote characters. If you only want the search to operate on the local physical drives of your computer, rather than across network drives, add the -mount flag. You can add many more flags to this command to search by a file's date, owner, permissions and other things too. Use the 'man find' command to get further info.
Though the find command can be used to locate files based on their name or attributes, if you want to match files based on their content then you'll need to use the grep command, specifying the text to search for and then one or more filenames, like this: 'grep shadowMap *.rib' - this will search for the word 'shadowMap' in all the .rib files of the current directory. The output of the grep command will list each line in the file(s) matching the text. You can also pass it flags to have it just output the name of the file it was found in (-l), or files it was not found in (-L). Use 'man grep' to get more complex usage information.
Hopefully if your work environment is setup well, you won't need to worry too much about file permissions, and the files you and your colleagues create will automatically be readable and editable by the right people. However, it pays to know a little about permissions, most commonly to be able to protect important files from being accidently overwritten.
If you do an ls -l on a file or directory, you'll see the permissions of the files listed in the first column:
drwxr-xr-x 2 chapman users 4096 Jan 9 2005 backup -r--r--r-- 1 chapman users 0 Jan 9 2005 important.txt -rwxrwxrwx 1 chapman users 0 Jan 9 2005 some.rib -rw-r--r-- 1 chapman users 0 Jan 9 2005 some.sl
The first character in the permissions column is usually either a 'd', meaning it is a directory, or otherwise '-' for a normal file (commonly also 'l' for a file link, but we won't cover links in this article). The next 9 characters specify the read, write and execute permissions, first for the owner of the file, then for those in the same user group as the owner, and finally for everyone else. The 'r' or 'read' permission on files means you can read their contents, 'w' or 'write' permission means you can modify them, and 'x' or 'execute' permission means you can run them if they are executable files or scripts.
You can change the permissions of a file with the chmod command, but you can only change permissions on a file you have 'write' access to, otherwise it would defeat the whole purpose. You pass a flag with a '+' to add or '-' to revoke a certain permission, followed by the type of permission (i.e. 'r', 'w' or 'x') and then the name of one or more files to affect. For example, to remove write permission from all files in the current directory you can run 'chmod -w *'. Specifying permissions this way will change them for all three access levels (owner, group and everyone). You can be a little more precise by placing 'u' for owner, 'g' for group or 'o' for everyone in front of the '+'/'-' flags. You can add one, two or all three of these letters together. This example is the same as the previous one, but it will only protect the files against writing for 'group' and 'everyone' - the owner will still be able to write to the files: 'chmod go-w *'. You can also specify permissions with a numerical system (e.g. 'chmod 777 *') but I won't go into that here.
Linked with the three levels of permissions, files also have the name of their owner and group associated with them. In the 'ls -l' output above, all the files are owned by 'chapman', and are in the group 'users'. To change the owner of a file, use 'chown OWNER FILES', where 'OWNER' is the login name of the new owner, and you can specify one or more files to change after that. Similarly, you can run 'chgrp GROUP FILES' to transfer one or more files to another ownership group. Be careful though: if you transfer ownership so that you no longer have write access to the file, you won't be able to transfer it back to yourself or change permissions on it.
You can change permissions or ownership of files in a recursive way, but passing the -R flag to chmod/chown/chgrp and naming a directory.
The permissions that newly created files have by default are determined by the umask command, which is a bit complex to explain here (it uses the numerical permissions system) but if you need to modify that behaviour run 'man umask' to get more info.
This is a fairly advanced command, which normally I wouldn't be covering in an introductory guide like this, except that it is so incredibly powerful when you're dealing with sequences of images, or other file sequences we commonly have to deal with in our industry.
With the tcsh shell, you can run the foreach command to operate on a bunch of files at a time. After running the command, specifying a list of files, it then asks you for one or more commands to run on each file. You stop specifying commands by entering 'end'. Here is a simple example:
foreach file (a.jpg b.jpb c.jpg) foreach? cp $file $file.bak foreach? end
So, we have called the foreach command with the names of three files ('a.jpg', 'b.jpg' and 'c.jpg'). The second argument is telling the command what we want the name of the file to be as we loop through the list. In this case we say to call it 'file', and in the commands below we refer to it by '$file'. If you need to embed the variable in the middle of some text, wrap it in curly braces, so {$file} in this example. After running the command it starts prompting us for things to do with each file as it loops through them, and we say we want to copy the file to a file with the same name, but with '.bak' tacked on the end. We then tell it we're done specifying commands to run by typing in 'end'. The end result of all this is that the following commands will be run:
cp a.jpg a.jpg.bak cp b.jpg b.jpg.bak cp c.jpg c.jpg.bak
In other words, we're making backup copies of the files specified. That is a simple example, but not too useful, as we need to specify all the files to the command. However, you can put wildcard patterns within the parentheses, or even the output of other commands like ls or find by wrapping them in single back-ticks ('`'). Here is a more complex example, which uses the find and grep commands we mentioned earlier to list all the RIB files under the '/tmp/' directory that contain the text '/job/troy/':
foreach file (`find /tmp -name '*.rib'`) foreach? grep -l /job/troy $file foreach? end
So hopefully you're starting to see the power of the unix shell - that various commands can be hooked together to solve all sorts of problems. In this example we're just searching through files, but we could be doing literally anything to them - copying, converting, rendering, etc.
From time to time you'll want to check on how much of your local or network drives you've still got free. By running the df command (disk free) you can see the size, usage and free space on all your local physical drives, and any network share drives that are currently mounted. If you run it with the -h option ('human' format output) you'll get sizes in kb/mb/gb. The output will look something like this, which should be pretty self-explanatory:
Filesystem Size Used Avail Use% Mounted on /dev/md0 514M 293M 195M 61% / /dev/md1 514M 95M 394M 20% /tmp /dev/md2 2.0G 1.5G 444M 78% /var /dev/md3 4.0G 1.3G 2.5G 35% /usr /dev/md4 27G 12G 14G 45% /var/local
That lets you know about your overall disk usage situation, but if you want to know how much disk a certain section of your file hierarchy is using, you'll need the du command (disk usage). Running it with no arguments will list the size of all directories within the current directory, or you can pass it the name of one or more other directories to list. The number next to each entry is normally in kilobytes by default, but again you can pass it the -h flag for 'human' output. If you're interested in the total size of a single directory, pass the -c flag, which will print the total size in addition to the size of any subdirectories.
Unix gives you quite a lot of control over the processes that are currently running on your machine (provided you have permission to mess with them - usually only your own processes). You can easily kill off processes (e.g. if they aren't behaving), pause and restart processes, move processes from the background to the foreground in the shell, and easily monitor how much system resources processes are taking.
To list the processes running on your machine, run the ps command. By default this will show you all the processes your login is running in the current shell. By specifying the -A flag it will list all processes running on the machine you're logged into. This command is mostly useful for checking whether a certain process is running (e.g. "I'm using a Maya license, but I don't see Maya open - is it hung or running in the background?"), or seeing which shell you launched something from.
To see what is using resources on your machine, you'll want to run the top utility. This shows you the top CPU hogging processes currently running, with info about them. By pressing the 'M' key (capital 'm') you can see the top processes ranked by memory usage instead of CPU usage. If you only want to see your own processes, hit the 'u' key and type in your login name. You can see how much memory and percentage of the CPU(s) each task is taking, and also up the top some overall summary information (system load, free memory). Press 'q' to quit.
When you run a command in the shell, it normally will keep control of that shell, so you can't do anything else there until the command has exited. If you want to run a command and retain control of the shell, all you need to do is append the '&' character to the end of the command before pressing return. If you've already run a command which has taken the shell, you can temporarily suspend it by pressing 'CTRL-Z'. You then have a choice of starting the command back up again in the 'foreground' mode (taking the shell) by running the fg command, or running it in the background with the bg command.
If you have a command running that you want to abort, you can press CTRL-C which should kill it.
If there is a process running on your machine that you want to stop, you can abort it with the kill command. In order to issue this command to a process though, you'll need to know the process ID, which you can get from either ps or top. Then just run kill PROC_ID, where 'PROC_ID' is the process ID to kill. By default the command tries to kill the process off in a nice and polite way, sending it a signal asking it to close itself down. However, if you have a stubborn process which is perhaps out of control, you might want to run kill -9 PROC_ID instead. The '-9' is a type of kill signal, which means the operating system will intervene and forcibly remove the process. However, you should be careful with this, as it doesn't give the process any chance to shutdown gracefully, save data, etc.
You can also stop all processes with a certain name by using the killall command. So running something like killall prman will interrupt all running instances of the PRMan renderer currently running. This is handy if something gets out of control and starts spawning lots of the same type of process (perhaps you've just done 'nedit *' in a directory full of files), or if you want to stop a process and you're sure there is only one with that name running, and you don't want to have to go and find its process ID.
If you have a graphical application running that you want to kill, you can run xkill, then when the cursor changes shape to a small rectangular icon just click on the window to kill. Running the normal kill or killall utilities also works for graphical programs, but using xkill you don't need to know the process name or ID, which is much easier.
Most archives under unix are in the TAR format, which was initially developed for tape archiving. A tar file can either be compressed (using gzip compression), or just be a collection of files mashed together. A compressed archive normally has the extension '.tar.gz' or '.tgz', and an uncompressed archive has '.tar'.
To extract a tar archive, run 'tar -xf FILE'. The 'x' flag means to extract, an the 'f' specifies that we're dealing with a file (without it tar assumes you're dealing with a tape drive), and 'FILE' is the name of your archive, which must come right after the '-f' flag. If it is a compressed archive you'll also need to pass the 'z' flag too.
To create a TAR archive, you'll need to use the '-c' flag (for 'create' mode) instead of the 'x' flag above, and you'll also need to specify the names of one or more files or directories to put into the archive. This example creates a compressed archve (because of the 'z' flag) of all the files and directories under '/tmp' and puts them into an archive called 'tmp_backup.tar.gz': 'tar -czf tmp_backup.tar.gz /tmp/*'
You might also have a single file which has been compressed, and this would normally have a '.gz' extension. To extract the file from this just run 'gzip -d FILE'. The -d flag means you're decompressing a file. If you want to compress a file, leave that flag off and just run 'gzip FILE' which will yield you a compressed file, now with a '.gz' extension.
If you've got a ZIP file from the Windows world, you can decompress it with unzip FILE. You can create a zip file with the zip command. The same example from above, but to create a ZIP file this time is: 'zip tmp_backup.zip /tmp/*'
Normally when you run a command, the output is printed to the shell. However, you can tell the shell to redirect that output to a file, by adding the '>' character to the end of the command with a filename to write to. For example, this will create a list of all the files in the current directory, and put that list in a file called 'my_files': 'ls > my_files'. If you want the redirection to add to the end of an existing file, rather than overwriting the file, just use '>>' instead of a single '>'.
Redirecting is handy if you want to save a copy of some output. Another case is if you just want to suppress all output you can redirect it to a special file device called '/dev/null'. Anything sent there will simply disappear into the digital abyss. A handy use of redirecting to a file is to produce small batch files. You can redirect an ls command like in the example above, then edit that file to add commands to be run on the files, then execute that script. This is similar to the foreach looping mentioned previously, but a little safer, because you can see and edit exactly what is to be run, and also it can be saved off for running again in the future.
As well as redirecting the output to a file, you can redirect the output straight to the input of another command. This is known as piping commands together, and is done with the '|' character. For example, if you wanted to see if the user 'jbloggs' was logged into your computer, you could run who, and manually scan the output, or you could run 'who | grep jbloggs' and it will pass the output of the who command to the grep command, which will then search for 'jbloggs'. There is no limit to the number of commands that can be strung together, and unix has many handy little utilities which are all designed to be used in this way.
An environment variable (a.k.a env-var) is a single variable name and value that you can set to control programs that are run in the shell. Common uses are to tell programs where to find the files they need (e.g. MAYA_SCRIPT_PATH tells Maya where to find MEL scripts) or to tell programs to behave in a slightly different way to normal.
To set an env-var under the tcsh shell, you run setenv NAME VALUE. That variable can then be used anywhere in the shell by prefixing the variable name with the dollar sign ('$'). So here's an example where we'll set a new variable and print its value in the shell:
>> setenv MOL 42 >> echo The meaning of life is $MOL The meaning of life is 42
You can also get the value of a variable with 'getenv NAME', or remove a variable with 'unsetenv NAME'. To see a list of all the env-vars currently operating in the shell, run env.
Environment variables only exist within the current shell process, and are propogated down to any new processes launched by that shell. If you want to set an env-var permanently, you'll need to run the setenv command within your .cshrc file (see the 'Saving Settings in your .cshrc File' section later).
Although most of the standard unix commands are very short, some other commands or scripts you run might be longer, or perhaps you want to always run a certain command with some extra flags instead of its default behaviour. In these cases it can be really handy to set a command alias. You can create an alias with 'alias NAME COMMANDS', and 'unalias NAME' to remove an alias.
Here is an example where we'll setup an alias for the ls command, so that it always outputs the file details, and lists
in reverse time order:
>> ls list.gz some.rib some.sl >> alias ls ls -ltr >> ls -r--r----- 1 chapman users 12218 Jan 9 12:28 some.sl -rwxrwxrwx 1 chapman users 3453 Jan 9 13:23 some.rib -rw-r--r-- 1 chapman users 618358 Jan 11 13:51 list.gz
You can even string multiple commands together to be run by a single alias, just separate them with ';' characters, e.g: 'alias mkshot mkdir maya; mkdir maya/scenes; mkdir maya/images'. Everything after the first word is run together when you run the aliased command.
You can list all current aliases by running alias with no arguments. Also handy is 'which COMMAND', that tells you the full path to a command, or what it is aliased to if it is an alias.
People who aren't used to using the shell think there is a lot of typing involved, but once you know a few tricks you'll find that most of the time you really aren't typing very much at all.
The most handy feature is filename completion. By typing a small section of a filename and pressing the '<TAB>' key the shell will automatically fill in the rest of the name for you if there is only a single match. If there is more than one potential match it will fill in as much as it can, and wait for you to type another character or two, then press '<TAB>' again to continue the matching.
Next on the list of most handy shortcuts is being able to scroll back through commands you've run previously. So unlike under a GUI interface where to perform an action twice requires exactly the same amount of effort the second time, to perform something again in the shell all you do is press the up arrow key to scroll back to the command you want, and press '<RETURN>' to run it again. If there is a small change to be made (e.g. a different filename), you can edit the command before pressing '<RETURN>'. If you want to see a list of previous commands you've run, use the history command.
If you are using the tcsh shell, there are a couple of options you can set to make these previous commands even easier to find and run:
bindkey -k up history-search-backward bindkey -k down history-search-forward
After putting these lines in your .cshrc file (see later section) and starting a new shell, you can start typing a few letters of a previous command, then press the up/down arrows to scroll through any matching commands you've previously run.
It is also easy to move around within a long command, making changes. Pressing 'CTRL-A' will move the cursor to the beginning of the line, 'CTRL-E' will move to the end of the line. 'ALT-F' will move forward a word, 'ALT-B' will move back a word. 'CTRL-K' will delete everything on the command line from the cursor to the end of the line.
There are a couple of symbols which you can use in a command to refer to previous commands. '!!' refers to the last command you ran, and '!$' refers to the last word of the last command you run. Most people wouldn't immediately recognise the power of this last one, but because of the way unix works, you quite often run a series of commands on the same file, and the filename is usually the last argument. So instead of having to specify the name of the same file many times over, you can just use '!$'. Here is an example:
mkdir /tmp/imgconvert cd !$ convert /tmp/image.bmp image.tif fcheck !$
In that example we made a directory, moved into it, converted an image into that directory and viewed the image using Maya's 'fcheck' utility. Although we ran multiple commands on the directory and on the file, we only needed to actually type the name of each once. Another way of re-using previous commands is with the '^' character. This tells the shell to run the previous command, but to replace a word in it with something else before running it. Here is another example:
mkdir sequence001 ^001^002 ^002^003
This makes a new directory called 'sequence001', then the next line does the same, but replaces '001' with '002', and the third replaces '002' with '003'. A trivial example, but this is another handy little shortcut you may find yourself using over and over again.
Here's a few useful tips and commands that don't really warrant their own sections.
If there are any commands you would like to have run each time you open a new shell (for example setting environment variables or aliases) then you should add those commands to your .cshrc file. This file exists in your home directory (just create it if need be) and any commands listed in it are run in sequence when you start a new shell.
In addition to your .cshrc file you can create other script files (also known as batch files) containing common sequences of commands you might want to run together. All you need to do is create a new file (any name you like), edit it to contain the commands you want, and give the file executable permissions (with 'chmod +x FILENAME'). You can then run the script by typing its filename.
This brief introduction is an attempt to get you started, and only really scratches the surface of what you can do. As well as books or other tutorials you can find online, unix itself has a few ways of providing its own help for you as you go.
There are online docs for most commands, which you can access with the man command, so in order to see the help for the ls command for example, you simply run 'man ls'. The resulting help shows up in a text viewer (see 'Viewing Files' section earlier for help). The 'man' pages are usually pretty dry, but are good for finding additional flags and options to commands, and the better pages have example uses.
The 'man' system also has a search functionality, for when you are looking for something but you don't know the name of the command. By running 'man -k KEYWORD' it will list all commands matching the keyword you enter.
Whilst the standard unix commands will have 'man' pages, many additional commands and utilities may not. However, most commands will show you some basic usage information if you run them with either -help, --help, or -h flags.
Finally, the tcsh shell has a very useful feature similar to filename completion, but instead for commands. By typing the start of a command's name then pressing 'CTRL-D' it will display a list of all the commands you can run that match that name.
This tutorial is just intended to be a very brief overview of the most commonly used commands and topics of unix shell usage. There are many weighty books you can buy on the topic, and countless more thorough tutorials online. Hopefully though this will get you comfortable in using a unix environment so you can get on with churning out your shots rather than worrying about how to deal with your files.
If you can think of something obvious I've left out here please let me know.