Introduction To Linux
Many students in the CS Department are unfamiliar with Linux, but may be very proficient at Windows. Since the department uses Linux heavily, it is essential to become comfortable working on the Linux platform.
This document is an introduction to Linux. Being an “introduction,” it will not describe every single command or every single option; however, it will give you a solid foundation and refer you to other sources for more information, when applicable.
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, this article uses the bash shell as an example. Although Linux and Unix are technically different systems, this tutorial will use the two terms more or less interchangeably. This tutorial also assumes that you are using a Linux system as configured by the CS Department; however most Unix systems will be similar.
Using Linux Graphically
Desktop Environments and Window Managers
On Linux you have a choice with everything. This includes the graphical interface. A program called a “window manager” (or “desktop environment” when it's a set of programs) is responsible for keeping track of the windows on the screen, drawing window borders and title bars, giving you a task bar, setting the background image, and configuring the look and feel of the system. There are dozens of window managers out there, each with its dedicated fans. The CS Department currently (as of 28 February 2017) uses the KDE Plasma desktop environment, although there are many others available, including Cinnamon, MATE, Unity, Gnome, and LXDE.
Logging On and the Shell
Like most computers, to use a Unix machine, you must first log on. To do this, you need an account, which will include a user name and a password. When you enter your user name and password, you can generally select a window manager and desktop, if more than one is installed on the system. Two fully featured window managers with desktops are Gnome and KDE. Once you have been authenticated and authorized, 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.
Getting 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, the line
man ls pulls up the reference page for the command
ls. The command
man uses the command
more to let you page through the reference pages. At the prompt for
more (a colon), you can press the space bar to view the next page or
q to quit viewing.
Manipulating the Filesystem
A Unix filesystem consists 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 command
cd. You can always return to your home directory with the command
cd ~. Other examples of using
cd include the following:
cd: also changes to your home directory cd -: change to last working directory cd <directory>: change to a specific directory cd ..: change to parent directory cd ~/<directory>: change to a directory underneath your home directory
Note that the tilde ('~') represents your home directory.
You can print the current working directory with the command
pwd. You can make a new directory with the command
mkdir, and you can remove an empty directory with the command
rmdir. (There's a way to do it with
rm, but it can be quite dangerous.)
Unix directories are both renamed and moved with the command
mv. This means that a directory can be renamed and moved with one command. For example, you could do the following to put the directory cs142 under your home directory:
mv ~/cs/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 command
cp. For example:
cp file1 1file.
To copy everything from the directory cs142 into the directory tmp under your home directory (assuming the directory tmp already exists), do this:
cp ~/cs/cs142/* ~/tmp
Each file/directory has a set of permissions associated with it. Every file/directory is also assigned an owner and a group ID. You can look at the files in your current directory with the command
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 group that owns the file/directory. The letter “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 chgrp, or
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 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 command
rm. 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 about Deleting Files in Unix
There is no un-delete mechanism!
When a file is gone, it's gone! Be careful and make sure you only delete what you actually want to delete. Keep backups! If you're unsure about whether a wildcard will match only what you want, execute
ls * first to see what it matches. Then you may run the line
rm * and know exactly what will be deleted. There are no second chances. Because of this, it is very important that you keep backups of your data.
No one will keep backups for you! The system administrators will not retrieve deleted or corrupted files. See Account Policies & Lab Rules for more information on your responsibility to backup your own files.
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 command
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 command
kill. 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 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 run of
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 (an invocation of
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 command
who. You can find out what each person is doing with the command
w (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 stream stdin is associated with the input of the process (the keyboard by default). A program can read from its stdin to retrieve user input. A program writes to its stdout or stderr to produce output for the user (stdout and stderr write to the screen by default). You can redirect stdout to a file (instead of to the terminal screen) using
>. For example, the command
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
<. For example, the line
cat < .bashrc prints on the terminal screen the contents of the file .bashrc. You can redirect both stdout and stderr to the same file using
A pipe ('|') is very useful. It passes the output of one command as the input to another command. For example, the command
ps -aux | grep cs142ta takes the output of
ps -aux, and sends it as the input to
grep cs142ta. This combined command lists all processes whose owner is user cs142ta. Another example is
ls -al | less. This command takes the output of
ls -al and sends it as the input to
less. This combined command lets you page through the output of a long directory listing.
Viewing and Editing Files
less lets you view a file. It has been cursorily described above. To see all the options for
less, type and execute
man less. The command
more also displays files but has fewer options than
less. Another command you can use is
cat. The command
cat simply prints the contents of the files you list as its arguments. For example, the line
cat file1 file2 will print the contents of file1 and file2, but it doesn't pause at the bottom of every page like
To edit a file you must open it in a text editor. Some editors that you can use include vim, vi, nano, and emacs. 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 or vim, run
vimtutor. To learn more about emacs you should start emacs with the command
emacs, and type
t (hold down the keys control and “h”, and then release them and press the key “t”). You can read more information on Vim (a Vi clone) and Emacs in the documents Vim, A Real Editor and Emacs: A Basic Introduction, respectively.
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
To compile an executable from a C++ source file called lab.cpp, you would do this:
gcc lab.cpp. 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 (e.g.
gcc -o lab.out lab.cpp).
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 that depend on other files. When you make a change to a source code file, you need to recompile it and re-link 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 is the list of 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.cpp prog.h gcc -c prog.cpp
This is just one simple way and 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.cpp 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 have a 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 document.
Logging into Machines Remotely Over 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 (i.e. your local machine). Then, you can type
ssh <username>@<hostname>, where username is your login name and hostname is the name of the machine you're trying to log in to.
For example, suppose you're logged on to the machine parthenon in the lab and your username is bob. You want to log into the machine deathstar. You could type
ssh bob@deathstar and you'll get a log in prompt for the host deathstar. After entering your password and hitting Enter, you should see a shell prompt on deathstar where you can type commands. To terminate the connection, exit from the shell as usual (with
logout, or Ctrl-D).
The Architecture of a Unix System
This section attempts to give you some background into what constitutes a Unix system. This can become a little confusing, but you will be introduced to 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, zsh, and bash. Although 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 bash 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).
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.
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 and Gnome are both examples of window managers with integrated desktops.
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. Though this can be confusing at first, with time it can become 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, with an attached keyboard for the user to use to interact 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 Yakuake, Guake, Konsole, rxvt, eterm, and xterm.
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 your system and try to 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 and 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.