Initial commit: CLI walkthrough for CHEG 667-013

Six-module walkthrough covering navigation, files, reading/searching,
processes/editors, scripting, and advanced tools (ssh, regex, tar, etc.).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Eric 2026-04-04 21:54:48 -04:00
commit c57d7539d8
10 changed files with 1415 additions and 0 deletions

275
01-navigation/README.md Normal file
View file

@ -0,0 +1,275 @@
# CLI Part I: Navigation
**CHEG 667-013 — Chemical Engineering with Computers**
Department of Chemical and Biomolecular Engineering, University of Delaware
---
## Key idea
Install and use the command line interface to navigate the file system.
## Key goals
- Open a terminal on your operating system
- Navigate the file system with `pwd`, `ls`, and `cd`
- Understand the root directory, absolute and relative paths, file permissions, and linked files
- Get help using `man` pages
---
Our goal this week is to learn about the command line interface (CLI). We will start by discussing computer operating systems and the CLI. As we progress, we will learn about various tools for automating tasks, writing and running programs, including shell scripts, and manipulating the file system.
Our focus will be on Unix commands. This is the native environment for Linux and macOS. For Windows users, there is a CLI called *PowerShell*, but it uses different commands. While it is worth familiarizing yourself with PowerShell, to follow along you'll need to install the *Windows Subsystem for Linux*. As of 2019, WSL 2 runs a virtualized full Linux kernel.
## 1. Running a command line interface
### Windows
Windows 10 and 11 users need to install the *Windows Subsystem for Linux* (WSL). In short: open PowerShell **as Administrator**, run `wsl --install`, restart your computer, then launch Ubuntu from the Start menu to create a username and password.
See [**WSL.md**](WSL.md) for detailed step-by-step instructions and troubleshooting.
- [How to install Linux on Windows with WSL](https://learn.microsoft.com/en-us/windows/wsl/install)
- [Set up a WSL development environment](https://learn.microsoft.com/en-us/windows/wsl/setup/environment)
- An alternative to WSL is to run a virtual machine (VM) using a hypervisor program like VMWare or VirtualBox. The latter is available at https://www.virtualbox.org
### macOS and Linux
Because the Macintosh OS is a derivative of Unix, users will have access to the Unix command line interface through the *Terminal* program. Just run Terminal. Most of the commands we will discuss are more or less identical between Linux and macOS, but there can be some differences.
Most Linux installations will boot to a GUI like Gnome or KDE. From there, you can run a terminal program like *xterm*.
> **Exercise 1:** Open a terminal window. Install WSL, if necessary.
## 2. Two tips before we start
Before we dive in, two things that will make your life easier from day one:
**Tab completion.** When typing a file or directory name, press the `Tab` key and the shell will try to complete it for you. If there's only one match, it fills in the rest. If there are multiple matches, press `Tab` twice to see the options. This saves enormous amounts of typing and prevents typos. Get in the habit of using it — experienced users press `Tab` constantly.
```
$ cd Dow<Tab>
$ cd Downloads/
```
**Clearing the screen.** When your terminal gets cluttered with output, type `clear` or press `Ctrl-L` to get a fresh screen. Your history is still there — just scroll up.
## 3. Navigating the file system
You should see a prompt. The prompt might include user and directory information. Here are some commands we use to navigate the file system:
- `pwd` — return working directory name
- `ls` — list directory contents
- `cd` — change directory
The command `pwd` is perhaps the easiest to understand; it shows us our current working directory:
```
$ pwd
/home/ef1j
```
This tells us that we're in the *home directory* of user `ef1j`. We see that it has the *absolute path* of `/home/ef1j`. We'll look at this more in detail below.
**NOTE:** The tilde character, `~`, is special. It can be used to refer to our home directory or the home directory of another user, as in `ls ~luser`.
Each command can have a number of options. Let's take a closer look at the `ls` command. I might see something like this when I type it after starting the terminal:
```
$ ls
Desktop/ Downloads/ Pictures/ Templates/
Documents/ Music/ Public/ Videos/
```
The command shows that there are several *directories* in `/home/ef1j` (Desktop, Downloads, etc.). I can get more information using the option `-l`:
```
$ ls -l
total 4
drwxr-xr-x 2 ef1j ef1j 2 Jul 30 2024 Desktop/
drwxr-xr-x 2 ef1j ef1j 2 Jul 30 2024 Documents/
drwxr-xr-x 2 ef1j ef1j 2 Jul 30 2024 Downloads/
drwxr-xr-x 2 ef1j ef1j 2 Jul 30 2024 Music/
drwxr-xr-x 2 ef1j ef1j 2 Jul 30 2024 Pictures/
drwxr-xr-x 2 ef1j ef1j 2 Jul 30 2024 Public/
drwxr-xr-x 2 ef1j ef1j 2 Jul 30 2024 Templates/
drwxr-xr-x 2 ef1j ef1j 2 Jul 30 2024 Videos/
```
which now shows the owner of each directory (`ef1j`), its group, and the date it was created or last modified.
If I type the command `ls -a`, I might see the following:
```
$ ls -a
./ .dbus/ .mozilla/ Videos/
../ Desktop/ Music/ .vnc/
.bash_aliases Documents/ Pictures/ .wget-hsts
.bash_history Downloads/ .profile .Xauthority
.bash_logout .gnupg/ Public/ .xsession-errors
.bashrc .ICEauthority .ssh/
.cache/ .lesshst .sudo_as_admin_successful
.config/ .local/ Templates/
```
It shows a number of *hidden files and directories* that are part of the system settings or used for application support.
## 4. Getting information and help
Now is a good time to introduce where we can get some help with Unix commands. Unix systems have a built-in help system of *manual pages*. The command to access these is `man`.
- Type `man ls` to see the options for the list command.
The `man` command creates a formatted *man page* in the terminal window. (Hence the answer to the oft-asked question of how a command works: *"RTFM!"* or *"Read the freakin' man (page)!"*)
- Use *space* to scroll ahead, *u* to move back up, and */* to search for a term.
> **Exercise 2:** Try several `ls` commands and options, like:
> - `ls -l` — long format
> - `ls -lt` — long format, newest first
> - `ls -lh` — long format, "human readable output"
> - `ls -F` — append indicator (one of `*/=>@|`) to entries
>
> Note how you can combine options. Use the `man` page to find more options to try. Maybe these will be more interesting once we have more files?
Note the following:
- Command options can be separate or combined: `ls -l -t` is the same as `ls -lt`. Try both!
- Sometimes options have input.
## 5. Changing directories
When we start a terminal session, usually we're placed in our home directory. This is part of the file system structure that you may normally see as folders in a GUI. Try going one step higher in the file system:
```
$ cd ..
```
In my case, I go one directory up to the `/home` directory. If I list the current directory, I see my user folder, and if I use the `pwd` command, it tells me that I'm in `/home`.
```
$ ls
ef1j/
$ pwd
/home
```
Note the following:
- Two dots, `..`, refers to the directory immediately above the current directory.
- One dot, `.`, refers to the current directory. It can be important in some commands, including running a program in the current directory.
A few tips:
- Typing `cd` alone will take you to your home directory.
- `cd -` will take you back to the directory before the last `cd` command. Try it!
## 6. Absolute and relative paths
You'll encounter two ways to specify a location in the file system:
An **absolute path** starts from the root directory `/` and spells out the full location. It works no matter where you are in the file system:
```
$ cat /home/ef1j/cheg667/bar
```
A **relative path** starts from your current directory. If you're already in `/home/ef1j`, you can write:
```
$ cat cheg667/bar
```
Both commands do the same thing — one is just shorter. Here are the special shortcuts for relative paths:
| Symbol | Meaning | Example |
|--------|---------|---------|
| `.` | Current directory | `./a.out` (run a program here) |
| `..` | Parent directory | `cd ..` (go up one level) |
| `~` | Home directory | `cd ~/cheg667` |
A good rule of thumb: use absolute paths in scripts (so they work regardless of where you run them) and relative paths when typing interactively (less typing).
## 7. Root directory
Go one more level up using `cd ..` or type `cd /`. If you use `ls`, you should see something like this:
```
$ ls
bin@ dev/ home/ lib32@ libx32@ mnt/ proc/ run/ snap/ sys/ usr/
boot/ etc/ lib@ lib64@ media/ opt/ root/ sbin@ srv/ tmp/ var/
```
This is the *root* directory. It contains directories that hold many of the system files. Here are a few you might see:
- `/bin` — executable programs or binaries (in this case, it points to `/usr/bin`)
- `/boot` — system startup files
- `/dev` — system device files
- `/etc` — system configuration files
- `/lib` — various *libraries* that the different software uses
- `/media` — removable drives and disks will normally show up here
- `/mnt` — mount point for manually mounting drives and devices
- `/opt` — installed software, like `anaconda` environments
- `/proc` — computer info (process information pseudo-file system)
- `/root` — root user home
- `/sbin` — superuser programs
- `/sys` — information about devices
- `/tmp` — temporary files
- `/usr` — system files, including executables and binaries
- `/var` — log files, lock files, spool files, and other system info
> **Exercise 3:** Explore! Using `cd` and `ls`, look around the file system. Use `ls -l` and `ls -lt` to look at when the files and directories were created or modified. Who is the owner of the file? Be sure to look at the files in `/bin` or `/usr/bin`. You should be able to find the programs we've been using (`ls`, `cd`, `man`) and many others.
### Linked files
You might see some files like this:
```
lrwxrwxrwx 1 root root 7 Apr 24 2022 bin -> usr/bin/
```
The `l` indicates that this is a *linked* file or directory. Notice how it points to a different directory, `/usr/bin`. This allows the file system to have more than one name for a file or directory. See `man ln` for more information.
### File permissions
In my directory listing, I also see the following for the `/etc` directory:
```
drwxr-xr-x 105 root root 195 Feb 4 16:12 etc/
```
The letters indicate that the file is a directory. There are three groups of letters after this that indicate permissions:
- `r` — read, `w` — write, and `x` — execute
Each of the three groups corresponds to:
- the file owner, the group, and all or everyone.
In this case, `root` is the owner. This is the super-user or system administrator. The user `root` can read, write, or execute files and programs in `/etc`. Members of the `root` group can, too. As a normal user who is not in the `root` group, we can only read and execute files and programs.
## Exercises
> **Exercise 4:** In your home directory, type `ls -R`. What does this command do? What do you see?
> **Exercise 5:** Type `ls /root`. What happens? Why?
> **Exercise 6:** What does the `cat` command stand for? What are some other uses of the command besides creating and printing a file?
## Additional resources and references
- [Command line for beginners](https://ubuntu.com/tutorials/command-line-for-beginners#1-overview)
- [Using Linux](https://linuxcommand.org)
- [The Linux filesystem explained](https://www.linuxfoundation.org/blog/blog/classic-sysadmin-the-linux-filesystem-explained)

162
01-navigation/WSL.md Normal file
View file

@ -0,0 +1,162 @@
# Installing WSL (Windows Subsystem for Linux)
This guide walks you through installing WSL on Windows 10 or 11. macOS and Linux users can skip this entirely.
---
## Step-by-step installation
### 1. Check your Windows version
Press `Win+R`, type `winver`, and press Enter. You need **Windows 10 build 19041 or later**, or **Windows 11**.
### 2. Open PowerShell as Administrator
This is important — a normal PowerShell window will not work.
- Click the **Start** button, type **PowerShell**
- Right-click **Windows PowerShell** and select **Run as administrator**
- Click **Yes** when prompted by User Account Control
Alternatively, right-click the Start button and choose **Terminal (Admin)**.
### 3. Install WSL
In the administrator PowerShell window, type:
```powershell
wsl --install
```
This single command does several things:
- Enables the WSL and Virtual Machine Platform features
- Downloads the latest Linux kernel
- Sets WSL 2 as the default version
- Downloads and installs Ubuntu
You should see progress output as it downloads and installs.
### 4. Restart your computer
When the install finishes, **restart your computer**. This is required — the features enabled in step 3 won't be active until you reboot.
### 5. Launch Ubuntu
After restarting, open the **Start** menu and search for **Ubuntu**. Click it to launch.
The first time you open Ubuntu, it will spend a minute or two decompressing files. This is normal — just wait.
### 6. Create your Linux username and password
Ubuntu will prompt you to create a new account:
```
Enter new UNIX username:
```
Pick a simple lowercase name with no spaces (e.g., `jsmith` or your UDel login).
Next, it will ask for a password. **Nothing will appear on screen while you type your password.** This is normal Linux behavior — it's not broken, it's just hiding your input for security. Type your password and press Enter. You'll be asked to confirm it.
### 7. Verify it's working
You should now see a Linux prompt that looks something like:
```
jsmith@DESKTOP-ABC123:~$
```
Try a few commands to confirm everything is working:
```bash
pwd
ls
whoami
```
### 8. Update your packages
It's good practice to update Ubuntu right after installing:
```bash
sudo apt update && sudo apt upgrade -y
```
You'll be prompted for the password you just created.
You're all set!
---
## Troubleshooting
### `wsl --install` just shows help text
This means WSL was already partially enabled on your machine (perhaps from a previous attempt). Instead, run:
```powershell
wsl --install -d Ubuntu
```
### The install hangs or stalls at 0%
Try downloading the distribution from the web instead:
```powershell
wsl --install --web-download -d Ubuntu
```
### "The virtual machine could not be started" (error 0x80370102)
Your computer's hardware virtualization may be disabled. You need to enable it in your BIOS/UEFI settings:
1. Restart your computer and enter the BIOS (usually by pressing `F2`, `F10`, `Del`, or `Esc` during boot — it varies by manufacturer)
2. Look for a setting called **Intel VT-x**, **Intel Virtualization Technology**, or **AMD-V** (usually under CPU or Advanced settings)
3. Enable it, save, and restart
### "WslRegisterDistribution failed" (error 0x8007019e)
The WSL feature itself isn't enabled. Open PowerShell as Administrator and run:
```powershell
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
```
Then restart and try again.
### `wsl` is not recognized as a command
Make sure you're using a 64-bit PowerShell. Try typing `wsl.exe` instead of `wsl`.
### I forgot my Linux password
From PowerShell (not inside Ubuntu), run:
```powershell
wsl -u root
```
Then reset your password:
```bash
passwd your_username
```
---
## Launching WSL after installation
Once installed, you can open your Linux terminal in any of these ways:
- **Start menu**: Search for **Ubuntu**
- **PowerShell or Command Prompt**: Type `wsl`
- **Windows Terminal** (recommended): Ubuntu appears as an option in the dropdown tab menu. Windows Terminal supports multiple tabs and is a nicer experience overall.
---
## References
- [Install WSL (Microsoft docs)](https://learn.microsoft.com/en-us/windows/wsl/install)
- [Set up a WSL development environment](https://learn.microsoft.com/en-us/windows/wsl/setup/environment)
- [WSL troubleshooting (Microsoft docs)](https://learn.microsoft.com/en-us/windows/wsl/troubleshooting)

176
02-files/README.md Normal file
View file

@ -0,0 +1,176 @@
# CLI Part II: Files and Directories
**CHEG 667-013 — Chemical Engineering with Computers**
Department of Chemical and Biomolecular Engineering, University of Delaware
---
## Key idea
Create, move, copy, and delete files and directories from the command line.
## Key goals
- Create directories with `mkdir` and remove them with `rmdir`
- Create files with `touch` and `cat`
- Move, copy, and remove files with `mv`, `cp`, and `rm`
- Understand that these operations are permanent — there is no trash can or undo
---
## 1. Making and removing directories
If we want to add or remove folders to our file hierarchy, we use the following commands:
- `mkdir` — make a directory
- `rmdir` — remove a directory (it needs to be empty)
**WARNING!** Removing a directory is *permanent*. **There is no trash can or undo!** This will apply to files, too.
Now go back to your home directory (`cd ~`) and make a new folder called `cheg667`:
```
$ mkdir cheg667
```
Verify that you made the directory by using `ls`. You can remove this directory with the `rmdir` command.
## 2. Moving, copying, and removing files
Now we'll learn how to move, copy, or remove files.
- `mv` — move (or rename) a file
- `cp` — copy a file
- `rm` — delete or remove a file
**WARNING!** All of these file operations are permanent! There is no undo! Moving or copying a file on top of another will erase or *clobber* the original. Be careful!
We need some files to work on. Do this in your home directory:
```
$ touch foobar
```
The `touch` command is a way of updating the modification time of a file. If the file doesn't exist, `touch` will create one. If we use `ls -lt`, we should see at the top that we created the file `foobar`, which has zero bytes.
```
-rw-rw-r-- 1 ef1j ef1j 0 Mar 30 06:57 foobar
```
Notice the file permissions. The file can be read by the user, group, and other users. Only the user and the group have permission to write to or otherwise modify the file or erase it.
Next, move `foobar` to the directory `~/cheg667`:
```
$ mv foobar cheg667
```
If you type `ls` now, you will not see it. But if you change directory to `cheg667` or type `ls cheg667`, you will find that it was moved to that directory.
Change directories to `cheg667` and type the following:
```
$ cp foobar foo
```
This copies the file `foobar` to a new file, `foo`:
```
$ ls
foo foobar
```
Notice that the file modification times are different:
```
$ ls -l
total 1
-rw-rw-r-- 1 ef1j ef1j 0 Mar 30 07:08 foo
-rw-rw-r-- 1 ef1j ef1j 0 Mar 30 06:57 foobar
```
## 3. Creating files with cat
Create another file, but this time with text using the `cat` command:
```
$ cat > bar
Terminal whispers,
cat > file.txt begins
empty lines take shape
^D
```
When you type `cat > bar`, it is telling the terminal to redirect the *standard input* of the terminal to a file. (More on this later.) When you hit enter, the input that you type will be written to the file. You can stop by typing `control-D`. Verify that the text was written to the file, again using the `cat` command:
```
$ cat bar
Terminal whispers,
cat > file.txt begins
empty lines take shape.
```
Using `ls`, you will also see that the file has a non-zero size:
```
-rw-rw-r-- 1 ef1j ef1j 67 Mar 30 07:18 bar
```
Now copy the file `bar`. Call it `bar2`:
```
$ cp bar bar2
```
Do you see it in the directory listing?
You can remove `bar2` with the command:
```
$ rm bar2
```
Check the directory listing again. The file should be gone.
## 4. Creating files with echo
The `echo` command prints text to the terminal. It's useful for quick output and for writing short content to files using a redirect:
```
$ echo "Hello, world!"
Hello, world!
$ echo "This is a test" > test.txt
$ cat test.txt
This is a test
```
Use `>>` to append instead of overwriting:
```
$ echo "Another line" >> test.txt
$ cat test.txt
This is a test
Another line
```
## 5. Changing file permissions with chmod
In the previous section, we saw that files have permissions (`r`, `w`, `x`) for the owner, group, and others. The `chmod` command lets you change these permissions. You'll need this when you want to make a file executable, like a script.
The most common use for us is adding execute permission:
```
$ chmod u+x myscript.sh
```
Here, `u` means the user (owner), `+x` means add execute permission. You can also set permissions for the group (`g`) or others (`o`):
- `chmod g+r file` — give the group read access
- `chmod o-w file` — remove write access from others
- `chmod a+x file` — give everyone execute access (`a` = all)
> **Exercise 1:** Practice making new text files with the `cat` and `echo` commands. Rename a file using `mv`. Practice copying files. Use `man` to learn more about `mv`, `cp`, `rm`, and `chmod`.

View file

@ -0,0 +1,109 @@
# CLI Part III: Reading and Searching
**CHEG 667-013 — Chemical Engineering with Computers**
Department of Chemical and Biomolecular Engineering, University of Delaware
---
## Key idea
Read, search, and filter files using command line tools, and combine them with pipes and redirects.
## Key goals
- Page through files with `cat`, `more`, and `less`
- Search for patterns in files with `grep`
- Connect commands together using pipes (`|`) and redirects (`>`, `>>`, `<`)
---
## 1. Reading files
We've already used the `cat` command to print a file. Several other programs are useful for scanning through files. These include:
- `cat` — print a file
- `head` — show the first lines of a file (default: 10)
- `tail` — show the last lines of a file (default: 10)
- `more` — page through a file one screen at a time
- `less` — "Opposite of more." (macOS `more` actually runs `less`.)
- `wc` — word count — count lines, words, and characters in a file
- `grep` — file pattern searcher
`head` and `tail` are handy for quickly peeking at a file without printing the whole thing:
```
$ head -5 lsR_filesystem.txt # first 5 lines
$ tail -20 lsR_filesystem.txt # last 20 lines
```
`wc` tells you how big a file is. With the `-l` option, it counts just the lines:
```
$ wc lsR_filesystem.txt
14328 112849 893752 lsR_filesystem.txt
$ wc -l lsR_filesystem.txt
14328 lsR_filesystem.txt
```
The three numbers are lines, words, and characters (bytes).
> **Exercise 1:** Make a directory listing of the root file system with `ls -lR / > lsR_filesystem.txt`. Use `head` to see the first 10 lines. Use `tail` to see the last 10 lines. Then page through the file using `less`. Move up and down. Can you find a particular file using a search?
## 2. Searching with grep
Of the programs above, `grep` is a little different. It is used to find files with matching strings. Its basic use looks something like this:
```
$ grep 'string' filename
```
which will look for `string` in the file `filename`.
### More help with less
Incidentally, in addition to the `man` pages, many commands have built-in help. Try running `less --help`. This also shows us that some options are preceded by a long dash. You might also try `less -?`.
## 3. Pipes and redirects
Pipes and redirects enable you to control the flow of information to and from processes.
- `|` — a pipe
- `>` — redirect output to a file (this will always overwrite the file)
- `>>` — redirect and *append* output to a file
- `<` — use a file as input
One of the design philosophies of Unix centers around providing small, focused program tools that can be used together. Pipes send the output of one program to the input of another. Try it! Type:
```
$ ps aux | less
```
The `ps aux` command will generate a long list of processes that scroll past quickly. By "piping" the command to `less`, it is easier to page through the output.
In Exercise 1, we redirected the output of `ls` to a file.
> **Exercise 2:** Use `grep` to search `lsR_filesystem.txt` for a program you have used (e.g., `grep ls lsR_filesystem.txt`). Try searching for other programs.
> **Exercise 3:** Combine commands with pipes. For example, try `history | grep cd` to find all the `cd` commands you've used. Try `ls /usr/bin | less` to page through the programs in `/usr/bin`.
## 4. Running commands as the administrator with sudo
Some commands require administrator (or *superuser*) privileges — things like installing software, modifying system files, or changing other users' settings. The `sudo` command ("superuser do") lets you run a single command with these elevated privileges:
```
$ sudo apt update
[sudo] password for ef1j:
```
You'll be prompted for *your* password (not the root password). If your account has been granted `sudo` access, the command will run as the administrator.
Use `sudo` only when you need to. Running everyday commands with `sudo` is unnecessary and can accidentally modify system files. A common pattern you'll see is using `sudo` for package management:
```
$ sudo apt update && sudo apt upgrade
```

View file

@ -0,0 +1,180 @@
# CLI Part IV: Processes and Editors
**CHEG 667-013 — Chemical Engineering with Computers**
Department of Chemical and Biomolecular Engineering, University of Delaware
---
## Key idea
Monitor and control running processes, edit files in the terminal, and use control characters and job control.
## Key goals
- Check system information with `who`, `ps`, `top`, and `uptime`
- Kill runaway processes
- Edit files with `vi`, `nano`, or `emacs`
- Use control characters (`^C`, `^Z`, `^D`) and job control (`fg`, `jobs`, `&`)
---
We continue on our quest to learn about the command line. There is a lot to learn and the commands are somewhat cryptic. The best way to get comfortable with the command line is to use it. Look around the system. You can't really break anything. You generally don't have the permissions to edit, move, or delete system files.
That said, remember: there is no undo when it comes to your own files. A good practice is to make backup copies of important files!
## 1. System information and managing processes
There are several useful programs for seeing who or what is running on a machine.
- `who` — display who is on the system
- `w` — display who is on the system and what they are doing
- `whoami` — display the current user ID
- `ps` — process status — information about processes on the system
- `top` — display sorted information about processes (like activity monitor)
- `uptime` — show how long system has been running
`ps` returns important information like the *process id*, a unique number assigned to every running process. The command has a few options, and a somewhat strange syntax. Most systems will interpret `ps aux` as a command that lists all running processes on a system.
> **Exercise 1:** Try out each of the commands above!
### Killing a process
If you have a process that seems to be hanging, like a program with a buggy infinite loop (maybe `top` shows a lot of CPU use and the fan is spinning loudly), you can terminate it with the `kill` command. You first have to find the process id using `ps`. Then type:
```
$ kill pid
```
## 2. Editing files in the terminal
Most of the time, we can use an editor or development environment to write code. However, sometimes we need to write or edit a file in the terminal, including configuration files. There are a few options (some people have [strong feelings about editors](https://en.wikipedia.org/wiki/Editor_war)):
- `vi` — "a programmers text editor"
- `nano` — a "small and friendly editor"
- `emacs` — Emacs is more than an editor.
- `ed` — line editor for Yoda-level Jedi editing.
> **Exercise 2:** Using one of the editors above, type in the following short C program:
>
> ```c
> #include <stdio.h>
> int main() {
> printf("hello, world");
> }
> ```
>
> Save this file as `hello.c`.
There is a bit of a learning curve for each of these editors, but they can be quite useful. Most users will choose `vi` or `nano`. The "standard editor" `ed` is found on almost every machine and can be a good fallback if you need to repair a system or make a quick edit.
### C programming side quest
Use the C compiler to create an executable program from our `hello.c` code:
```
$ cc hello.c
$ ls
a.out* hello.c
```
Now we have an executable file `a.out`. Run it by typing `./a.out`. A right of passage!
## 3. Controlling the terminal output
Several control characters are used to control the terminal and its output:
- `^C` — stop execution (halt a program or clear a terminal line)
- `^S` — pause output
- `^Q` — continue output
- `^D` — end of transmission / end of file
Here, the caret character `^` stands for `control`. You might use control-C the most.
## 4. Suspending and backgrounding processes
Sometimes you need to pause what you're doing (like editing a file) to perform another task. You can have multiple terminal windows (or tabs) open, but if you're working on a remote machine, it may be inconvenient to open multiple sessions. Suspending (pausing) execution is one option. In other cases, a program may take a while to run, and its output is written to files, not the terminal. In that case, running it in the background is a good option.
- `^Z` — suspend an active process
- `fg` — foreground a suspended or backgrounded process
- `jobs` — display status of jobs in the current session (not all shells)
- `&` — used after a command, this runs a process in the background
Type `cat` and `return`. Then type `^Z`.
```
$ cat
^Z
[1]+ Stopped cat
```
The `cat` command was reading from the standard input (the keyboard). When we typed control-Z, it suspended the process. Type `ps` and you should still see it listed as an active process. We can reactivate it using the command `fg`:
```
$ fg
cat
```
It tells us that the `cat` command is active again. (Nothing much will happen. Try typing a few lines. What do you see and why?)
Control-Z is useful when you are editing a file and need to return to the command line (although some editors have the ability to open a new shell). Use `vi` or `nano` to open your `hello.c` file. Then hit `control-Z`:
```
$ vi hello.c
[1]+ Stopped vi hello.c
$
```
Now do some other work. Compile the program:
```
$ cc hello.c
```
You should see a new file called `a.out`:
```
$ ls -l
total 20
-rwxrwxr-x 1 furst furst 15960 Mar 31 21:41 a.out*
-rw-rw-r-- 1 furst furst 65 Mar 31 21:41 hello.c
```
This is the executable or binary file compiled from our short C program. Run it by typing `./a.out`.
Now return to the editor. Type:
```
$ fg
vi hello.c
```
(This will put you back in the editor. You probably won't see these lines until you finally quit the editor, unless you're using `ed`.)
**Warning!** Any process running in the background will be terminated if you close the terminal session. There are a few tools to keep processes running after you disconnect:
- `nohup` — run a command immune to hangups. Prefix any command with `nohup` and it will keep running after the terminal closes. Output goes to `nohup.out` by default:
```
$ nohup ./long_simulation &
```
- `screen` — a terminal multiplexer that lets you create sessions you can detach from and reattach to later. Start a session with `screen`, run your work, then detach with `Ctrl-A d`. Reattach later with `screen -r`.
- `tmux` — a more modern terminal multiplexer with similar goals to `screen` but better defaults, window splitting, and scripting. Start a session with `tmux`, detach with `Ctrl-B d`, and reattach with `tmux attach`. `tmux` also makes it easy to split your terminal into panes:
```
$ tmux # start a new session
Ctrl-B % # split vertically
Ctrl-B " # split horizontally
Ctrl-B arrow-key # move between panes
Ctrl-B d # detach (session keeps running)
$ tmux attach # reattach later
```
Both `screen` and `tmux` are especially useful when working on a remote machine over SSH — if your connection drops, the session survives and you can reconnect to it.

187
05-scripting/README.md Normal file
View file

@ -0,0 +1,187 @@
# CLI Part V: Scripting
**CHEG 667-013 — Chemical Engineering with Computers**
Department of Chemical and Biomolecular Engineering, University of Delaware
---
## Key idea
Use wildcards, shell history, and shell scripts to work efficiently and automate tasks.
## Key goals
- Select multiple files with wildcards (`*`, `?`)
- Make directory backups with `cp -r`
- Use shell history to recall and re-execute commands
- Write and run a shell script
---
## 1. Wildcards and matching
In earlier sections, we used `mv`, `cp`, and `rm` to manipulate files one at a time. We can select more than one file to act on by using wildcards:
- `*` — match a string of characters
- `?` — match one character
For example, compare the output of these commands:
```
$ ls /dev/tty*
```
```
$ ls /dev/tty?
```
What files are listed in the first example? What is the difference in the second?
> **Exercise 1:** Practice listing certain files. Can you list all of the `/dev/tty` files that begin with `tty1`? How about all of the programs in `/usr/bin` that begin with the letter *p*? Try some other letters!
> **Exercise 2:** Count the number of files that begin with the letter *p* in `/usr/bin` by typing `ls /usr/bin/p* | wc -l`. What is the program `wc`? (RTFM!)
### Delete all files, recursively
Clear out a directory structure for deletion using the command:
```
$ rm -r *
```
Be careful! Remember, there is no undo!
## 2. Making a backup of a directory
What if I have a directory `~/foobar` with important files? I want to make a copy of that directory. Can I use the following command?
```
$ cp foobar foobar_backup
```
Why or why not? Try it!
The copy command will not act on a directory. However, we can copy all of the directory contents to a new directory using the recursion option, `cp -r`:
```
$ cp -r foobar foobar_backup
```
Now we should have a backup of `foobar` with all of the files (and directories). Here's the original directory:
```
$ ls -l foobar
total 20
-rwxrwxr-x 1 furst furst 15960 Mar 31 13:52 a.out*
-rw-rw-r-- 1 furst furst 61 Mar 31 13:52 hello.c
```
and here is the backup:
```
$ ls -l foobar_backup/
total 20
-rwxrwxr-x 1 furst furst 15960 Mar 31 18:07 a.out*
-rw-rw-r-- 1 furst furst 61 Mar 31 18:07 hello.c
```
Something interesting happened: when we copy the files, they have new modification times. This might be undesirable for a backup. But I can *preserve* the old modification times with the `-p` option:
```
$ cp -rp foobar foobar_backup
```
Now the copies of those files should preserve their original modification times. This holds for a number of other file transfer and copying commands, like `rsync` and `sftp`.
## 3. Shell history
Typing in a command again and again can be a drag. Luckily, most shells save a history of previous commands. You can refer back to this history and even execute previous commands.
- `history` — print the shell command history
- `!` and `!!` — execute a previous command or the most recent command
Type `history` (or maybe `history | less`):
```
$ history
...
2013 ls
2014 less weather.sh
2015 man whoami
2016 whoami
2017 man history
2018 history
```
Now, if I type `!less` ("bang less"):
```
$ !less
```
it will execute the last `less` instruction in my command history (in this case, `less weather.sh`). This is useful when commands are long and have a lot of options or if you need to repeatedly refer back to a text file, like the example here.
Typing `!!` ("bang-bang") will execute the last command in the history. This is also handy!
## 4. Shell programming
The shell is the program that is managing our input and output in the terminal. There are several shell programs to choose from including the Bourne shell `sh`, C shell `csh`, Korn shell `ksh`, Z shell `zsh`, but `bash` is a common default.
We can also write scripts in the shell. These may be used to run other programs or a combination of tasks. Programming the shell is a subject in itself, but a powerful tool. Here's one (perhaps useful) example to play with.
Type in the following and save it as `weather.sh` (or use the copy in this directory):
```bash
#!/bin/bash
# weather.sh [-s STATE] [ZONE]
usage() { echo "Usage: $0 [-s STATE] [ZONE]" 1>&2; exit 1; }
STATE="de"
ZONE="001"
while getopts "s:" flag; do
case "$flag" in
s) STATE="$OPTARG" ;;
*) usage ;;
esac
done
shift $((OPTIND - 1))
# Allow 0 or 1 positional arg (ZONE)
if [ "$#" -gt 1 ]; then
usage
fi
if [ "$#" -eq 1 ]; then
if [[ ! "$1" =~ ^[0-9]{3}$ ]]; then
usage
fi
ZONE="$1"
fi
STATE="${STATE,,}" # lowercase
curl -s "https://tgftp.nws.noaa.gov/data/forecasts/zone/${STATE}/${STATE}z${ZONE}.txt"
```
Now change the permissions to make this script executable:
```
$ chmod u+x weather.sh
```
You now have a short script that downloads the latest weather forecast! Who needs the web!
macOS Easter egg: `./weather.sh | tail -n +15 | say`
The shell script above shows how you can write your own Unix utility. It processes command options like the programs we've learned about and provides some user information, including fairly reasonable error processing.
> **Exercise 3:** Try a few different states and zones. (You'll have to look them up.) Redirect each report to a unique file. Can you concatenate these into one large file?
> **Exercise 4:** Write your own shell script. It can be simple — maybe one that creates a backup of a directory, or one that greets the user with the current date and time.

31
05-scripting/weather.sh Executable file
View file

@ -0,0 +1,31 @@
#!/bin/bash
# weather.sh [-s STATE] [ZONE]
usage() { echo "Usage: $0 [-s STATE] [ZONE]" 1>&2; exit 1; }
STATE="de"
ZONE="001"
while getopts "s:" flag; do
case "$flag" in
s) STATE="$OPTARG" ;;
*) usage ;;
esac
done
shift $((OPTIND - 1))
# Allow 0 or 1 positional arg (ZONE)
if [ "$#" -gt 1 ]; then
usage
fi
if [ "$#" -eq 1 ]; then
if [[ ! "$1" =~ ^[0-9]{3}$ ]]; then
usage
fi
ZONE="$1"
fi
STATE="${STATE,,}" # lowercase
curl -s "https://tgftp.nws.noaa.gov/data/forecasts/zone/${STATE}/${STATE}z${ZONE}.txt"

233
06-advanced/README.md Normal file
View file

@ -0,0 +1,233 @@
# CLI Part VI: Advanced Tools
**CHEG 667-013 — Chemical Engineering with Computers**
Department of Chemical and Biomolecular Engineering, University of Delaware
---
## Key idea
Connect to remote machines, transfer files, and use additional command line tools for everyday tasks.
## Key goals
- Connect to remote machines with `ssh` and transfer files with `scp` and `sftp`
- Download files from the web with `curl` and `wget`
- Find files with `find`, compare them with `diff`, and archive them with `tar`
- Identify commands with `which`
- Understand globs and regular expressions for pattern matching
---
## 1. Remote access with ssh
`ssh` (secure shell) lets you log in to a remote machine over the network. This is how you'll connect to department servers, computing clusters, or cloud machines:
```
$ ssh username@hostname
```
For example, to connect to a UD server:
```
$ ssh ef1j@mahler.che.udel.edu
```
You'll be prompted for your password on the remote machine. Once connected, you'll see a new prompt — everything you type now runs on the remote machine.
To disconnect, type `exit` or press `Ctrl-D`.
### SSH keys
Typing your password every time gets old. You can set up *SSH keys* for password-free login:
```
$ ssh-keygen # generate a key pair (press Enter for defaults)
$ ssh-copy-id username@hostname # copy your public key to the remote machine
```
After this, `ssh` will authenticate using your key instead of a password.
## 2. Transferring files with scp and sftp
Once you're working on remote machines, you'll need to move files back and forth.
### scp — secure copy
`scp` works like `cp`, but copies files over the network:
```
$ scp localfile.txt username@hostname:~/destination/
$ scp username@hostname:~/remotefile.txt ./
```
The first command copies a local file to the remote machine. The second copies a remote file to your current directory. Add `-r` to copy entire directories.
### sftp — secure file transfer
`sftp` gives you an interactive session for browsing and transferring files:
```
$ sftp username@hostname
sftp> ls
sftp> cd results
sftp> get output.csv
sftp> put input.dat
sftp> exit
```
Use `get` to download and `put` to upload. It's useful when you want to browse what's on the remote machine before transferring.
## 3. Downloading files with curl and wget
Both `curl` and `wget` download files from the web. You've already seen `curl` in the `weather.sh` script.
### curl
`curl` prints the downloaded content to the terminal by default. Use `-o` to save to a file:
```
$ curl -s https://example.com/data.csv -o data.csv
```
The `-s` flag is for "silent" mode (no progress bar).
### wget
`wget` saves to a file by default, which makes it simpler for straightforward downloads:
```
$ wget https://example.com/data.csv
```
Use `wget -r` to download entire directories or websites recursively. On macOS, `wget` may need to be installed separately (e.g., `brew install wget`), while `curl` is available by default.
## 4. Finding files with find
The `find` command searches for files by name, type, size, modification time, and more. It searches recursively through directories:
```
$ find . -name "*.csv" # find all CSV files in current directory and below
$ find ~/cheg667 -name "hello.c" # find a specific file
$ find . -type d # find all directories
$ find . -name "*.tmp" -delete # find and delete all .tmp files (careful!)
```
The first argument is where to start searching. The remaining arguments are filters.
## 5. Comparing files with diff
`diff` shows the differences between two files, line by line:
```
$ diff file1.txt file2.txt
3c3
< This is the original line.
---
> This is the modified line.
```
Lines starting with `<` are from the first file, `>` from the second. `diff` is useful for checking what changed between two versions of a file. You'll see it again if you use version control tools like `git`.
## 6. Identifying commands with which
If you're not sure where a command lives or which version you're running, `which` tells you:
```
$ which python
/usr/bin/python
$ which ls
/usr/bin/ls
```
This is especially helpful when you have multiple versions of a program installed (e.g., different Python installations) and need to know which one the shell is using.
## 7. Archiving files with tar
`tar` bundles files and directories into a single archive. It's the standard way to package things on Unix systems.
Create an archive:
```
$ tar -czf archive.tar.gz my_directory/
```
This creates a compressed archive (`-c` create, `-z` gzip compression, `-f` filename). Extract it with:
```
$ tar -xzf archive.tar.gz
```
(`-x` for extract). To see what's inside without extracting:
```
$ tar -tzf archive.tar.gz
```
You'll encounter `.tar.gz` (or `.tgz`) files frequently when downloading source code or datasets.
## 8. Globs and regular expressions
You've already used wildcards like `*` and `?` in section 05. These patterns are called *globs* — the shell expands them into matching filenames before the command runs. Here's the full set:
| Pattern | Matches | Example |
|---------|---------|---------|
| `*` | Any string of characters | `*.txt` — all text files |
| `?` | Exactly one character | `file?.dat``file1.dat`, `fileA.dat` |
| `[abc]` | One character from the set | `file[123].dat``file1.dat`, `file2.dat`, `file3.dat` |
| `[a-z]` | One character in the range | `[A-Z]*.txt` — files starting with a capital letter |
| `[!abc]` | One character *not* in the set | `file[!0-9].dat` — files where the character isn't a digit |
Globs are expanded by the shell and work with any command (`ls`, `cp`, `rm`, etc.).
### Regular expressions
Regular expressions (or *regex*) are a more powerful pattern language used inside programs like `grep`, `sed`, and many programming languages. Unlike globs, they aren't expanded by the shell — they're interpreted by the program itself.
Here are the basics:
| Pattern | Meaning | Example |
|---------|---------|---------|
| `.` | Any single character | `h.t` matches `hat`, `hit`, `hot` |
| `*` | Zero or more of the preceding character | `ab*c` matches `ac`, `abc`, `abbc` |
| `+` | One or more of the preceding character | `ab+c` matches `abc`, `abbc`, but not `ac` |
| `^` | Start of line | `^From` matches lines starting with "From" |
| `$` | End of line | `\.csv$` matches lines ending with ".csv" |
| `[ ]` | Character class (same as globs) | `[0-9]+` matches one or more digits |
| `\` | Escape a special character | `\.` matches a literal period |
**Watch out:** `*` means different things in globs and regex! In a glob, `*.txt` means "anything ending in .txt". In a regex, `*` means "zero or more of the previous character". This is a common source of confusion.
Using regex with `grep`:
```
$ grep '^From:' emails.txt # lines starting with "From:"
$ grep '[0-9][0-9]*\.[0-9]' data.txt # lines containing a decimal number
$ grep -i 'error' logfile.txt # case-insensitive search
$ grep -c 'warning' logfile.txt # count matching lines
$ grep -v '^#' config.txt # lines that do NOT start with #
```
The `-i` flag ignores case, `-c` counts matches instead of printing them, and `-v` inverts the match (shows non-matching lines). These options combine well with pipes:
```
$ ps aux | grep python # find running Python processes
$ history | grep -c ssh # how many times have I used ssh?
```
Regular expressions are a deep subject — you don't need to master them now, but recognizing the basics will help you read documentation and write better `grep` commands.
> **Exercise 1:** If you have access to a remote machine (a department server, for example), try connecting with `ssh`. Use `scp` to copy a file back and forth.
> **Exercise 2:** Use `find` to locate all `.c` files somewhere under your home directory.
> **Exercise 3:** Create a directory with a few files in it. Use `tar -czf` to archive it. Delete the original directory, then extract the archive to restore it.
> **Exercise 4:** Use `curl` or `wget` to download a file from the web. Try downloading a plain text file, like a Project Gutenberg book (e.g., `https://www.gutenberg.org/files/1342/1342-0.txt` for Pride and Prejudice). Use `wc -l` to count the lines, `head` to see the beginning, and `grep` to search for a word.

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Eric M. Furst, University of Delaware
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

41
README.md Normal file
View file

@ -0,0 +1,41 @@
# CLI Power Tools
**CHEG 667-013 — Chemical Engineering with Computers**
Department of Chemical and Biomolecular Engineering, University of Delaware
A hands-on walkthrough of the Unix command line interface. Learn how to navigate the file system, manipulate files, search and filter text, manage processes, and write shell scripts — essential skills for any engineer working with computers.
## Sections
| # | Topic | Description |
|---|-------|-------------|
| [01](01-navigation/) | **Navigation** | Open a terminal, navigate the file system, understand paths, permissions, and get help with `man`. |
| [02](02-files/) | **Files and directories** | Create, move, copy, and remove files and directories. |
| [03](03-reading-and-searching/) | **Reading and searching** | Read files with `cat`, `less`, and `grep`. Combine tools with pipes and redirects. |
| [04](04-processes-and-editors/) | **Processes and editors** | Monitor and manage processes. Edit files in the terminal. Control characters and job control. |
| [05](05-scripting/) | **Scripting** | Wildcards, shell history, and writing your first shell script. |
| [06](06-advanced/) | **Advanced tools** | Remote access with `ssh`, file transfers, downloading, finding files, and archiving. |
## Prerequisites
- A terminal (macOS/Linux, or WSL on Windows)
- No prior command line experience required
## Getting started
Clone this repository and work through each section in order:
```bash
git clone https://lem.che.udel.edu/git/furst/cli-walkthrough.git
cd cli-walkthrough
```
Each section has its own `README.md` with a full walkthrough and exercises.
## License
MIT
## Author
Eric M. Furst, University of Delaware