Linux in CSE 351

Overview
As computing and servers (i.e., ~the cloud~) become more and more prevalent across all industries, it is increasingly likely that you may find yourself using a Linux shell at some point, so it's a good skill to have/know despite our general preference for graphical things!

This course explores low-level topics in machine representation of programs and data. For our reference system, we're using Rocky Linux. Other Linux and macOS systems are very similar, and Windows machines also use the same underlying processors and memory organization. But for assignments in this course, your submissions need to work on, and will be graded on, our reference system.

This is a quick little tutorial on how to get yourself up and running on Linux. If you are a CSE major, then you have access to departmental servers collectively called attu (actually reached at attu.cs.washington.edu). You are welcome to use attu or the CSE virtual machine, which are running the same Linux image. If you are using the CSE virtual machine, then read just "Terminal on Linux" and then from "Shell Basics" onward.

Terminal and Shell Access
Terminology
A shell is a program that processes (textual) commands through the operating system and returns the output. This is the piece that "does the work".
A terminal is a wrapper program that runs a shell. It is primarily responsible for handling the user text input and displaying the output from the shell. This is one example of a command-line interface (CLI).

We use a terminal (e.g., Terminal) to connect to one of many shells (e.g., bash) installed on a Linux machine. You may hear these terms used somewhat interchangeably even though there is a difference; the distinction is irrelevant in 351. The shell is the bread and butter of Linux and brings you a lot of power with not very many key presses.

Shell on Windows

Avoid Window's Command Prompt, which looks like a command line interface but uses a different set of commands and tools and behave differently than the shells on Mac and Linux. Instead, you can connect to attu using any of the following methods:

PowerShell: Windows 7 and up come installed with PowerShell, which is a hybrid between Command Prompt and a Linux terminal. It does, however, recognize the ssh and scp commands, which is all that you will need for this course.
bash: If you are running a 64-bit version of Windows 10 and have installed the "Anniversary Update" (released Aug. 2016) then you can enable a bash terminal (command line interface) directly within Windows! Newer machines can directly install Ubuntu from the Microsoft store, otherwise, here is one useful link for installing bash.
PuTTY: A lightweight SSH client that lets you interact with another computer over the Internet (like opening a shell). You can directly download putty.exe onto your computer.

Shell on macOS

The macOS Terminal behaves very similarly to most Linux shells. As a result, most of the commands on Terminal will be the same as those from a Linux shell. However, to use the Linux shell commands for 351, we will connect to attu.

Click the Spotlight Search button in the upper-right, type "terminal", and press return.

Shell on Linux

Most Linux distributions already have a terminal application pre-installed. Given the vast number of distributions, we won't cover specific steps for how to get a shell in your specific version here. But if you need help figuring it out, don't hesitate to ask! We still recommend that you connect to attu, to ensure that you have all of the tools needed and are using the same environment as everyone else.

Logging into attu

attu is a powerful computer sitting in the CSE building that is ready to run your work, except that it has no screen. It runs linux, and can only be accessed over the network. You will be granted an account (your UWNetID) on attu for the quarter. attu has all of the commands that you will need in the 351 labs, and is built to be fast, so more often than not it's most convenient to run lab programs on attu.

Accessing attu from Windows (PuTTY)

Open putty.exe from wherever you downloaded it.
For the host name, type <your-csenetid>@attu.cs.washington.edu
Click Open at the bottom.
If you're prompted about an RSA key, click Yes.
Put in your Kerberos password when asked for a password. It will look like you're not typing anything – that's done on purpose so people looking over your shoulder won't know your password.

Accessing attu from Windows (bash), OS X, or Linux

Open the shell on your computer (see "Getting a Shell" above).
Now that you have a terminal up, type ssh <your-uwnetid>@attu.cs.washington.edu and press [Enter].
If prompted about a server key, type yes and press [Enter].
When prompted, enter your Kerberos password and press [Enter]. Like PuTTY, it won't look like you're typing. This is done on purpose :)

Changing your attu password

If you would like to change your Kerberos password, type passwd into the command prompt and press [Enter], then follow the instructions given.

Finding Your Way Around the Shell

Linux Files and Directories

Terminology
A directory is a file system organizational tool for grouping (related) files, including subdirectories, together.
A folder is a fancy word that Microsoft invented to make computers seem more human and refers to the grouping of files in the graphical user interface, which may not correspond to the underlying file system structure.
A path is a textual reference to a location in a directory system (e.g., /homes/iws/wolfson/myfile.txt).

All of the files we will create, edit, and use in this class are stored in a directory (of your choosing) in the Linux file system. The most important part for 351 is understanding the directory structure layout so that you can properly locate your files. File paths will be more important in future courses for specifying file locations within your tt or in shell commands. Do note that paths in Linux are case-sensitive (e.g., /home/test.txt is not the same as /home/Test.txt).

The Root Directory (/)

There is only a single hierarchal directory structure. Everything starts from the root directory, represented by '/', and then expands into sub-directories. Where DOS/Windows had various drives (C:, D:, etc) and then directories under those partitions, Linux places all the drives under the root directory by 'mounting' them under specific directories. The closest parallel to the root directory in Windows would probably be C:.

Note that Linux uses the forward slash '/' instead of the backslash '\' as in DOS/Windows. So c:\windows\system would be /c/windows/system. (As a side note, Linux is not going against convention here. Unix has been around a lot longer than Windows and was the standard before Windows was. Rather, it was DOS that took the different path, using '/' for command-line options and '\' as the directory separator.)

Your Home Directory (~)

To keep people (users) from stepping on each other's toes, everyone has one directory ("folder") that they can write and make changes to. This is called your "home directory". On any Unix system, you can refer to the home directory with a tilde, so a folder called frogs inside of your home directory would have a path like: ~/frogs.

When you run a command, your shell will replace ~ with the path to your home directory. If you want to know what that is or how to manipulate the shell, read the next section on basic Unix commands.

Other Important Directories (. and ..)

The shell also allows you to directly reference directories relative to your current working directory. '.' represents the current working directory. '..' refers to the direct parent of the current working directory. Every additional '.' refers to the directory one level higher.

This can be pretty handy in working your way around your directory structure. For example, if you are in the folder lab1, a sibling directory lab2 would be referred to as: ../lab2.

Basic Unix commands

To move around through the directory structure in your terminal window, you'll need to know a few basic Unix commands. Note that you always start in your home directory when you open a terminal.

To get help on some command, say you want to know how to use ls, type "man ls" and you will get the manual pages for that command. (Alternatively, you can use "info" in the same way.)

CommandFunctionExampleExplanationNotes
mkdirCreates a new directory with the given name in the current working directory.mkdir lab1This will create a new directory called "lab1".
lsLists all directories and files in the current directory.ls -AThis will list all sub-directories and files. The -A flag means that hidden directories and files will also be printed to the console.Check the manual page for ls to find out various flags to show directories and files in different forms.
cdNavigates to the specified directory, given its relative path.cd lab1This will navigate to the lab1 directory inside the current directory.This is a common place where . and .. are used. Also, to use a directory's absolute path, start the directory name with either / or ~. For example:

cd ~/cse351/lab2

pwdPrints the current working directory path.pwdThis will print the current working directory's absolute path to the console.
exitExits the console, or logs out of the current SSH session.exitThis will terminate the current terminal window. If you are SSH'd into attu, this will terminate your session.

Here is a sample execution of some Unix commands. The [attu]$ is just the prompt telling you that you're logged into attu. Lines that don't start with this prompt are output returned by the shell in response to the previous command.

[attu]$ mkdir mydir
[attu]$ ls
mail mydir
[attu]$ cd mydir
[attu]$ pwd
/homes/jhsia/mydir
[attu]$ exit

These are just the very minimum basics, of course.

Changing your shell

The shell is the program where you type in commands. There are different shell programs, which are all similar but have different rules and features. For sake of uniformity, we will use a shell called "bash," and your account should be set-up to use this by default. You can check using the following command: [attu]$ echo $0.

In case the output isn't bash or -bash (or you're updating your personal Linux machine), you can change the shell temporarily or permanently. We strongly recommend the latter, but we'll explain the former first to help you understand what is going on.

Temporarily: Type [attu]$ bash.

Now you may have a different-looking prompt (such as [bash-3.00]$), but otherwise at this point you will not notice any differences. Note that instead of changing your shell, you've actually opened up a new shell (we'll discuss processes in this course), so when you type [bash-3.00]$ exit, you'll actually return to the original shell (the one you typed bash into).

Permanently: Instead, you can tell the operating system that the "first shell" for every terminal should be bash for your account. From any prompt, type: [attu]$ chsh -s /bin/bash.

You are running the "change shell" program and specifying that your new shell can be found at /bin/bash. It's almost that simple:

  • To be sure you have the right to do this, you'll be prompted for your password.
  • Before that, you'll be warned that typing passwords can be dangerous. Say "y".
  • As the message says, the change may take a few hours. In the meantime, see the "Temporarily" instructions above.

As a final note, if your shell already is bash, chsh will just say "Shell not changed."

Copying Files between attu

This is handy if you want to work locally but still perform testing on attu.

Download the necessary files to your machine's hard drive (directly from the web or attu), then use a text editor to make changes. After that, you'll need to copy the updated text files back to attu using one of the following suggested methods:

scp (from a shell): uses the command line interface you'll be getting accustomed to in this course. A quick overview can be found on this blog post.
FileZilla : GUI version of SCP that allows for drag-and-drop and limited remote file system manipulation (e.g. file renaming, file deletion, file permissions, directory creation). Works on all platforms (Windows, macOS, Linux).
WinSCP (Windows only): GUI version of SCP that allows for drag-and-drop and limited remote file system manipulation (e.g. file renaming, file deletion, file permissions, directory creation).
Cyberduck (Windows, macOS): GUI version of SCP that allows for drag-and-drop and limited remote file system manipulation (e.g. file renaming, file deletion, file permissions, directory creation).
Editing

Once you get comfortable accessing a Linux shell and navigating files, you're going to need the ability to view and edit files, which is where text editors come in. While we are generally most comfortable using text editors with nice graphical user interfaces (e.g., Microsoft Word) or integrated development environments (e.g., jGRASP, IntelliJ), there is a lot of overhead involved in sending the graphics data over the Internet when you are connected to a remote server. So instead, we would encourage you to try out one of the two most popular text user interface editors: Emacs or vim.

Most of the course staff are more familiar with vim, but don't let that dissuade you from trying Emacs if you'd prefer to. Both editors have a steep learning curve and are greatly customizable, so we've provided an entirely separate text editor page to help you get started.

It's perfectly normal and expected to feel intimidated at first, but 351 involves relatively little coding, which makes it a great course to dip your toes in the water!
Compiling

We will be using a C compiler called gcc in this course, so once you've made edits to your source file and want to test your program, you will need to run a command to produce the executable that will run on your computer (or other desired build product).

Note that this means that after every edit you make to your source code, you will need to recompile it to see the changes in the executable! It is a very common mistake to make changes to your source code but then run your stale (i.e., old) executable and be confused as to why the output is the same as before.

For the most part, the exact compilation command that you will need to use will be given to you in the assignment specs, so you can just copy-and-paste it into your terminal. We'll learn about some of the different options available for the compilation command in this course, and more is covered in the follow-on course, CSE 333.

Your terminal program will automatically store a command history (i.e., some set number of the last commands passed to the shell, regardless of whether or not they succeeded). To save you time from re-typing commands or continually using copy-and-paste, you can access previous commands quickly by pressing the Up (↑) and Down (↓) keys. You can also search back through your command history using Ctrl+R!

Makefiles

To make compilation even simpler for you, many of the lab assignments provide you with a Makefile, which contains the correct compilation command so you never have to type it out yourself! You do NOT need to know how these work or how to read these files, but those who are curious should take the follow-on course, CSE 333. All you need to know for 351 is that you only need to run the command make while you are in the directory that contains that lab's Makefile file and the compilation will be done for you!

Though unlikely, if something really doesn't look like it's running properly when you execute make, first runmake clean before make again. For the curious, the likely culprit in these situations is thatmake and gcc have cached computations required to build your software which have either become corrupt or interfere with the new changes you've made. The make clean command will remove intermediate build products so that the whole compilation process starts over from scratch.
Executing

We're not using a graphical interface, so there's no option to double-click an executable to run it anymore; everything must be specified in the command line!

All of the commands given above are the names of executables that come pre-installed with either the operating system or the shell that you are using. The trick is that your shell has a list of places that it knows to look for an exectuble that matches the name of the command that you gave it. However, the shell won't know about an executable that you've built yourself unless you explicitly tell it where to look. In Linux, what this means is that in order to run your locally compiled executable, you will need to specify a path to the executable instead of just using the name of the executable.

For example, if you are remotely connected to attu, currently in your home directory, and have compiled an executable named hello there that outputs the text "Hello, world!", the following transcript shows: (1) an incorrect call to the executable, (2) a correct call using the relative path (recall that. represents the current/present directory), (3) a correct call using the absolute path (for the userjhsia).

[attu]$ hello
-bash: hello: command not found
[attu]$ ./hello
Hello, world!
[attu]$ /homes/iws/jhsia/hello
Hello, world!
Option 2 (prepending ./ to your executable name) is by far the most common usage.

Execution Output

Some executables, particularly some of our lab test suites, output many lines of text and numbers that will be useful for understanding your current progress and debugging. However, your terminal can only display so many of those lines, based on the window size, the text font size, and your terminal's line buffering (this can sometimes be changed in settings, but will have a defined maximum value). Try scrolling upward with your mouse first, but if you can't see all of the output, you can use one of the techniques below to do so:

Save output to a file

Append a greater-than character and file name to the end of your command to save the execution output to a file instead of printing it to the terminal. For example, to save the output of the executable ptestto the file output.txt, you would run:

[attu]$ ./ptest > output.txt
[attu]$
Notice that the output doesn't show up in the terminal anymore because it's been redirected to the file. Use your favorite text editor to open output.txt to view the output.
If the file output.txt already exists in the current directory, it will overwrite/replace the contents of that file, so be careful!
View output screen-by-screen

Append a vertical bar character and the command less to the end of your command to show output "page-by-page." For example, for the executable ptest, you would run:

[attu]$ ./ptest | less
You can navigate the output using the Up (up one line), Down (down one line), and Space (down one screen) keys.
You can exit from this view by either reaching the end of the output or pressing the 'Q' key.
Note that this method does not store the output anywhere so once you exit this view, you won't be able to view the output unless you run the whole command again.
Debugging

Debugging is a critical skill for computing, but one that you are not expected to be very good at yet. An explicit goal of the course is to help you improve your debugging skills, though debugging in 351 will likely feel very different than what you may have experienced previously for a number of reasons:

We will use new languages in C and x86-64 assembly.
We will use a text user interface debugger called GDB.
The labs will focus less on composing programming language constructs properly and more on using our conceptual knowledge of the underlying computer organization to solve tasks/puzzles.

Because of the importance of this skill and the newness of the 351 environment, we've provided an entirely separate debugging tools and tips page to help you throughout the course.

Written by Andrew Reusch (areusch@gmail.com).

Updated by Sarang Joshi (sarangj@cs.uw.edu), Justin Hsia (jhsia@cs.uw.edu), and Andrew Hu (andrewhu@uw.edu).