Navigating Unix

Later in class we'll be going over how to use Unix in a bit more detail. For now, here's some context for what was going on when we ran the hello-world.py example yesterday in class.

What's Unix?

Unix is a family of computer operating systems (OSs). Exactly what modern day OSs fall under this category is somewhat murky, but both GNU/Linux and macOS have much in common with true Unix OSs such as FreeBSD or Solaris. Even Windows now has some Unix-like aspects now. For my purposes here, I'll talk about anything that acts like Unix as being Unix-like, or using a Unix environment. But I'll probably mess up and use the word Unix to describe any number of environments from Linux to Mac.

The Terminal: The Unix User Interface

The history of Unix is beyond the scope of this post (see the Wikipedia page if you're interested), but suffice to say, it's old. The default user interface (UI) in Unix is a text-based terminal like the one shown below.

A terminal in Linux, image credit goes to william @ Linoxide

Interactions with the terminal consist of inputting lines of text, hitting Enter/Return, then reading the resulting output of text.

Much of how we interact with computers on an everyday basis is through a graphical user interface (GUI) where we have visual cues such as a desktop-analog to help us remember how to find things. Of course, now much of our casual computational interaction are through touch interfaces on phones, which is even more different than the Unix environment. That's not to say that you can't have multiple UIs for a single OS. In fact most Unix-like OSs come with a built-in desktop environment, in addition to a terminal interface.

So if we're all familiar with desktop environements, why bother with the terminal? If you search on the internet for an answer to that questions, you'll probably find vague answers along the lines of the terminal being "more powerful" than a GUI environment. This may be true, but if you haven't experienced a use case for the power that comes from a text-based UI, then it rings somewhat hollow. Suffice to say, if you want to manage textual data in a precise and efficient way, a Unix-like environment provides numerous tools for doing so. Throughout this course I'll to try regularly highlight useful Unix programs that complement the tools we learn about within the Python programming language. But for now, we'll suffer through it together and pick up on some of benefits of learning to work in a textual UI along the way!

The Unix Environment

From GUI desktop environments, we're used to the idea of there being files and folders. Files are things with data (textual or otherwise), and folders are collections of files and other folders. In Unix land, folders are usually called directories, but it's the same idea. Since directories can be nested and they (usually) don't contain directories which they themselves are members of, we can often think of the Unix filesystem as a tree, with a root directory at the top which contains all other directories (at some arbitrary nested depth of directories).

We can visualize this tree as shown below.

Linux directory tree, from oreilly.com

Since the terminal is a text-based UI, we need a consistent way refer to the path to these directories. In other words, how do we find a particular directory or file in the tree? The root of this tree is denoted with a single forward slash, /. Directories under this root will be written to the right of the slash. So a directory named foo located within this root directory would be labeled as /foo. If the directory foo contains a directory named bar, then we the path to bar would be /foo/bar. If foo also contained a file called baz, we would write the path to this file as /foo/baz. In the tree shown above, the directory /home/patrick/school is two levels under the root directory. This is different than the directory /home/bill/school, since, despite sharing the same name, they have different paths.

For the most part, you'll be working under your home directory. In macOS, this is /Users/yourusername (e.g., mine would be /Users/adwasser). As a general principle, don't mess with things outside your home directory, though the way most Unix-like systems are configured, only an administrator can do so.

Also, as a shortcut to your own home directory, you can use a tilde, ~. So if I wanted to refer to the directory projects located under my home directory, I could use the path ~/projects.

Where do these directory names come from?

In the diagram above, there are some weirdly named directories (bin, usr, etc). You can read about these in the Wikipedia page on the Unix filesystem here. On macOS, your home directories are located under /Users instead of /home. Of note, it is tempting to guess that /usr is short for "user"; while this might (?) have been true at some point, better to think of this now as Unix System Resources.

Terminal-ology

Technically, the actual program that processes the text that we input is called the shell. There are a large number of shells out there, but by far the most common one is called bash. Other somewhat less common shells are csh, tcsh, sh, and zsh. The terminal just refers to the program that reads your keyboard input and graphically displays the output of a shell, and you can use different terminal programs with different shells. macOS comes with a built-in terminal program, but there are other ones out there too.

Most shells provide some sort of prompt for input. In the example in the first image, the dollar sign, $, shows where you can enter text for the shell to process. Here the text on the left of the prompt shows the user (wschalle), the name of the machine (WillyLaptop), and the current working directory, (~, the user's home directory).

While working in the shell, we will always have some working directory. This is the directory that we are currently "located" in. While a directory is our working directory, we can refer to subdirectories as a relative path by not including the root directory. For example, my working directory was my home directory, located at the path /Users/adwasser, I could refer to the file located at /Users/adwasser/projects/notes.txt as projects/notes.txt.

You can always refer to your current working directory with a single dot (period). For example, while in my home directory, the paths /Users/adwasser/projects, ~/projects, and ./projects all refer to the same directory.

You can refer to the directory above you current working directory with two dots. So if we were in /Users/adwasser/projects, then .. would refer to the directory /Users/adwasser.

Interacting with Unix Programs

Unix programs are called by typing their name and hitting Enter (or Return on Mac keyboards). Programs can accept one or more arguments, with spaces delimiting the program and any arguments. For example, echo is a somewhat silly, though occasionally useful program that prints out whatever you give it. So if you were to type echo hello and hit Enter at the prompt, this would output the text "hello". You can also call echo without any arguments, in which case it returns an empty line. There are actual uses for this program in real life, since most shells allow for some sort of variables, or containers for differnt kinds of data. So we might actually want to print out the textual representation of some variable by using echo. But variables in programming will be a topic for later in the course.

Navigating through the Trees

There are a handful of basic Unix commands, or programs, that are invaluable for navigating this environment. Unix commands are notoriously terse, but there are some good mnemonics for remembering what they all do.

  • ls

Short for "list". Typing this command in the terminal will output text that indicates the files and directories contained in the current working directory. You can also call ls with a directory as the argument, in which case it will print out the files and directories of that directory. So for example, with my home directory as my working directory, I could enter ls to see what's inside my home directory, but I could also enter ls /usr to see what's contained in the directory /usr.

  • cd

Short for "change directory". How do you change your working directory? cd is your friend. If you call it without an argument, your home directory will become your working directory. If you call it with a directory as an argument, then that directory become your working directory.

  • pwd

Short for "print working directory". Like the extended name implies, this simply prints out where you currently are located in the directory tree.

Common pitfalls

  • Unix is case-sensitive, so "Foo" is different than "foo" is different than "FOO"

  • Spaces have meaning. In particular, spaces are usually interpreted as separation between programs and their arguments. If you had a python file with spaces (e.g., "My Program.py"), you wouldn't be able to run this as python My Program.py. Rather, you would have to escape the space by typing python My\ Program.py. Best to just avoid spaces in filenames or directory names, using underscores if need be.

social