Comp 141 Class 1 notes

May 23

Review the basics


A brief history of Unix

Early computers usually ran batch jobs: you would write your program and then submit it. Later (hopefully minutes later but sometimes hours) you'd discover your program ran (possibly unsuccessfully), and would collect your output.

Debugging was hard.

Often you would write your program on IBM cards and submit your job by handing a box of your cards to a machine operator across a counter. Your output would be printed. This system was still in use at Loyola when I came here in 1982, when essentially all computing here was done on one IBM mainframe running the System/370 operating system. (I refused to have anything to do with cards.)

Serious computer users disliked this, and there were interactive time-sharing operating systems. Even the IBM mainframe got time sharing, early on.

The Multics project was intended to build the ultimate time-sharing operating system. It began in 1964, as a joint project by MIT, GE, AT&T and others. The operating system was certainly reasonably successful, but there were Issues, and Bell Labs pulled out in 1969.

Ken Thompson was a Bell Labs employee who worked on Multics, and after the pullout he began a new operating system which he called Unix, along with Dennis Ritchie and others. The idea of the name was that Multics tried to do MULtiple things, and Unix would do one thing well. Unix was heavily influenced by the design of Multics. 

There was no "batch mode" in Unix, ever. Everything started through interactions with a terminal, connected via a serial line, and which ran a shell program that displayed what you were typing and what the computer's responses were on a screen. (You could still run "background" jobs.) The shell also launched commands that you typed.

It is not entirely clear to me exactly when the first Unix system booted successfully, but the Unix "epoch date" is Jan 1, 1970. System times represent seconds since then.

The first paper on Unix was published in 1974; the first widely distributed version, Version 7, appeared in 1979. Around the same time the University of California at Berkeley began work on various ports and variations of Unix; these ultimately became BSD Unix.

From early on, Unix supported pipes: the output of one program could be directly connected as the input of another:

    ls -l | grep '^d'

This led to the Unix Philosophy: programs (at least "utility" programs) should be small, modular, general-purpose, and easily composable. Here is the version as set down by Doug McIlroy in 1978:

  1. Make each program do one thing well. To do a new job, build afresh rather than complicate old programs by adding new "features".
  2. Expect the output of every program to become the input to another, as yet unknown, program. Don't clutter output with extraneous information. Avoid stringently columnar or binary input formats. Don't insist on interactive input.
  3. Design and build software, even operating systems, to be tried early, ideally within weeks. Don't hesitate to throw away the clumsy parts and rebuild them.

Point 3 is reminiscent of Eric Raymond's 1997 "bazaar" model of Linux development.

File redirection also was supported: the user could ask that input and output for a program come from files rather than the terminal.

One of the most important elements of the Unix design philosophy was that "everything is a file". That is, the printer appears to the system as a special file, and to print something, you write to it. Network sockets are special files you can read from and write to. Programs can communicate with one another through pipes. Here is a table of the Linux x64 system call interrupt numbers: https://filippo.io/linux-syscall-table. (User programs communicate with the kernel by executing an "interrupt" instruction after leaving the system call interrupt number in a register.) Note that the first three are

0    read()
1    write()
2    open()

Note also that there are now 457 entries, which means things have gotten Complicated in recent years.

How to Run Unix

Basically you have four options:

  1. Run Linux on a virtual machine provided by the CS Department
  2. Create a virtual machine on your laptop and run Linux there
  3. Create a Linux shell account via Github. This gives you command-line access only, no bitmapped display.
  4. Use bash under the Windows Subsystem for Linux, or zsh on a Mac

Running on a CS-department VM:

  1. Connect to perlis.cs.luc.edu in your browser.
  2. Log in to Guacamole. Your username is your Loyola UVID; your password is pxxxxx, where xxxxx is the last five digits of your student number.
  3. You should see a little box with a plus sign, and some string like "0-comp141-x-sum2024". Click on the plus-sign box. (The connection here is for your own virtual machine; it is not shared with others.)
  4. Now click on either the little-screen icon, for a GUI connection, or the >_ icon, for a command-line connection.
  5. Log in, with username comp141 and password Linux@cs.
  6. At least with the command-line connection

Homework 1: log into your CS-dept VM this way. The file hello.text contains a Magic Number. Email it to me.

Creating your own VM:

  1. Install VirtualBox (or VMware). VirtualBox is from virtualbox.org.
  2. Install the extension pack
  3. You can either install Linux from scratch, on a new virtual disk, or create a Linux VM using an existing virtual disk. Installation is generally from a CD-ROM image, typically an *.iso file. You can download these from Ubuntu.com. If you want an existing disk image, there is a 2022 full disk image for Lubuntu, slightly smaller than Ubuntu, at https://loyolauniversitychicago-my.sharepoint.com/:u:/g/personal/pdordal_luc_edu/Ee0BZw4k-O5Pqi6uDq5Mer0BG0jrMQP9p_YuUc6DRKdwbQ. Note that this is zipped; you will have to unzip it.
  4. Start VirtualBox and click "New"
  5. Give your new virtual machine a name, like "mylinux"
  6. Specify that the new-machine Type is "Linux" and the Version is "Ubuntu (64 bit)".
  7. For Hard disk, select the radio button for "use an existing virtual hard disk file", if you are using a pre-built virtual hard disk. If you are creating a new installation from an *.iso file, you will create a new virtual hard disk. Ideally it should be at least 32 GB.
  8. If you are using a pre-built virtual hard disk, you must add it to the VirtualBox library. At the far right side of the file-selection box is a little folder button. Click that to get the virtual-disk manager. Click "Add" and root around until you find your disk image (eg lubuntu.vdi).
  9. Start your virtual machine. For the disk image mentioned in Step 3, the username and password are both "mininet".

Github codespace:

  1. Log into Github.com. Create an account if necessary.
  2. Create a new repository, with the NEW button.
  3. Choose the "master" or "trunk" top-level branch
  4. Click the <> Code button, and then the Codespaces tab (it may already be selected)
  5. Click the Create codespace on __________ button.

(Don't try this with, say, Firefox with a heavily locked-down installation of NoScript.)

Windows/Mac shells:

If you have a Mac and open a Terminal, the shell zsh is run. It's close to bash.

If you have a Windows machine, you can install the Windows Subsystem for Linux, or WSL. Then, as I understand it, the common Linux commands are available through powershell (but probably not cmd). But there is still that issue of '/' versus '\' for file names.

A First Look at the Shell

The first shell was sh, the Bourne shell. While bash (the Bourne Again shell) is today more popular (by a lot), it's still very sh-like. There's also zsh. I have no idea what is going on with zsh; its ties to csh suggest weirdness.

Some things to try:

1. Type ls to list your files (there may not be any). It's short for "list". Why is it ls and not "lis" or "list"? I dunno, bytes were more expensive back then.

2. Type pwd to print your current directory.

3. Type cd to change to a different directory, eg cd /  to change to the root (/) directory

Every process always has a "current working directory" (although the cwd can be deleted after the process starts).

The directory name following cd can be an absolute path, beginning with /, or a relative path, beginning with anything else.

4. Type ls -l to get a "long" list of files, with sizes. (In the / directory, there should be plenty.) What do all the columns mean?

5. Other options include aAbBcCdDfFgGhHiIklLmnNopqQrRsStTuUvwxXZ. Also some string-only options, like --full-time and --file-type and --dereference-command-line-symlink-to-dir. Welcome to my world!

6. Maybe you have a lot of files, and only want to look at the first few. Then ls -l | head will give you the first ten. The vertical bar is the pipe symbol. The output of ls -l is one line per file, and it becomes the input (via the pipe) to the head command, which prints the first 10 lines of its input and discards the rest. (You can print the first, say, 30 lines with head -n 30). If you want the ten most recent files, have ls print recent files first with the -t option: ls -lt | head.

7. ls dirname lists the files in the directory dirname (or if dirname is a regular file, it lists that file).

8. Options to ls that are more important: -l, -a, -t

9. Try ls --help. Or man ls

10. Plain ls does not show filenames beginning with ".". Use -a to show these hidden things Every directory contains two special entries, "." which refers to itself, and "..", which refers to the parent directory.

How does ls compare with a visual file browser? With ls, it's easy to get confused whether you just listed the files at the current directory, or in a subdirectory. At some point, though, the real issue is that text-based commands can be connected into pipes, and into scripts.

Shell stuff

We can type anything into the shell, even gibberish. (What happens when we do?)

Typing an up-arrow lets us see the previous command. Typing left-arrow and right-arrow let us move around a previous command, and edit it.

More basic commands

cat

cal (also cal 5 2024, but cal 5 24 is a looong time ago!) (Be sure to try cal 9 1752)

date

df

free