01. The Shell

Dated Feb 6, 2020; last modified on Sun, 18 Sep 2022

Topic 1: The Shell. missing.csail.mit.edu .

What is the Shell?

At their very core, shells are all roughly the same: they allow you to run programs, give them input, and inspect their output in a semi-structured way.

Potpourri of Shell Utilities and Programs

We can find out which file is executed for a given program name using the which program, e.g. $ which python gives me /Users/dchege711/anaconda3/bin/python

Connecting Programs

While > overwrites a file’s content, >> appends to a file.

| lets me chain programs such that the output of one is the input of another. This is where the shell shines.

Too Much Powaah

One rarely logs into the system as the root user since it’s too easy to accidentally break things. The sudo command lets you ‘do’ something as ‘su’ - the super user.

To write to the sysfs file system mounted under sys, you need to be root. For instance, here’s a recipe to change the brightness of your laptop’s screen:

$ sudo find -L /sys/class/backlight -maxdepth 2 -name '*brightness*'
/sys/class/backlight/thinkpad_screen/brightness
$ cd /sys/class/backlight/thinkpad_screen

$ sudo echo 3 > brightness would fail because sudo only applies to the echo command. Since the shell does not run as root, you need $ echo 3 | sudo tee brightness.

The tee utility copies standard input to standard output, making a copy in zero or more files. tee runs as the root user, so permissions work out.

But since I’m on MacOS, I do not have the sysfs. These damned walled gardens!

The Shell Prompt

The prompt can be customized to provide more useful information. Oh My Zsh offers further customization, e.g. support for Git, but I’ll stay vanilla for now. I think the shell is too powerful for me to add dependencies . My ZSH shell is now:

# If I'm root, show a red '#', otherwise show a green '$'. '%f' resets the color
USER_ROOT_OR_NOT="%(!.%F{red}#%f.%F{green}$%f)"
# %~ gives current directory, replacing $HOME with ~
PROMPT="%F{cyan}%~%f ${USER_ROOT_OR_NOT} %f"

The Curious Case of /tmp

I’m surprised that it’s not the same as the TMPDIR environment variable. On my machine, TMPDIR = /var/folders/gc/p6lgv5555nnfsggg7_wwwn440000gn/T/

According to /u/nohillside (apple.stackexchange.com) , TMPDIR is only available to the logged in user.

/etc/defaults/periodic.conf (described in the periodic.conf(5) man page ) shows that my any file in my /tmp folder that hasn’t been accessed in 3 days gets deleted.

Terminal Escaping

$ echo "!/bin/sh" > somefile.txt doesn’t work

Double quotes preserve the literal value of all characters within the quotes except ‘$’, ‘`’, ‘' and, when history expansion is enabled, ‘!’. Single Quotes (gnu.org)

In contrast, single quotes preserve the literal value of each character. A single quote may not occur between single quotes, even when preceded by a backslash. Double Quotes (gnu.org)

Proper Use of chmod

​​All this time I’d been using chmod wrong. I blindly ran $ chmod 700 myfile and consequently locked everyone out.

According to the man page, we’d arrive at 700 from 400 (owner can read) + 200 (owner can write) + 100 (owner can execute). But I think we can interpret it as the bit that is set in the rwx triple, e.g. 111 = 7

The default settings are -rw-r--r--. To give myself executing permissions, I should run chmod with a value of (400 + 200 + 100) + (40) + (4) = 744, to make it -rwxr--r--

String Matching Exercise

Challenge: Use | and > to write the “last modified” date output by semester into a file called last-modified.txt in your home directory.

The contents of semester were:

#!/bin/sh
curl --head --silent https://missing.csail.mit.edu

​​I had trouble with this. What program should I pipe semester’s output so that the end result is the “last modified” line only?

Took me some time to find it: $ ./semester | grep --regexp=Last-Modified*. I knew grep did some regex matching, but I didn’t know it matched per line. That’s neat!