Introduction to UNIX (and Linux)
Your First Encounter with a Unix Machine
This tutorial will focus on using Unix from the level of a shell and shell based utilities. Though most shells are similar for basic commands, I will be using the bash shell as an example. This tutorial assumes that you are using a Linux system as configured by the CS Department; though on the level that we are discussing, most Unix systems are the same.
Logging on and the shell
To use a Unix machine, you must first log on. To do this, you need to create an account and obtain a user name and password. When you enter your user name and password, you can also select a window manager and desktop. Two fully featured window managers with desktops are Gnome and KDE. Two lighter weight window managers are FluxBox and WindowMaker. These window managers do not include desktops, but are very fast and configurable. Once you have been identified and validated, Unix loads your chosen window manager. It is from within that window manager that you can load any graphical program. To follow the rest of this tutorial, you should choose to open a terminal with a shell. From within the shell you can run any program on the system, even if it does not appear in your window manager's menus. When you are done, you should close the shell by typing exit. You also must log out of the window manager so that others won't be able to use your account.
Learn how to get help from Unix
The main Unix help facility is its on-line reference manual. You can read about a subject by typing man <subject>. For example, man ls pulls up the reference page for the "ls" command. I use man almost every day. Man uses the more command to let you page through the reference pages. At the "more" prompt (a colon), you can type space-bar to view the next page, or return to view the next line, or "q" to quit viewing.
Getting around the filesystem and first commands
A Unix filesystem consists mainly of files and directories. Directories are organized in a hierarchy. The current directory in the hierarchy is named "." and the parent directory is named "..". You are assigned a directory as your "home directory". You own this directory and everything subordinate to it. When your shell starts, your current working directory is your home directory. You can change the current working directory with the cd command. You can always return to your home directory with the command cd ~. Other examples using cd:
cd: also changes to your home directory cd -: change to last working directory cd <directory>: change to directory cd ..: change to parent directory cd ~/bin: change to the bin directory underneath your home directory
If you set the CDPATH variable properly, cd will search the cdpath for the directory you've specified. For example, if your home directory is /users/liddl, and you have a /users/liddl/cs/cs142 directory, and you set CDPATH to contain ~/cs, then typing cd cs142 will take you to /users/liddl/cs/cs142 from where ever you might be. Without CDPATH, you'd have to do either cd /users/liddl/cs/cs142 or cd ~/cs/cs142. Note that the tilde (~) represents your home directory.
You can print the current working directory with the pwd command. You can make a new directory with the mkdir command, and you can remove an empty directory with the rmdir command. (There's a way to do it with rm, but it can be dangerous.
Unix directories are renamed and moved with the mv command. This means that a directory can be renamed and moved with one command. For example, I could do the following to put cs142 under my home directory:
mv ~/cs/cs142 ~
Or:
cd ~/cs; mv cs142 ..
Files can be moved and renamed in a similar way. For example, to change the name of file1 to 1file, do this:
mv file1 1file
You can also copy files with the cp command. Example:
cp file1 1file
To copy everything from the cs142 directory into the tmp directory under your home directory (assuming the tmp directory already exists), do this:
cp ~/cs/cs142/* ~/tmp
Each file/directory has a set of permissions associated with it. Every file/directory also is assigned an owner and a group ID. You can look at the files in your current directory with the ls command (e.g., ls -l). The first 10 letters of each line from ls -l show the file/directory permissions. The first letter is "d" for directories or "-" for regular files. The next 9 letters are grouped into three rwx-triples. The first triple indicates the file/directory owner's permissions. The second triple indicates the group's permissions. And the third triple gives permissions for users who are not the owner and who are not in the same group. "r" stands for read permission, "w" for write permission, and "x" for execute permission. You can't search a directory unless you have execute permission for it. Here are some commands to change file attributes:
chown: change owner chgrp: change group chmod: change permissions
Look up these commands in the on-line manual pages by typing man chown, man chgrp, or man chmod.
Files with a period as the first letter of the file name are hidden files (compare the difference between an ls and an ls -a). Here are some useful options to the "ls" command:
| a: | show hidden files |
|---|---|
| l: | show long listing |
| C: | show short listing (in columns) |
| F: | mark files by type (/ after directories, * after executable files, etc.) |
| t: | list in order of time (creation) |
| r: | list in reverse order |
| R: | list recursively |
These options can be combined. Here are some I've found useful:
ls -al ls -l ls -C ls -lrt ls -lt ls -lR
You can delete a file with the rm command. Be careful if you type rm *, because you could delete all of your files. Unix does not ask you if you're sure you want to do that.
Warning
THERE IS NO UNDELETE MECHANISM
When a file is gone, it's gone! Sayonara, hasta la vista, bye-bye-baby! BE CAREFUL. ONLY DELETE WHAT YOU WANT TO DELETE. KEEP BACKUPS. If you're unsure about whether a wildcard will pick up only what you want, do an "ls" with that wildcard first, to see what it matches, then run the "rm". THERE ARE NO SECOND CHANCES. Because of this, it is very important that you keep backups of your data.
Warning
NO ONE WILL KEEP BACKUPS FOR YOU
Unix processes and users
Unix is a multi-tasking environment. There are always a number of different programs running at the same time. Each Unix program is called a "process". Each process has a "process ID" or "pid" associated with it. You can look at processes that are currently executing by using the "ps" command. Examples:
| ps: | list your processes running in the current shell |
|---|---|
| ps -aux: | list all processes, in a long format |
You can send a signal to a process you own with the kill command. There are lots of signals, but you only need to worry about two right now. The default is to send an interrupt signal. You can do this by typing kill <pid> where pid is the process ID number of the process you want to terminate. If that doesn't work, you can try kill -9 <pid>, which sends an uninterruptible termination signal to the process. If the process is still around after a kill -9, then it is either hung up in the Unix kernel, waiting for an event to complete, or you are not the owner of the process (kill will tell you if you try to kill something you don't own).
You can find out who is logged on to the system with the who command. You can find out what each person is doing with the w command. (Or you could type ps -aux | grep username to look at a given user's processes.)
I/O redirection (<, >), and pipes (|)
Every Unix process has three streams associated with it: stdin, stdout, and stderr. The stdin stream is associated with the input of the process (the keyboard by default). A program can read its stdin stream to get user input. A program writes to its stdout or stderr streams to produce output for the user to see (stdout and stderr go to the screen by default). You can redirect stdout to a file (instead of to the terminal screen) using the ">". For example: ls > ls.out places a directory listing in the file called "ls.out". You can redirect stdin to come from a file (instead of from the keyboard) by using the "<". For example: cat < .bashrc types out on the terminal screen the contents of the file ".bashrc". You can redirect both stdout and stderr to the same file using "2>&1".
A pipe is very useful. It sets up the output of one command as the input to another command. You set up a pipe using "|". For example: ps -aux | grep cs142ta. This command takes the output of "ps -aux", and sends it as the input to "grep cs142ta". This command will list all processes whose owner is user "cs142ta". Another example: ls -al | less. This command takes the output of "ls -al" and sends it as the input to "less". This command lets you page through the output of a long directory listing.
Viewing and editing files.
The program less lets you view a file. It has been described above. To see all the options for more, type man less. The program more also displays files but has fewer options than less. Another program you can use is cat. Cat simply prints the contents of the files you list. For example, cat file1 file2 will print the contents of file1 and file2, but it doesn't pause after every page like more and less do.
To edit a file you must use an editor. Some editors that you can use include vi, emacs, and nano. There are many good tutorials about these editors on the web, and the man pages are also helpful. To get your feet wet with vi, run vimtutor. To learn more about emacs you should start emacs with the emacs command, and type Ctrl-h t (hold down the control and "h" keys, then release them and press the "t" key). You can get more information on Vim (a Vi clone) and Emacs in the "Vim, A Real Editor", and "A Basic Introduction to Emacs" documents.
Software Development
Compiling and Linking
Turning source code into an executable consists of two steps: compiling the source code into an object file (they end with ".o"), and linking object files together to make an executable. The C++ compiler on most Linux systems is gcc. It is similar to the compilers used on other Unix platforms. When you compile, gcc will do most of your linking for you. Should you ever need to do your own linking, the linker installed on most systems is ld.
To compile an executable from a C++ source file called prog.cc, you would do this: gcc prog.c. This creates an executable named "a.out". If you want to specify the name of the executable that gcc makes, you must use the "-o" flag.
Using the Make Facility
Though make is most often used to help compile an executable from multiple source files, it is a utility that can helps you maintain files which depend on other files. When you make a change to a source code file, you now need to recompile it and relink the resulting object file to the other object files necessary to make an executable program. If you edited a header file, you might need to recompile multiple other files. Rather than keeping track of the interrelationships between all of your source files, make can do that for you. You give make its instructions in a file called "Makefile". Instructions have the form:
target: dependency list
instructions
where target is the file that you want to automatically update, dependency list is the set of files the target depends on, and instructions are commands that get executed when make determines that a target is older than one of its dependencies. For example, consider a program called prog, which gets linked from prog.o, which gets compiled from prog.cc and prog.h. Its Makefile would look like this:
prog: prog.o
gcc prog.o -o prog
prog.o: prog.cc prog.h
gcc -c prog.cc
This is just one simple way, there are other ways to do this. You invoke make by simply typing make at the command line. When executed, it searches for a Makefile in the directory where it was called. It goes to the top of that Makefile and sees if the first target needs to be updated. It does this by recursively checking the files in the dependency list. In our example, it sees whether it needs to update "prog" by checking whether prog.o is up to date. It checks the timestamp of prog.o and sees if it's older than prog.cc or prog.h. If so, make first updates prog.o by executing "gcc -c prog.cc". Next, if prog is older than prog.o, make updates prog by executing the command "gcc prog.o -o prog".
Makefiles are very powerful. They can use variables and number of useful functions. It is worth the time to read a more complete tutorial about make and Makefiles. One such tutorial is the " Makefiles in a Nutshell" document.
Network Awareness
Unix is a very network-aware system. This tutorial offers only the barest of instruction. I strongly suggests that you read the documents in the general section of the CS Documentation Project which address security and logins, as well as email and spam.
Learn how to log in to another machine on the Internet with SSH.
If you have an account on some other machine, you can log on to that machine remotely using SSH (which encrypts the data sent on the network). First, you must be logged on to a machine (your local machine). Then, you can type ssh -l <username> <hostname> where username is your login name and hostname is the machine ID you're trying to log in to. For example, suppose you're logged on to "verdi" in the lab and your username is "bob". You want to log into "clara". You could type ssh -l bob clara and you'll get a log in prompt for the host named clara. You type your password as usual. You should see a shell prompt where you can type commands. To terminate the connection, exit from the shell as usual (with exit, logout, or ctrl-D).
Learn how to send and read mail.
There are several e-mail programs you can use. The traditional programs are mail and mailx. You'll find those programs on most kinds of Unix machines. To read your mail, type mail. To send mail, type mail <address>, where address is the e-mail address of the person you want to mail something to; then type your message, and when you're done, type a period (.) on a line all by itself.
On of the most popular email clients is pine. Just type pine at the command prompt and everything is pretty self-explanatory. The commands are listed at the bottom of the terminal window. Remember that the ^ means press the control key (Ctrl).
Learn how to use ftp to retrieve files.
To connect to a host, type ftp <hostname>. For example, ftp ftp.example.com. Ftp will ask you for a user name and password. Because ftp is unencrypted, any username and password you supply can be read by anyone who is looking at the network connection. For this reason, if you must supply a user name and password, I suggest that you use sftp or scp. You can get more information about these programs in other areas of the CS Documentation Project.
If the host supports anonymous ftp, you can give anonymous for the user ID, and your e-mail address for the password. Once you're connected to the ftp host, you can do a directory listing with dir, change directories with cd, and retrieve files with get <filename>. Type ? at the ftp prompt for a list of commands. You can type help <command> to get a description of any of the commands. When you're done, type quit to exit. Again, remember that man ftp will show you the Unix reference manual page for ftp.
The Architecture of a Unix System
In this section I attempt to give you some background into what constitutes a Unix system. This can become a little confusing, but will introduce vocabulary and concepts which will enable you to better understand your Unix system. Don't worry if you get lost, and feel free to skip this section if you are in a hurry.
The kernel and shells
Every operating system is built around a system kernel which performs the basic functions necessary for a computer to run. The only way to interact with the kernel is through system calls. Programs make system calls to get the kernel to perform requested functions. Systems that run many programs need a way to request that the kernel run the correct program. A shell is a program which allows a user to ask the kernel to do many different things. Most of the functionality of a Unix system is not in the shell, but in the many small programs that the shell calls to perform a myriad of functions. These small, single purpose programs are called utilities.
Today there are many different shells for Unix such as sh, csh, tcsh, ksh, korn, ash, bourne, and bash. Though for basic commands they are all similar, each one is a little different. Each shell has a set of initialization files, much like CONFIG.SYS and AUTOEXEC.BAT for MS-DOS. For example, the Bourne shell uses .profile and .bashrc; the C-shell uses .cshrc and .login. The commands in these files are executed when the shell starts up. When the shell is ready, it gives you a prompt, and you can type commands for the shell to pass to the system kernel.
Windowing systems, window managers, and desktops
Sometimes users want to do more than one thing at a time. For this reason shells have developed an idea of job control, where each process running simultaneously in a shell is a job. But to see the output of multiple jobs simultaneously, one must put each shell into a window, and display multiple windows side by side. The program which displays those windows is called a "windowing system". Windowing systems usually take commands from a pointing device such as a mouse in addition to the keyboard. Many of these windowing systems also take care of pretty graphics that programs can use to draw to the screen. One graphical windowing system that is widely used today is the X Windowing System (abbreviated X11 or just X). One common implementation of X is XFree86.
The Windowing System only provides an interface with the kernel for drawing windows and maybe graphics. The program which actually places the windows and determines how they will look is called a "window manager". A window manager usually provides a menu interface for starting new programs, and allows the user to move smoothly from desktop to desktop. Two popular window managers are Enlightenment and BlackBox.
Users often want to use a window manager that includes a desktop. Desktops allow the user to place icons on the background of the screen, and usually provide a palette, applet, or taskbar which gives information about the system such as the time, what programs are open, and a logout button. KDE is a window manager with an integrated desktop. Gnome is a desktop which allows the user to select from a variety of window managers such as Sawfish and Metacity.
Many users wish that they had more screen space than their monitor provides. Most desktops and window managers provide that space by creating "virtual desktops" or "workspaces". The user can open up programs on any of these virtual desktops and then move between them with keystrokes or by scrolling the mouse off of the edge of one virtual desktop on to another. I like to have 4-8 virtual desktops where I can organize all of the applications I have open: two for email and todo lists, two for Internet documentation, two for programming, and two for debugging output. Though this could be confusing at first, with time it becomes very helpful.
Terminals and consoles
When you want access to a command line from within your windowing system, you must open a shell inside of a terminal. Originally the term "terminal" referred to a screen upon which the command prompt of a shell is displayed when no windowing system is running. Originally a console was the station with terminal and keyboard where a user interacted with the system. Over time, terminal and console came to be used interchangeably to refer to the actual command prompt or a window which displays the command prompt. Even though you only have one physical terminal or console, modern Unix systems emulate multiple virtual terminals. These virtual terminals (or ttys -- a historical reference to "teletype terminals") are accessed by holding down the Ctrl and Alt keys along with one of the function keys at the top of an IBM style keyboard. F1-F6 usually run character terminals with shells, while F7-F12 usually run graphical terminals with windowing systems. By using virtual terminals one user can run a couple of different shells and two or more separate window managers without any conflicts. A user must log in separately to each virtual terminal, and a window manager must be started on a graphical terminal before anything will display there. A graphical login manager such as XDM, KDM, or GDM usually runs on F7 or F8 to facilitate graphical logins.
But this is probably not what you are looking for when you want to access a shell from within your window manager. You want to see that shell in a window beside your other applications. That window is also called a virtual terminal or console, and many programs can be used to make such a window. Each terminal program has its own advantages and most people have a preferred terminal application. Examples of such applications are Konsole, Gnome-terminal, rxvt, eterm, and xterm.
The point
Notice that in the Unix world kernels, shells, windowing systems, window managers, desktops, and terminals are all distinct concepts and independent entities. Users can mix and match these different components and make them inter operate. Users can also interact with the system at different levels, harnessing the functionality of specific layers of the system. This allows lots of flexibility and multiple ways of doing things. It can also be very confusing. Don't worry if it doesn't make sense at first, but pay attention to the different components of you system and try and discover which one provides what functionality.
Though most modern Unix systems include all of these components, they don't all have to. There exist non-graphical windowing systems, window managers that are not desktops, and sometimes it is better not to have a windowing system at all. This modularity is part of what makes Unix so powerful. Rather than getting overwhelmed by it, learn to appreciate it and you will find it a rewarding experience.