EECS 280 Tutorials

Command Line Interface (CLI)

This is a brief tutorial of command line interface basics.

The GUI (Graphic User Interface) is a “point and click” way to interact with a computer. The Windows File Explorer and macOS Finder are examples of GUIs.

The CLI (Command Line Interface) is a text-based way to interact with a computer. The terminal is another name for the CLI. On the Windows Subsystem for Linux (WSL) it might be called “Ubuntu”. The CLI is fast, easy to automate, and easy to use remotely.

gui vs cli

Prerequisites

If you haven’t installed CLI tools on your machine yet, follow one of these tutorials first. Linux users have CLI tools installed by default.

macOS Windows

Open Terminal (Windows)

Start an Ubuntu Bash shell.

start menu select Ubuntu WSL Ubuntu terminal

Open Terminal (macOS)

Start the Terminal application that comes with macOS.

Keywords

A file stores data like C++ source code (main.cpp) or plain text (example.txt).

A directory contains files and other directories. It’s also called a folder.

A path is the location of a file or directory. Sometimes we end a directory path with /. For example:

/Users/ohjun/Desktop/project/main.cpp
/Users/ohjun/Desktop/project/stuff/

keywords example

Basic Commands

ls

ls prints files and directories in the present working directory.

  $ ls
  example.txt main.cpp stuff
ls example

Pro-tip: Colorize the output of ls to tell files and directories apart (instructions).

colorized ls example

tree

tree recursively prints files and directories. tree is useful for comparing your files against a project spec.

$ tree
.
├── example.txt
├── main.cpp
└── stuff
    └── hello.txt

Pitfall: You may need to install tree.

$ sudo apt install tree  # WSL, Linux
$ brew install tree      # macOS

pwd

pwd prints the path of the present working directory.

  $ pwd
  /Users/ohjun/Desktop/project
pwd example

mkdir

mkdir creates a directory.

  $ mkdir myfolder
mkdir example

touch

touch creates an empty file.

  $ touch euchre.cpp
touch example

rm

rm removes (deletes) a file.

rm -rf removes a directory.

  $ rm euchre.cpp
  $ rm -rf stuff2/
rm example

Warning: Files deleted by rm are gone forever. You cannot recover them from the Trash.

cd

cd changes directory.

  $ cd stuff/
cd example

mv

mv moves a file or directory into a different directory.

  $ mv main.cpp stuff/
mv example

mv is also used to rename a file or directory.

  $ mv example.txt new_name.txt
mv rename example

cp

cp copies a file.

  $ cp new_name.txt stuff/
cp example

open / wslview

On macOS, open opens a file or directory with the default application, like a double click (docs).

On WSL (Windows), wslview opens a file or directory with the default application, like a double click (docs).

WSL Pitfall: You may need to install wslu, which includes wslview (source).

Check your Ubuntu version.

$ lsb_release -a
Description:    Ubuntu 22.04 LTS

Ubuntu 20.04 and earlier:

$ sudo apt update
$ sudo apt install ubuntu-wsl wslu

Ubuntu 22.04 and later:

$ sudo add-apt-repository ppa:wslutilities/wslu
$ sudo apt update
$ sudo apt install wslu

Tips and Tricks

clear Control + l

clear the terminal. Pro-tip: Control + l. That’s a lowercase L.

Tab complete TAB

TAB autocompletes a file or directory name.

Type the first part of a filename, then press TAB. Press again to show multiple completion options.

$ cd ~/src/e  # Press TAB twice to see options
eecs280/     eecs281/     eecs485/

Previous Command

shows previous commands.

Colorize ls output

Colorize the output of ls so it’s easy to tell the difference between files and directories.

colorized ls example

Windows/WSL and Linux (Bash shell)

Verify you’re using the Bash shell, which is typical on WSL Ubuntu Linux.

$ echo $0
-bash

Edit your shell customization file.

$ touch ~/.bash_profile  # Create file if it doesn't exist
$ wslview ~/.bash_profile

WSL Pitfall: You may need to install wslview.

Add this line. Whenever you type ls, you’ll actually get ls --color, which adds color.

alias ls='ls --color'

Close your terminal and reopen it. You should see colorized ls output.

colorized ls WSL example

macOS (Z shell)

Verify you’re using the Z shell, which is typical on macOS.

$ echo $0
zsh

Edit your shell customization file

$ touch ~/.zshrc  # Create file if it doesn't exist
$ open ~/.zshrc

Add this line. Whenever you type ls, you’ll actually get ls -G.

alias ls='ls -G'

Close your terminal and reopen it. You should see colorized ls output.

colorized ls macOS example

Customize prompt

Customize the terminal prompt to be more helpful and look prettier.

First, complete the Colorize ls output section. At this point, you should know whether you are using Bash or Z Shell, and you should have a working .bash_profile or .zshrc file.

Windows/WSL and Linux (Bash shell)

Add a line to your .bash_profile file that sets the PS1 environment variable.

export PS1='\[\e[0;32m\][\u] \[\e[0;34m\]\w/ \[\e[01;34m\]$ \[\e[0m\]'

Close your terminal and reopen it. It should look like this. For more, check out this guide.

customized bash example

macOS (Z shell)

Add a line to your .zshrc file that sets the PS1 environment variable.

PROMPT='%F{green}[%n] %F{blue}%~%f %B%F{blue}$%f%b '

Close your terminal and reopen it. It should look like this. For more, check out this guide.

customized zsh example

Special Paths

A path is the location of a file or directory.

Current directory .

. refers to the current directory.

For example, you might open the current directory in the Finder (File Explorer).

$ open .     # macOS
$ wslview .  # Windows/WSL

Parent directory ..

.. refers to the parent directory of the current directory.

$ pwd
/Users/ohjun/Desktop/project/stuff
$ cd ..
$ pwd
/Users/ohjun/Desktop/project

Home directory ~

~ refers to your home directory.

$ cd ~
$ pwd
/Users/ohjun
$ ls
Applications Pictures Desktop ...

Root directory /

/ refers to the root directory. This is the top-most directory in your file system, and has no parent.

$ ls /
Applications cores sbin ...

Absolute Path

An absolute path starts from the root directory /.

For example, sometimes it’s useful to make sure the exact file is correct.

$ /usr/local/bin/python3  # One version of Python
$ /usr/bin/python3        # Another version of Python

Relative Path

A relative path starts from the current directory.

For example, running an executable.

$ ./main.exe

Glob *

A glob is a wildcard path that may match multiple paths. The * symbol matches any string.

$ cp -v starter_files/* .
'starter-files/Makefile' -> './Makefile'
'starter-files/main_test.in' -> './main_test.in'
...

More commands

This section contains some more useful commands.

wget

wget downloads a file from the internet.

For example, download the starter files for EECS 280 project 1:

$ wget https://eecs280staff.github.io/p1-stats/starter-files.tar.gz
$ ls
starter-files.tar.gz

tar

tar unpacks an archive.

For example, unpack the starter files for EECS 280 project 1:

$ tar -xvzf starter-files.tar.gz
starter-files/
...
$ tree
.
├── starter-files
│   ├── Makefile
│   ├── main_test.in
│   ├── main_test.out.correct
│   ├── main_test_data.tsv
│   ├── p1_library.cpp
│   ├── p1_library.hpp
│   ├── stats.hpp
│   ├── stats_public_test.cpp
│   └── stats_tests.cpp.starter
└── starter-files.tar.gz

diff

diff compares two files.

Here’s an example from EECS 280 project 1 (full example). No output means the files are identical.

$ diff main_test.out main_test.out.correct

cat

cat concatenates files and prints them.

For example, you can dump the contents of a file to the terminal.

$ cat main.cpp
#include <iostream>
using namespace std;

int main() {
  cout << "hello from main!\n";
}

grep

grep searches inside a file. It’s short for “globally search for a regular expression and print matching lines”.

Search for vector in main.cpp.

$ grep vector main.cpp
#include <vector>
  vector<double> v = extract_column(filename, column_name);
  vector<vector<double> > summary = summarize(v);

Search for vector in all .cpp files. This example also uses a glob (*).

$ grep vector *.cpp
main.cpp:#include <vector>
main.cpp:  vector<double> v = extract_column(filename, column_name);
main.cpp:  vector<vector<double> > summary = summarize(v);
stats.cpp:#include <vector>
...
stats_tests.cpp:#include <vector>
...

Redirection

Redirection sends input or output to a file or another command.

Pipe |

The pipe (|) sends the output of the left command to the input of the right command.

Here’s an example that searches for .cpp files. The output of ls is piped to the input of grep.

$ ls | grep cpp
main.cpp
stats.cpp
stats_tests.cpp

Input redirection <

Input redirection sends the contents of a file to the input of a program. Input redirection is useful for automating program input.

Here’s an example program.

#include <iostream>
#include <string>
using namespace std;

int main() {
  cout << "What's your name?" << endl;
  string name;
  cin >> name;
  cout << "Hello " << name << "!\n";
}

Without input redirection, the user types input (highlighted).

$ g++ main.cpp -o main.exe
$ ./main.exe
What's your name?
Drew
Hello Drew!

Create a file with user input. We’ll call it main_test.in.

Drew

Redirect file main_test.in to stdin of main.exe. We have automated user input.

$ ./main.exe < main_test.in
What's your name?
Hello Drew!

Output redirection >

Output redirection sends the output of a program to a file. Output redirection is useful for testing program output.

We will use the example program from the input redirection section.

Create a file with correct output. We’ll call it main_test.out.correct. EECS 280 projects typically provided a few correct output files.

What's your name?
Hello Drew!

Run main.exe, redirecting input and output.

$ ./main.exe < main_test.in > main_test.out

Compare the saved (redirected) output to the correct output using diff. No output means the files are identical.

$ diff main_test.out main_test.out.correct

Shell scripting

A shell script is a file that contains commands. Shell scripts are useful for automating things like running test cases. Learn more at the EECS 485 Shell Scripting Tutorial.

Acknowledgments

Original document written by Andrew DeOrio awdeorio@umich.edu and Oh Jun Kweon ohjun@umich.edu.

This document is licensed under a Creative Commons Attribution-NonCommercial 4.0 License. You’re free to copy and share this document, but not to sell it. You may not share source code provided with this document.