This document is intended to give new users an introduction to UNIX and in particular DEC UNIX (the operating system formerly known as OSF/1) and Linux. This document does not go into a large amount of detail or cover many advanced topics. Instead, it is intended to get the new user running, on both feet, so that he or she may then make better use of the system and spend less time learning how to do simple tasks.
At login time, you will see a prompt resembling the following on your screen:
OSF/1 (mssly3.mssl.ucl.ac.uk) (ttypc)
Here, enter your username, and press the key. Our hero, atp, would type the following:
Now, enter your password. It won't be echoed to the screen when you login, so type carefully. If you mistype your password, you'll see the message
and you'll have to try again.
Once you have correctly entered the username and password, you are officially logged into the system, and are free to roam.
As soon as you login, the system starts the shell, and you can type commands to it. Here's a quick example. Here, ATP logs in, and is left sitting at the shell prompt.
Password: atp's password
Last login: Fri May 12 07:41:21 from msslv9.mssl.ucl.
DEC OSF/1 V2.1 (Rev. 250); Tue Aug 30 21:32:53 BST 1994
DEC OSF/1 V2.0 Worksystem Software (Rev. 240)
Access to and use of this system are restricted to authorised individuals.
``/home/atp%'' is the shell's prompt, indicating that it's ready to take commands. (More on what the prompt itself means later.) Let's try telling the system to do something interesting:
/home/atp% make love
make: *** No way to make target `love'. Stop.
Well, as it turns out make was the name of an actual program on the system, and the shell executed this program when given the command. (Unfortunately, the system was being unfriendly.)
This brings us to one burning question: What are commands? What happens when you type ``make love''? The first word on the command line, ``make'', is the name of the command to be executed. Everything else on the command line is taken as arguments to this command. Examples:
/home/atp% cp foo bar
Here, the name of the command is ``cp'', and the arguments are ``foo'' and ``bar''.
When you type a command, the shell does several things. First of all, it looks at the command name, and checks to see if it is a command which is internal to the shell. (That is, a command which the shell knows how to execute itself. There are a number of these commands, and we'll go into them later.) The shell also checks to see if the command is an alias, or substitute name, for another command. If neither of these conditions apply, the shell looks for a program, on the disk, with the command's name. If it finds such a program, the shell runs it, giving the program the arguments specified on the command line.
In our example, the shell looks for the program called make, and runs it with the argument love. Make is a program often used to compile large programs, and it takes as arguments the name of a ``target'' to compile. In the case of ``make love'', we instructed make to compile the target love. Because make can't find a target by this name, it fails with a humorous error message, and we are returned to the shell prompt.
What happens if we type a command to a shell, and the shell can't find a program with the command name to run? Well, we can try it:
/home/atp% eat dirt
eat: command not found
Quite simply, if the shell can't find a program with the name given on the command line (here, ``eat''), it prints an error message which should be self-explanatory. You'll often see this error message if you mistype a command (for example, if you had typed ``mkae love'' instead of ``make love'').
Before we delve much further, we should tell you how to log out of the system. At the shell prompt, use the command
to logout. There are other ways of logging out as well, but this is the most foolproof one.
You should also be aware of how to change your password. The command to do this is passwd or yppasswd which will prompt you for your old password, and your new password. It will ask you to reenter the new password for validation. passwd is used on standalone systems and yppasswd for clusters of machines. Be careful not to forget your password - if you do, you will have to ask the system manager to reset it for you.
Under most operating systems (UNIX included), there is the concept of a file, which is just a bundle of information which is given a name (called a filename). Essentially, anything which is saved on disk is saved in an individual file.
Files are identified by their filenames. For example, the file containing your next publication might be saved with the filename pub100.tex. These names usually identify the file and its contents in some form which is meaningful to you. There is no standard format for filenames as there is under MS-DOS and other operating systems; in general, filenames may contain any character (except / - see the discussion of pathnames, below), and are limited to 256 characters in length.
With the concept of files comes the concept of directories. A directory is just a collection of files. It can be thought of as a ``folder'' which contains many different files. Directories themselves are given names, with which you can identify them. Furthermore, directories are maintained in a tree-like structure; that is, directories may contain other directories.
A file may be referred to by its pathname, which is made up of the filename, preceded by the name of the directory which contains the file. For example, let's say that ATP has a directory called papers, which contains three files: flare1.tex, flare2.tex, and flare3.tex. (Each of these three files contains information for three of ATP's ongoing projects.) To refer to the file flare1.tex, ATP can specify the file's pathname:
As you can see, the directory and file names are separated by a single slash (/). For this reason, filenames themselves cannot contain the / character.
As mentioned, directories can be nested within each other as well. For example, let's say that ATP has another directory, within papers, called notes. This directory contains the files hard-xray and soft-xray. The pathname of the file hard-xray would be
Therefore, the pathname really is a ``path'' which you take to locate a certain file. The directory above a given subdirectory is known as the parent directory. Here, the directory papers is the parent of the notes directory.
Most UNIX systems have a standard layout for files, so that system resources and programs can be easily located. This layout forms a directory tree, which starts at the ``/'' directory, also known as ``the root directory''. Directly underneath / are some important subdirectories: /bin, /etc, /dev, and /usr, among others. These directories in turn contain other directories which contain system configuration files, programs, and so on.
In particular, each user has a home directory, which is the directory set aside for that user to store his or her files. In the examples above, all of ATP's files (such as hard-xray and flare1.tex) were contained in ATP's home directory. Usually, user home directories are contained under /home, and are named for the user who owns that directory. Therefore, ATP's home directory is /home/atp.
In Figure 1.1 a sample directory tree is represented. It should give you some idea of how the directory tree on your system is organized.
Figure 1.1: A typical (abridged) Unix directory tree.
At any given time, commands that you type to the shell are given in terms of your current working directory. You can think of your working directory as the directory in which you are currently ``located''. When you first login, your working directory is set to your home directory - /home/atp in our case. Whenever you reference a file, you may refer to it in relationship to your current working directory, instead of specifying the full pathname of the file.
Here's an example. ATP has the directory papers, and papers contains the file flare1.tex. If ATP wants to look at this file, he can use the command
/home/atp% more /home/atp/papers/flare1.tex
The more command simply displays a file, one screen at a time. However, because ATP's current working directory is /home/atp, he can instead refer to the file relative to his current location. The command would be
/home/atp% more papers/flare1.tex
Therefore, if you begin a filename (such as papers/flare1.tex) with a character other than ``/'', the system assumes that you're referring to the file in terms relative to your current working directory. This is known as a relative pathname.
On the other hand, if you begin a filename with a ``/'', the system interprets this as a full pathname - that is, a pathname including the entire path to the file, starting from the root directory, /. This is known as an absolute pathname.
Under both csh and tcsh(the default shell), your home directory can be referred to using the tilde character (``~''). For example, the command
/home/atp% more ~/papers/flare1.tex
is equivalent to
/home/atp% more /home/atp/papers/flare1.tex
The ``~'' character is simply replaced with the name of your home directory by the shell.
In addition, you can specify other user's home directories with the tilde as well. The pathname ``~ard/letters'' translates to ``/home/ard/letters'' by the shell (if /home/ard is ard's home directory). The use of the tilde is simply a shortcut; there is no directory named ``~'' - it's just syntactic sugar provided by the shell.
Now that we can login, and know how to refer to files using pathnames, how can we change our current working directory, to make life easier?
The command for moving around in the directory structure is cd, short for ``change directory''. You'll notice that many often-used Unix commands are two or three letters. The usage of the cd command is:
where <directory> is the name of the directory which you wish to change to.
As we said, when you login, you begin in your home directory. If ATP wanted to move down into the papers subdirectory, he'd use the command
/home/atp% cd papers
As you can see, ATP's prompt changes to reflect his current working directory (so he knows where he is). Now that he's in the papers directory, he can look at his flare paper with the command
/home/atp/papers% more flare1.tex
Now, ATP is stuck in the papers subdirectory. To move back up to the parent directory, use the command
/home/atp/papers% cd ..
(Note the space between the ``cd'' and the ``..''.) Every directory has an entry named ``..'' which refers to the parent directory. Similarly, every directory has an entry named ``.'' which refers to itself. Therefore, the command
/home/atp/papers% cd .
gets us nowhere.
You can also use absolute pathnames in the cd command. To cd into ARD's home directory, we can use the command
/home/atp/papers% cd /home/ard
Also, using cd with no argument will return you to your own home directory.
Here we can see that ATP has three entries in his current directory: Mail, letters, and papers. This doesn't tell us much - are these directories or files? We can use the -F option on the ls command to tell us more.
/home/atp% ls -F
From the / appended to each filename, we know that these three entries are in fact subdirectories.
Using ls -F may also append ``*'' to the end of a filename. This indicates that the file is an executable, or a program which can be run. If nothing is appended to the filename using ls -F, the file is a ``plain old file'', that is, it's neither a directory, or an executable.
In general, each UNIX command may take a number of options in addition to other arguments. These options usually begin with a ``-'', as demonstrated above with ls -F. The -F option tells ls to give more information about the type of the files involved - in this case, printing a / after each directory name.
If you give ls a directory name, it will print the contents of that directory.
/home/atp% ls -F papers
Or, for a more interesting listing, let's see what's in the system's /etc directory.
/home/atp% ls /etc
Images ftpusers lpc rc.new shells
adm getty magic rc0.d startcons
bcheckrc gettydefs motd rc1.d swapoff
brc group mount rc2.d swapon
brc~ inet mtab rc3.d syslog.conf
csh.cshrc init mtools rc4.d syslog.pid
csh.login init.d pac rc5.d syslogd.reload
default initrunlvl passwd rmt termcap
disktab inittab printcap rpc umount
fdprm inittab.old profile rpcinfo update
fstab issue psdatabase securetty utmp
ftpaccess lilo rc services wtmp
Let's cd up to the top of the directory tree, using ``cd ..'', and then down to another directory: /usr/bin.
/home/atp% cd ..
/home% cd ..
/% cd usr
/usr% cd bin
You can also move into directories in multiple steps, as in cd /usr/bin.
Try moving around various directories, using ls and cd. In some cases, you may run into a foreboding ``Permission denied'' error message. This is simply the concept of UNIX security kicking in: in order to ls or to cd into a directory, you must have permission to do so. We'll talk more about this in Section 9.
It's time to learn how to create directories. This involves the use of the mkdir command. Try the following:
/home/atp% mkdir foo
/home/atp% ls -F
/home/atp% cd foo
Congrats! You've just made a new directory and moved into it. Since there aren't any files in this new directory, let's learn how to copy files from one place to another.
Copying files is done with the command cp:
/home/atp/foo% cp /etc/termcap .
/home/atp/foo% cp /etc/shells .
/home/atp/foo% ls -F
/home/atp/foo% cp shells bells
/home/atp/foo% ls -F
bells shells termcap
The cp command copies the files listed on the command line to the file or directory given as the last argument. Notice how we use the directory ``.'' to refer to the current directory.
A new command named mv moves files, instead of copying them. The syntax is very straightforward.
/home/atp/foo% mv termcap sells
/home/atp/foo% ls -F
bells sells shells
Notice how termcap no longer exists, but in its place is the file sells. This can be used to rename files, as we have just done, but also to move a file to a completely new directory.
Note: mv and cp will overwrite the destination file (if it already exists) without asking you. Be careful when you move a file into another directory: there may already be a file with the same name in that directory, which you'll overwrite! You can avoid this by using the -i option with mv or cp which will prompt you before overwriting the file.
You now have an ugly rhyme developing with the use of the ls command. To delete a file, use the rm command. (``rm'' stands for ``remove'').
/home/atp/foo% rm bells sells
/home/atp/foo% ls -F
We're left with nothing but shells, but we won't complain. Note that rm by default won't prompt you before deleting a file - so be careful. If you accidently delete a file then you may be able to recover it if the disk it was on is backed up regularly. See your system manager for details.
A related command to rm is rmdir. This command deletes a directory, but only if the directory is empty. If the directory contains any files or subdirectories, rmdir will complain.
The commands more and cat are used for viewing the contents of files. more displays a file, one screenful at a time, while cat displays the whole file at once.
To look at the file shells, we can use the command
/home/atp/foo% more shells
In case you're interested what shells contains, it's a list of valid shell programs on your system. On most systems, this includes /bin/sh, /bin/csh, and /bin/tcsh. We'll talk about these different types of shells later.
While using more, press to display the next page of text, and to display the previous page. There are other commands available in more as well, these are just the basics. Pressing will quit more.
Quit more if you haven't already, to return to the shell prompt, and try cat /etc/termcap. The text will probably fly by much too quickly for you to read it. The name ``cat'' actually stands for ``concatenate'', which is the real use of the program. The cat command can be used to concatenate the contents of several files and save the result to another file. This will be discussed later.
The command used to access man pages is man. For example, if you're interested in finding out about the other options of the ls command, you can type
/home/atp% man ls
and the man page for ls will be displayed.
Unfortunately, most of the man pages out there are written for those who already have some idea of what the command or resource does. For this reason, man pages usually only contain the hardcore technical details of the command, without a lot of tutorial. However, man pages can be an invaluable resource for jogging your memory if you forget the syntax of a command. Man pages will also tell you a lot about the commands which we won't tell you in this book.
You should try man for the commands we've already gone over, and for new commands. You'll notice some of these commands won't have man pages. This could be for several reasons. For instance the command might be an internal shell command, or an alias (as discussed in Section 1.2), in which case it would not have a man page of its own. One example is cd, which is a shell internal command. The shell actually processes the cd - there is no separate program which contains this command.
If you don't know the name of a command then you can try using the -k option to man which will search the man pages for keyward you specify. For instance.
/home/atp% man -k print
will list all occurences and hence commands associated with printing.
Note that options usually begin with a ``-'', and in most cases multiple one-letter options may be combined using a single ``-''. For example, instead of using the command ls -l -F, it is adequate to use ls -lF.
Instead of listing all of the options available for each of these commands, we'll only talk about those which are useful or important at this time. In fact, most of these commands have a large number of options (most of which you'll never use). You can use man to see the manual pages for each command, which list all of the available options.
Also note that many of these commands take a list of files or directories as arguments, denoted by ``<file1> ... <fileN>''. For example, the cp command takes as arguments a list of files to copy, followed by the destination file or directory. When copying more than one file, the destination must be a directory.
UNIX is a multitasking, operating system. Multitasking is very useful, and once you get used to it, you'll use it all of the time. Before long, you'll be able to run programs in the ``background'', switch between multiple tasks, and ``pipeline'' programs together to achieve complicated results with a single command.
Many of the features we'll be covering in this section are features provided by the shell itself. Be careful not to confuse UNIX (the actual operating system) with the shell - the shell is just an interface to the underlying system. The shell provides a great deal of functionality on top of UNIX itself.
The shell is not only an interpreter for your interactive commands, which you type at the prompt. It is also a powerful programming language, which allows you to write shell scripts, to ``batch'' several shell commands together in a file. Use of shell scripts is a very powerful tool, which will allow you to automate and expand your usage of UNIX. See Section 9.1 for more information.
There are several types of shells in the UNIX world. The two major types are the ``Bourne shell'' and the ``C shell''. The Bourne shell uses a command syntax like the original shell on early UNIX systems, such as System III. The name of the Bourne shell on most UNIX systems is /bin/sh (where sh stands for ``shell''). The C shell (not to be confused with sea shell) uses a different syntax, somewhat like the programming language C, and on most UNIX systems is named /bin/csh.
On most systems, there are several variations of these shells available. The two most commonly used are the Bourne Again Shell, or ``Bash'' (/bin/bash), and Tcsh (/bin/tcsh). The default shell on our DEC UNIX systems will be Tcsh. This is an expanded version of the original C shell and contains many user friendly features.
As far as normal commands, such as cp and ls, are concerned, the type of shell you're using doesn't matter - the syntax is the same. Only when you start to write shell scripts or use some of the advanced features of the shell do the differences between shell types begin to matter. If you're really curious at this point, read the man pages for sh, csh and tcsh.
A key feature of most Unix shells is the ability to reference more than one filename using special characters. These so-called wildcards allow you to refer to, say, all filenames which contain the character ``n''.
The wildcard ``*'' refers to any character or string of characters in a filename. For example, when you use the character ``*'' in a filename, the shell replaces it with all possible substitutions from filenames in the directory which you're referencing.
Here's a quick example. Let's suppose that ATP has the files frog, joe, and stuff in his current directory.
frog joe stuff
To access all files with the letter ``o'' in the filename, we can use the command
/home/atp% ls *o*
As you can see, the use of the ``*'' wildcard was replaced with all substitutions which matched the wildcard from filenames in the current directory.
The use of ``*'' by itself simply matches all filenames, because all characters match the wildcard.
/home/atp% ls *
frog joe stuff
Here are a few more examples.
/home/atp% ls f*
/home/atp% ls *ff
/home/atp% ls *f*
/home/atp% ls s*f
The process of changing a ``*'' into filenames is called wildcard expansion and is done by the shell. This is important: the individual commands, such as ls, never see the ``*'' in their list of parameters. The shell expands the wildcard to include all of the filenames which match. So, the command
/home/atp% ls *o*
is expanded by the shell to actually be
/home/atp% ls frog joe
One important note about the ``*'' wildcard. Using this wildcard will not match filenames which begin with a single period (``.''). These files are treated as ``hidden'' files - while they are not really hidden, they don't show up on normal ls listings, and aren't touched by the use of the ``*'' wildcard.
Here's an example. We already mentioned that each directory has two special entries in it: ``.'' refers to the current directory, and ``..'' refers to the parent directory. However, when you use ls, these two entries don't show up.
frog joe stuff
If you use the -a switch with ls, however, you can display filenames which begin with ``.''. Observe:
/home/atp% ls -a
. .. .login .tcshrc frog joe stuff
Now we can see the two special entries, ``.'' and ``..'', as well two other ``hidden'' files - .tcshrc and .login. These files are startup file used by tcsh when ATP logs in. More on them in Section 9.2.2.
Note that when we use the ``*'' wildcard, none of the filenames beginning with ``.'' are displayed.
/home/atp% ls *
frog joe stuff
This is a safety feature: if the ``*'' wildcard matched filenames beginning with ``.'', it would also match the directory names ``.'' and ``..''. This can be dangerous when using certain commands.
Another wildcard is ``?''. The ``?'' wildcard will only expand a single character. Thus, ``ls ?'' will display all one character filenames, and ``ls termca?'' would display ``termcap'' but not ``termcap.backup''. Here's another example:
/home/atp% ls j?e
/home/atp% ls f??g
/home/atp% ls ????f
As you can see, wildcards allow you to specify many files at one time. In the simple command summary, in Section 3, we said that the cp and mv commands actually can copy or move multiple files at one time. For example,
/home/atp% cp /etc/s* /home/atp
will copy all filenames in /etc beginning with ``s'' to the directory /home/atp. Therefore, the format of the cp command is really
cp<file1> <file2> <file3>
... <fileN> <destination>
where <file1> through <fileN>is a list of filenames to copy, and <destination> is the destination file or directory to copy them to. mv has an identical syntax.
Note that if you are copying or moving more than one file, the <destination> must be a directory. You can only copy or move a single file to another file.
Many UNIX commands get input from what is known as standard input and send their output to standard output (often abbreviated as ``stdin'' and ``stdout''). Your shell sets things up so that standard input is your keyboard, and standard output is the screen.
Here's an example using the command cat. Normally, cat reads data from all of the filenames given on the command line and sends this data directly to stdout. Therefore, using the command
/home/atp/papers% cat flare1.tex flare2.tex
will display the contents of the file flare1.tex followed by flare2.tex.
However, if no filenames are given to cat as parameters, it instead reads data from stdin, and sends it back to stdout. Here's an example.
As you can see, each line that the user types (displayed in italics) is immediately echoed back by the cat command. When reading from standard input, commands know that the input is ``finished'' when they receive an EOT (end-of-text) signal. In general, this is generated by pressing .
Here's another example. The command sort reads in lines of text (again, from stdin, unless files are given on the command line), and sends the sorted output to stdout. Try the following.
Now we can alphabetize our shopping list... isn't UNIX useful?
Now, let's say that we wanted to send the output of sort to a file, to save our shopping list elsewhere. The shell allows us to redirect standard output to a filename, using the ``>'' symbol. Here's how it works.
/home/atp/papers% sort > shopping-list
As you can see, the result of the sort command isn't displayed, instead it's saved to the file shopping-list. Let's look at this file.
/home/atp/papers% cat shopping-list
Now we can sort our shopping list, and save it, too! But let's suppose that we were storing our unsorted, original shopping list in the file items. One way of sorting the information and saving it to a file would be to give sort the name of the file to read, in lieu of standard input, and redirect standard output as we did above. As so:
/home/atp/papers% sort items > shopping-list
/home/atp/papers% cat shopping-list
However, there's another way of doing this. Not only can we redirect standard output, but we can redirect standard input as well, using the ``<'' symbol.
/home/atp/papers% sort < items
Technically, sort < items is equivalent to sort items, but the former allows us to demonstrate the point: sort < items behaves as if the data in the file items was typed to standard input. The shell handles the redirection. sort wasn't given the name of the file (items) to read; as far as sort is concerned, it was still reading from standard input as if you had typed the data from your keyboard.
This introduces the concept of a filter. A filter is a program which reads data from standard input, processes it in some way, and sends the processed data to standard output. Using redirection, standard input and/or standard output can be referenced from files. sort is a simple filter: it sorts the incoming data and sends the result to standard output. cat is even simpler: it doesn't do anything with the incoming data, it simply outputs whatever was given to it.
We've already demonstrated how to use sort as a filter. However, these examples assumed that you had data in a file somewhere, or were willing to type the data to standard input yourself. What if the data you wanted to sort came from the output of another command, such as ls? For example, using the -r option with sort sorts the data in reverse-alphabetical order. If you wanted to list the files in your current directory in reverse order, one way to do it would be:
/home/atp/papers% ls > file-list
/home/atp/papers% sort -r file-list
Here, we saved the output of ls in a file, and then ran sort -r on that file. But this is unwieldy and causes us to use a temporary file to save the data from ls.
The solution is to use pipelining. Pipelining is another feature of the shell which allows you to connect a string of commands in a ``pipe'', where the stdout of the first command is sent directly to the stdin of the second command, and so on. Here, we wish to send the stdout of ls to the stdin of sort. The ``|'' symbol is used to create a pipe:
/home/atp/papers% ls sort -r
This command is much shorter, and obviously easier to type.
Another useful example - using the command
/home/atp/papers% ls /usr/bin
is going to display a long list a files, most of which will fly past the screen too quickly for you to read them. Instead, let's use more to display the list of files in /usr/bin.
/home/atp/papers% ls /usr/bin more
Now you can page down the list of files at your own leisure.
But the fun doesn't stop here! We can pipe more than two commands together. The command head is a filter which displays the first lines from an input stream (here, input from a pipe). If we wanted to display the last filename in alphabetical order in the current directory, we can use:
/home/atp/papers% ls sort -r head -1
where head -1 simply displays the first line of input that it receives (in this case, the stream of reverse-sorted data from ls).
Using ``>'' to redirect output to a file can be destructive: in other words, the command
/home/atp/papers% ls > file-list
can either overwrite the contents of the file file-list, or cause the command to fail with the message file exists. The second case is the default at MSSL. If, instead, you redirect with the symbol ``>>'', the output will be appended to the named file, instead of overwriting it.
/home/atp/papers% ls >> file-list
will append the output of the ls command to file-list.
Just keep in mind that redirection and using pipes are features provided by the shell - the shell provides this handy syntax using ``>'' and ``>>'' and ``|''. It has nothing to do with the commands themselves, but the shell.
Because there are multiple users on a UNIX system, in order to protect individual user's files from tampering by other users, UNIX provides a mechanism known as file permissions. This mechanism allows files and directories to be ``owned'' by a particular user. As an example, because ATP created the files in his home directory, ATP owns those files, and has access to them.
UNIX also allows files to be shared between users and groups of users. If ATP so desired, he could cut off access to his files, such that no other user could access them. However, on most systems the default is to allow other users to read your files, but not modify or delete them in any way.
As explained above, every file is owned by a particular user. However, files are also owned by a particular group, which is a system-defined group of users. Every user is placed into at least one group when that user is created. However, the system manager may also grant the user access to more than one group.
Groups are usually defined by the type of users which access the machine. For example, on MSSL UNIX system, users will be placed into the group corresponding to their research area. For example xray, solar, computing or plasma etc. There are also a few system-defined groups (such as bin and admin) which are used by the system itself to control access to resources - very rarely do actual users belong to these system groups.
Permissions fall into three main divisions: read, write, and execute. These permissions may be granted to three classes of users: the owner of the file, the group to which the file belongs, and to all users, regardless of group.
Read permission allows a user to read the contents of the file, or in the case of directories, to list the contents of the directory (using ls). Write permission allows the user to write to and modify the file. For directories, write permission allows the user to create new files or delete files within that directory. Finally, execute permission allows the user to run the file as a program or shell script (if the file happens to be a program or shell script, that is). For directories, having execute permission allows the user to cd into the directory in question.
Let's look at an example to demonstrate file permissions. Using the ls command with the -l option will display a ``long'' listing of the file, including file permissions.
/home/atp/foo% ls -l stuff
-rw-r--r-- 1 atp solar 505 Mar 13 19:05 stuff
The first field printed in the listing represents the file permissions. The third field is the owner of the file (atp), and the fourth field is the group to which the file belongs (solar). Obviously, the last field is the name of the file (stuff), and we'll cover the other fields later.
This file is owned by atp, and belongs to the group solar. Let's look at the file permissions. The string -rw-r--r-- lists, in order, the permissions granted to the file's owner, the file's group, and everybody else.
The first character of the permissions string (``-'') represents the type of file. A ``-'' just means that this is a regular file (as opposed to a directory or device driver). The next three letters (``rw-'') represent the permissions granted to the file's owner, atp. The ``r'' stands for ``read'' and the ``w'' stands for ``write''. Thus, atp has read and write permission to the file stuff.
As we mentioned, besides read and write permission, there is also ``execute'' permission - represented by an ``x''. However, there is a ``-'' here in place of the ``x'', so ATP doesn't have execute permission on this file. This is fine, the file stuff isn't a program of any kind. Of course, because ATP owns the file, he may grant himself execute permission for the file if he so desires. This will be covered shortly.
The next three characters, r--, represent the group's permissions on the file. The group which owns this file is solar. Because only an ``r'' appears here, any user which belongs to the group solar may read this file.
The last three characters, also r--, represent the permissions granted to every other user on the system (other than the owner of the file and those in the group solar). Again, because only an ``r'' is present, other users may read the file, but not write to it or execute it.
Here are some other examples of group permissions.
It is important to note that the permissions granted to a file also depend on the permissions of the directory in which the file is located. For example, even if a file is set to -rwxrwxrwx, other users cannot access the file unless they have read and execute access to the directory in which the file is located. For example, if ATP wanted to restrict access to all of his files, he could simply set the permissions on his home directory /home/atp to -rwx------. In this way, no other user has access to his directory, and all files and directories within it. ATP doesn't need to worry about the individual permissions on each of his files.
In other words, to access a file at all, you must have execute access to all directories along the file's pathname, and read (or execute) access to the file itself.
Usually, users on a UNIX system are very open with their files. The usual set of permissions given to files is -rw-r--r--, which will allow other users to read the file, but not change it in any way. The usual set of permissions given to directories is -rwxr-xr-x, which will allow other users to look through your directories, but not create or delete files within them.
However, many users wish to keep other users out of their files. Setting the permissions of a file to -rw------- will not allow any other user to access the file. Likewise, setting the permissions of a directory to -rwx------ will keep other users out of the directory in question.
The command chmod is used to set the permissions on a file. Only the owner of a file may change the permissions on that file. The syntax of chmod is:
Briefly, you supply one or more of all, user, group, or other. Then you specify whether you are adding rights (+) or taking them away (-). Finally, you specify one or more of read, write, and execute. Some examples of legal commands are:
Every time you run a program, you start what is known as a process - which is just a fancy name for a running program. The command ps displays a list of currently running processes. Here's an example:
PID TT STAT TIME COMMAND
24 3 S 0:03 (tcsh)
161 3 R 0:00 ps
The PID listed in the first column is the process ID, a unique number given to every running process. The last column, COMMAND, is the name of the running command. Here, we're only looking at the processes which ATP is currently running. These are tcssh (ATP's shell), and the ps command itself. As you can see, tcsh is running concurrently with the ps command. tcsh executed ps when ATP typed the command. After ps is finished running (after the table of processes is displayed), control is returned to the tcsh process, which displays the prompt, ready for another command.
A running process is known as a job to the shell. The terms process and job are interchangeable. However, a process is usually referred to as a ``job'' when used in conjunction with job control - a feature of the shell which allows you to switch between several independent jobs.
In most cases users are only running a single job at a time - that being whatever command they last typed to the shell. However, using job control, you can run several jobs at once, switching between them as needed. How might this be useful? Let's say that you're editing a text file and need to suddenly interrupt your editing and do something else. With job control, you can temporarily suspend the editor, and back at the shell prompt start to work on something else. When you're done, you can start the editor back up, and be back where you started, as if you never left the editor. This is just one example. There are many practical uses for job control.
Jobs can either be in the foreground or in the background. There can only be one job in the foreground at any one time. The foreground job is the job which you interact with - it receives input from the keyboard and sends output to your screen. (Unless, of course, you have redirected input or output, as described in Section 6.2). On the other hand, jobs in the background do not receive input from the terminal - in general, they run along quietly without need for interaction.
Some jobs take a long time to finish, and don't do anything interesting while they are running. Compiling programs is one such job, as is compressing a large file. There's no reason why you should sit around being bored while these jobs complete their tasks; you can just run them in the background. While the jobs are running in the background, you are free to run other programs.
Jobs may also be suspended. A suspended job is a job that is not currently running, but is temporarily stopped. After you suspend a job, you can tell the job to continue, in the foreground or the background as needed. Resuming a suspended job will not change the state of the job in any way - the job will continue to run where it left off.
Note that suspending a job is not equal to interrupting a job. When you interrupt a running process (by hitting your interrupt key, which is usually it kills the process, for good. Once the job is killed, there's no hope of resuming it; you'll have to re-run the command. Also note that some programs trap the interrupt, so that hitting won't immediately kill the job. This is to allow the program to perform any necessary cleanup operations before exiting. In fact, some programs simply don't allow you to kill them with an interrupt at all.
Let's begin with a simple example. The command yes is a seemingly useless command which sends an endless stream of y's to standard output. (This is actually useful. If you piped the output of yes to another command which asked a series of yes and no questions, the stream of yes's would confirm all of the questions.)
Try it out.
The yes's will continue ad infinitum. You can kill the process by hitting your interrupt key, which is usually . Wait for the screen to stop scrolling. So that we don't have to put up with the annoying stream of yes's, let's redirect the standard output of yes to /dev/null. The special file /dev/null acts as a ``black hole'' for data. Any data sent to it will disappear (The directory /dev hold special files which allow access to system devices like tape drives). This is a very effective method of quieting an otherwise verbose program.
/home/atp% yes > /dev/null
Ah, much better. Nothing is printed, but the shell prompt doesn't come back. This is because yes is still running, and is sending those inane yes's to /dev/null. Again, to kill the job, hit the interrupt key.
Let's suppose that we wanted the yes command to continue to run, but wanted to get our shell prompt back to work on other things. We can put yes into the background, which will allow it to run, but without need for interaction.
One way to put a process in the background is to append an ``&'' character to the end of the command.
/home/atp% yes > /dev/null &
As you can see, we have our shell prompt back. But what is this
 164''? And is the yes command really running?
'' represents the job number for the yes
process. The shell assigns a job number to every running job. Because
yes is the one and only job that we're currently running, it
is assigned job number 1. The ``164'' is the process ID, or
PID, number given by the system to the job. Either number may be used to
refer to the job, as we'll see later.
You now have the yes process running in the background, continuously sending a stream of y's to /dev/null. To check on the status of this process, use the shell internal command jobs.
+ Running yes >/dev/null &
Sure enough, there it is. You could also use the ps command as demonstrated above to check on the status of the job.
To terminate the job, use the command kill. This command takes either a job number or a process ID number as an argument. This was job number 1, so using the command
/home/atp% kill %1
will kill the job. When identifying the job with the job number, you must prefix the number with a percent (``%'') character.
Now that we've killed the job, we can use jobs again to check on it:
+ Terminated yes >/dev/null
The job is in fact dead, and if we use the jobs command again nothing should be printed.
You can also kill the job using the process ID (PID) number, which is printed along with the job ID when you start the job. In our example, the process ID is 164, so the command
/home/atp% kill 164
is equivalent to
/home/atp% kill %1
You don't need to use the ``%'' when referring to a job by its process ID.
There is another way to put a job into the background. You can start the job normally (in the foreground), stop the job, and then restart it in the background.
First, start the yes process in the foreground, as you normally would:
/home/atp% yes > /dev/null
Again, because yes is running in the foreground, you shouldn't get your shell prompt back.
Now, instead of interrupting the job with , we'll suspend the job. Suspending a job doesn't kill it: it only temporarily stops the job until you restart it. To do this, you hit the suspend key, which is usually .
/home/atp% yes > /dev/null
+ Stopped yes >/dev/null
While the job is suspended, it's simply not running. No CPU time is used for the job. However, you can restart the job, which will cause the job to run again as if nothing ever happened. It will continue to run where it left off.
To restart the job in the foreground, use the command fg (for ``foreground'').
The shell prints the name of the command again so you're aware of which job you just put into the foreground. Stop the job again, with . This time, use the command bg to put the job into the background. This will cause the command to run just as if you started the command with ``&'' as in the last section.
+ yes >/dev/null &
And we have our prompt back. jobs should report that yes is indeed running, and we can kill the job with kill as we did before.
How can we stop the job again? Using won't work, because the job is in the background. The answer is to put the job in the foreground, with fg, and then stop it. As it turns out you can use fg on either stopped jobs or jobs in the background.
There is a big difference between a job in the background and a job which is stopped. A stopped job is not running - it's not using any CPU time, and it's not doing any work (the job still occupies system memory, although it may be swapped out to disk). A job in the background is running, and using memory, as well as completing some task while you do other work. However, a job in the background may try to display text on to your terminal, which can be annoying if you're trying to work on something else. For example, if you used the command
/home/atp% yes &
without redirecting stdout to /dev/null, a stream of y's would be printed to your screen, without any way of interrupting it (you can't use to interrupt jobs in the background). In order to stop the endless y's, you'd have to use the fg command, to bring the job to the foreground, and then use to kill it.
Another note. The fg and bg commands normally foreground or background the job which was last stopped (indicated by a ``+'' next to the job number when you use the command jobs). If you are running multiple jobs at once, you can foreground or background a specific job by giving the job ID as an argument to fg or bg, as in
/home/atp% fg %2
(to foreground job number 2), or
/home/atp% bg %3
(to background job number 3). You can't use process ID numbers with fg or bg.
Furthermore, using the job number alone, as in
is equivalent to
/home/atp% fg %2
The shell provides many mechanisms to customize your work environment. As we've mentioned before, the shell is more than a command interpreter - it is also a powerful programming language. While writing shell scripts is an extensive subject, we'd like to introduce you to some of the ways that you can simplify your work on a UNIX system by using these advanced features of the shell.
As we have mentioned before, different shells use different syntaxes when executing shell scripts. For example, Tcsh uses a C-like syntax, while Bourne shells use another type of syntax. In this section, we won't be running into many of the differences between the two, but we will assume that shell scripts are executed using the Bourne shell syntax.
/home/atp% cat chapter1 chapter2 chapter3 > book
/home/atp% wc -l book
/home/atp% lpr book
would concatenate the files chapter1, chapter2, and chapter3 and place the result in the file book. Then, a count of the number of lines in book would be displayed, and finally book would be printed with the lpr command.
Instead of typing all of these commands, you could group them into a shell script. We described shell scripts briefly in Section 9.1. The shell script used to run all of these commands would look like
# A shell script to create and print the book
cat chapter1 chapter2 chapter3 > book
wc -l book
If this script was saved in the file makebook, you could simply use the command
to run all of the commands in the script. Shell scripts are just plain text files; you can create them with an editor such as emacs or vi .
Let's look at this shell script. The first line, ``#!/bin/sh'', identifies the file as a shell script, and tells the shell how to execute the script. It instructs the shell to pass the script to /bin/sh for execution, where /bin/sh is the shell program itself. Why is this important? On most UNIX systems, /bin/sh is a Bourne-type shell, such as Bash. By forcing the shell script to run using /bin/sh, we are ensuring that the script will run under a Bourne-syntax shell (instead of, say, a C shell). This will cause your script to run using the Bourne syntax even if you use Tcsh (or another C shell) as your login shell.
The second line is a comment. Comments begin with the character ``#'' and continue to the end of the line. Comments are ignored by the shell - they are commonly used to identify the shell script to the programmer.
The rest of the lines in the script are just commands, as you would type them to the shell directly. In effect, the shell reads each line of the script and runs that line as if you had typed it at the shell prompt.
Permissions are important for shell scripts. If you create a shell script, you must make sure that you have execute permission on the script in order to run it. The command
/home/atp% chmod u+x makebook
can be used to give yourself execute permission on the shell script makebook.
The shell allows you to define variables, as most programming languages do. A variable is just a piece of data which is given the name.
When you assign a value to a variable (using the ``='' operator), you can access the variable by prepending a ``$'' to the variable name, as demonstrated below.
/home/atp% set foo='hello there'
The variable foo is given the value ``hello there''. You can now refer to this value by the variable name, prefixed with a ``$'' character. The command
/home/atp% echo $foo
produces the same results as
/home/atp% echo 'hello there'
These variables are internal to the shell. This means that only the shell can access these variables. This can be useful in shell scripts; if you need to keep track of a filename, for example, you can store it in a variable, as above. Using the command set will display a list of all defined shell variables.
However, the shell allows you to export variables to the environment. The environment is the set of variables which all commands that you execute have access to. Once you define a variable inside the shell, exporting it makes that variable part of the environment as well. The setenv command is used to export a variable to the environment.
The environment is very important to the UNIX system. It allows you to configure certain commands just by setting variables which the commands know about.
Here's a quick example. The environment variable PAGER is used by the man command. It specifies the command to use to display man pages one screenful at a time. If you set PAGER to be the name of a command, it will use that command to display the man pages, instead of more (which is the default).
Set PAGER to ``cat''. This will cause output from man to be displayed to the screen all at once, without breaking it up into pages.
/home/atp% setenv PAGER cat
Try the command man ls. The man page should fly past your screen without pausing for you.
Now, if we set PAGER to ``more'', the more command will be used to display the man page.
/home/atp% setenv PAGER more
The man pages for a particular command will tell you if the command uses any environment variables; for example, the man man page explains that PAGER is used to specify the pager command. Some commands share environment variables; for example, many commands use the EDITOR environment variable to specify the default editor to use when one is needed.
The environment is also used to keep track of important information about your login session. An example is the HOME environment variable, which contains the name of your home directory.
/home/atp/papers% echo $HOME
Another interesting environment variable is prompt, which defines the main shell prompt. For example,
/home/atp% set prompt='Your command, please: '
Your command, please:
To set the prompt back to our usual (which contains the current working directory followed by a ``#'' symbol),
Your command, please: set prompt='%/% '
The tcsh man page describes the syntax used for setting the prompt.
When you use the ls command, how does the shell find the ls executable itself? In fact, ls is found in /bin/ls on most systems. The shell uses the environment variable path to locate executable files for commands which you type.
For example, your path variable may be set to:
/bin /usr/bin /usr/local/bin .
This is a list of directories for the shell to search, each directory separated by a space. When you use the command ls, the shell first looks for /bin/ls, then /usr/bin/ls, and so on.
Note that the path has nothing to do with finding regular files. For example, if you use the command
/home/atp% cp foo bar
The shell does not use path to locate the files foo and bar - those filenames are assumed to be complete. The shell only uses path to locate the cp executable.
This saves you a lot of time; it means that you don't have to remember where all of the command executables are stored. On many systems, executables are scattered about in many places, such as /usr/bin, /bin, or /usr/local/bin. Instead of giving the command's full pathname (such as /usr/bin/cp), you can simply set path to the list of directories that you want the shell to automatically search.
Notice that path contains ``.'', which is the current working directory. This allows you to create a shell script or program and run it as a command from your current directory, without having to specify it directly (as in ./makebook). If a directory isn't on your path, then the shell will not search it for commands to run - this includes the current directory.
The initialization scripts themselves are simply shell scripts, as described above. However, they are very useful in setting up your environment by executing commands automatically when you login. For example, if you always use the mail command to check your mail when you login, you place the command in your initialization script so it will be executed automatically.
Most shells distinguish between a login shell and other invocations of the shell. A login shell is a shell invoked at login time; usually, it's the only shell which you'll use. However, if you ``shell out'' of another program, such as vi, you start another instance of the shell, which isn't your login shell. In addition, whenever you run a shell script, you automatically start another instance of the shell to execute the script.
Tcsh uses the following initialization scripts: /etc/csh.login (executed by all Tcsh users at login time), $HOME/.tcshrc (executed at login time and by all new instances of Tcsh), and $HOME/.login (executed at login time, following .tcshrc). If .tcshrc is not present, .cshrc is used instead.
To fully understand the function of these files, you'll need to learn more about the shell itself. Shell programming is a complicated subject, far beyond the scope of this document. See the man pages for tcsh to learn more about customizing your shell environment.
The command to print under unix is lpr. e.g.
/home/atp% lpr flare1.ps
This will print the file flare1.ps to the default printer. This is currently the declaser. To send a file to another printer use the command /home/atp% lpr -P<printer_name> <file>
where <printer_name> can be either the declaser, canon, phaser or ps printers.
To show a print queue on the default printer, the command is
or for any other printer
/home/atp% lpq -P<printer_name>
Hopefully we have provided enough information to give you a basic idea of how to use the system. Keep in mind that what is covered here is the very basics.
One indispensable tool for learning about the system is to read the man pages. While many of the man pages may appear confusing at first, if you dig beneath the surface there is a wealth of information contained therein.
Utilities like Mail and Editors have not been covered in this document, but will be dealt with in other documents. Other documents available are listed below.