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!