Lab: Linux Basics

The original Unix operating system and its successor Linux were designed to support the common tasks and needs of computer users. This laboratory exercise focuses on some commands to set up your account and establish subdirectories for your CSC 161 activities.

To work productively in C we’ll often need to use a command-line interface. This is in addition to the graphical interface you’re likely more familiar with. This lab walks you through some of the basics.

A. Basic Terminal Usage

Click the small monitor icon on the bar at the bottom of your screen. If you do not have the terminal icon the instructor or class mentor can help you create one.

Move the terminal window to the side of your browser window by clicking and dragging on the bar at the top of the terminal window.

If you move the terminal window too far, it may go into another workspace, and the system may display only material in this new workspace. The instructor or mentor can help you navigate to the other workspace to move the terminal back. You may also find that using the scroll wheel on the Linux desktop jumps between workspaces, which can be surprising.

Lab Organization

This is our first reading-only section of the lab. Most headings and sections appear above the work that you need to complete to move on in the lab. This section has italicized text, which indicates that you should read the section, but once you and your partner(s) understand the section you can move on. Please do still read carefully, since you may need this information for later exercises.

Terminology

The word “terminal” refers to the window that appears when you launch the terminal program, while the “shell” is a program that runs in the terminal, accepts user input, and runs programs when requested. When we work with software in this way, we are using a command-line interface (CLI). To be precise, we should be calling the window a terminal emulator because it is a piece of software that pretends to be a computer terminal, a physical device that presents a text interface and keyboard to a user of a large computer that typically resides somewhere else. Modern computers generally don’t have separate physical terminals, and terminal windows almost always run a shell when you open them. You’ll find that readings, labs, and some outside resources often use the terms “terminal,” “shell,” and “command-line interface” interchangeably, even though they are technically different things.

Copy and Paste Between Windows

Linux allows you to copy and paste between windows in two different ways. The first way, which will be familiar to Windows users, is to use the ctrl+c and ctrl+v shortcuts to copy and paste, respectively. These hotkeys work in most situations, but not in the terminal window; that’s because ctrl shortcuts historically have a different meaning in command line interfaces. The copy shortcut, ctrl+c, will instead quit the currently running program when you use it in the terminal. To copy and paste, just add a shift key to the shortcuts in the terminal window: ctrl+shift+c to copy and ctrl+shift+v to paste.

An alternative, Linux-only approach is to use the middle mouse button. Select text in one window, switch to the other window, and then press down on the scroll wheel to paste. This can be difficult to do without accidentally scrolling, so you may prefer the keyboard shortcuts.

Copy the text below from this browser and paste it into your terminal window, then hit enter to run it.

/home/nyedawn/csc161/shared/hello

This line of text is a path to an executable. By hitting enter, you’ve run the program.

Formatting for Terminal Examples

This website will use special formatting for terminal examples. These will display with white text on a black background. The terminal examples will include a $ prompt character to show you the lines that you type or paste into the terminal like this:

$ /home/nyedawn/csc161/shared/hello
Hello CSC 161!

Lines without a $ character are output from the program that was just run. This display is styled in a way that will prevent most web browsers from copying the prompt character or terminal output. You can check this by trying to select all the text in the black box; only the text that appears in the first example should be selectable.

Exercises

Every section of the lab (indicated by a heading with a letter) will have an Exercises section. You’ll find numbered exercises that you should complete before moving on to the next part. Make sure you keep notes and/or a copy of your work for these exercises because you’ll be asked to turn some or all of them in as part of your weekly lab report. There are no exercises for this section of the lab so you can move on right away.

B. Working with Files and Directories

In this part of the lab, we’ll practice using the terminal to navigate and manipulate files and directories in Linux. Directories, which you might know as “folders,” contain files and other directories. The collection of files and directories accessible on your computer make up the Linux filesystem.

Get the Current Directory

In the terminal window, type pwd (short for “print working directory”). You should see something that looks like this, but with your username:

$ pwd
/home/nyedawn

The output of pwd is a path, which is the name for a location on the Linux filesystem. To be precise, this is an absolute path because it begins with a / character. Absolute paths begin at the root of the Linux filesystem—a directory called “/”—and describe the steps necessary to get to the final destination. In this case, we are looking at a directory named nyedawn that resides in the directory /home, which is in turn a directory named home in the root directory.

Your shell always has a current working directory, and typically it will start in your home directory as it did in the examples above. We’ll see in the next few steps how we can change the current directory, and why it matters.

Listing Directories

We often need to look at what is contained in a directory. We can do this with the ls program. Use the terminal to run ls and look at its output:

$ ls

The output from ls is often styled to give indications of which entries are files and which are directories; compare the output from ls to what you see in your home directory in the graphical file browser to get a sense of what these styles mean.

You may wonder why ls displayed the contents of your home directory. This is the first case where the current working directory for the shell matters. When you run ls without an argument, it will always list the current directory. Try running ls with an argument instead:

$ ls /home/nyedawn/csc161

The output from this command will be completely different because we’re looking at a different directory.

Creating Directories

You’ll want to create directories to keep your work for this class organized. We use the mkdir program to create directories in the terminal. Run the following lines to create a structure for your work in this class:

$ mkdir csc161
$ mkdir csc161/homework
$ mkdir csc161/labs

Now verify that this worked by running ls to list your home directory; make sure there is a directory named csc161. Then, list the csc161 directory to make sure it contains the labs and homework directories.

All group members should log in to the computer you use to create these directories; you can do this now, or when you’ve finished with the lab exercises.

Relative Paths

The paths we used in this step (csc161, csc161/homework, and csc161/labs) did not begin with a /, which means they are relative paths. They refer to locations on the filesystem relative to the current working directory instead of the root directory (/).

Moving Around

We can change the working directory of the shell using the cd command. Use cd to jump into the csc161 directory you just created and run ls to list its contents:

$ cd csc161
$ ls
homework
labs

There are two special directory names you can use in every Linux directory; the path . always refers to the current directory, and .. refers to its parent directory. So in the csc161/labs directory, . refers to /home/nyedawn/csc161/labs and .. refers to `/home/nyedawn/csc161.

Another special directory name is ~, which refers to your home directory. You can use ~ by itself, or as part of a path like ~/csc161 to refer to something starting from your home directory.

Copying Files

Next, we’ll use the cp program to copy files in the terminal. First, create a directory to hold your work for today’s lab and move to that directory:

$ mkdir ~/csc161/labs/linux-basics
$ cd ~/csc161/labs/linux-basics

Now that your terminal is in the directory you created, copy over a C source file from the instructor’s directory with cp:

$ cp /home/nyedawn/csc161/shared/hello.c .

The cp program expects at least two arguments: the first is a source to copy from, and the last is the destination. In this case, we provided a directory as the destination so the file hello.c will keep its original name; if the second argument was something like goodbye.c the file would be created with that name in the current directory.

Exercises

Answer the following questions before moving on to the next part of the lab. Don’t forget to write down your answers in case they are required for this week’s lab report.

  1. Starting in the csc161 directory you created, imagine you want to use cd to move into the homework directory. What are three different paths you could give to cd to get to that destination?

  2. The ls program we have been using is stored in the directory /usr/bin/. Move to your home directory. Now construct a relative path (e.g. one that does not begin with /) that refers to /usr/bin. Run ls with that path as an argument to confirm that it works, and make sure the output (which will be quite long) includes the ls program.

C. Working with Code

Now that you have some code in your directory, we’ll turn it into an executable program, run it, and use that code as a starting point for a second program.

Compiling and Running a C Program

Now that you have a copy of the C source file, we’ll use the clang compiler to turn it into an executable. A compiler takes source code written in a language humans are meant to read and write and turns it into a file that the operating system can give directly to your computer’s processor to run, called an executable. Nearly all of the programs we’ve run in this lab (ls, mkdir, cp, the shell, clang, etc.) are executables, which is why you can run them.

Here is the complete compiler invocation. Make sure you are still in the ~/csc161/labs/linux-basics directory before you run it:

$ clang -o hello hello.c

This line runs the clang compiler with three arguments. The first two arguments, -o and hello go together: -o is a flag that tells clang we are about to tell it where to put its output, and the next argument hello gives the name of the executable we want clang to create. The last argument, hello.c is the source file we want to compile.

Run the compile command if you haven’t already, and then run ls to make sure there is a file named hello in the current directory.

Now that you’ve compiled the hello program, run it with the following command line invocation:

$ ./hello

What’s with the ./?

You may be wondering why the line above starts with “./”. Normally when we write paths they are either absolute (starting with /) or relative to the current directory. Things work differently when we are giving the shell the name of a program to run.

When we ask the shell to run ls, it does not try to run a program called ls in the current directory. Instead, it looks in a special variable called $PATH to decide where it should look for a program named ls. Run this in your terminal to see what $PATH is set to:

$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/games

Your path may look slightly different, which is okay. The important detail to note is that this is a colon-separated list of paths. When you ask the shell to run ls it will check directories one-by-one to look for an ls program. The shell runs the first match it finds, and if it reaches the end of the list it gives you an error. You can confirm this by running hello without a path:

$ hello
bash: hello: command not found

So when we tell the shell to run ./hello we are giving it a path to an executable, which bypasses the search through $PATH. We could also run hello with other paths like this one:

$ ~/csc161/labs/linux-basics/hello

You could add . to $PATH to save yourself the extra effort of typing “./”, but this is a little unconventional, and there are important security-related reasons why this is a bad idea.

Exercises

  1. Copy the hello.c source file to a new file named goodbye.c in your linux-basics directory.
  2. Run the command code goodbye.c to open the new file in Visual Studio Code, the editor we’ll use in this class. This is a new command, but you should be able to figure out how and where to run it.
  3. Modify the code to print a new message, "Goodbye CSC 151". The code in goodbye.c will be unfamiliar, but you should be able to use your experience from CSC 151 to figure out what part of the program you need to edit.
  4. Jump back to the terminal and use clang to compile your new code to an executable named goodbye.
  5. Run your new program and verify that it works as expected.

D. Documentation

For the final part of today’s lab, you’ll use one of the best resources to help you with Linux and C development: the Linux Manual Pages. You can find guidance on how to use manual pages (sometimes referred to as “manpages”) in the reference section of this site. Review this reference, then complete the exercises below.

Exercises

  1. Use the manpages to figure out how to get ls to list a directory with entries sorted in reverse alphabetical order.
  2. Use the manpages to figure out what the which command does. Describe it in your own words, and explain one situation where you might want to use it.