Skip to content

Development Environment

The first step in our journey to programming proficiency is to set up the tools you need to write, compile, run, and manage (C++) programs/code. This collection of tools is called a Development Environment.

For this course, our development environment consists of:

  1. A Terminal: To interact with the computer using text commands.
  2. ssh: a program to connect to the ENGR servers at OSU.
  3. vim: a text editor to write your code.
  4. git: a version control system to manage your code (we’ll cover this in the Git lecture).
  5. g++: a compiler to turn your C++ code into a running program (we’ll cover this in the C++ Basics lecture).

Don’t worry if these terms are new to you. We will walk through each one step-by-step.

A terminal is a program that lets us interface with our computer via textual commands that get interpreted by another internal program called a shell. All of the software we write in this class will be text-based.

That means that our programs will not create windows or tabs with graphical user interfaces. Instead, we will run our programs by issuing textual commands in a terminal, and they will output responses through text in the terminal as well. Indeed, it’s difficult to write, build, and run basic software without some sort of terminal.

Luckily, all modern operating systems come with one or more terminals installed. Follow the instructions below based on your operating system to become acquainted with your terminal.

Windows actually offers a few terminals / shells. The oldest one is the Command shell (CMD). Most people consider it to be obsolete, so I don’t recommend using it. The Command shell was superseded by Powershell—lots of people use this one.

To access Powershell, simply search for “Powershell” in the Windows start menu. When you start it, a window should appear with a text cursor. You can now begin issuing textual commands to your computer by typing them and pressing enter. We’ll learn about some commands shortly.

When you open Powershell for the first time, it will default to a certain configuration that most people don’t like, so you may want to do some reconfiguration. If you right click on the window’s menu bar (the top of the window) and click “Properties”, you can configure your terminal to your liking (e.g., background colors, font colors, font sizes, etc).

Mac comes with a terminal by default. It’s simply called “Terminal”, and you can find it by typing “Terminal” into the Mac Spotlight search (the magnifying glass at the top-right corner of your screen). When you open your Mac Terminal for the first time, it will default to a certain configuration that most people don’t like, so you may want to do some reconfiguration. In the menu bar, navigate to Terminal → Preferences, then navigate to the Profiles tab. From here, you can add new terminal profiles and modify existing ones. A profile is basically just a configuration of terminal settings. For most cases, it’s sufficient to just modify the default profile (e.g., “Basic”). You can change default font sizes, colors, etc.

If you’re running a UNIX/Linux OS other than macOS (e.g., Ubuntu, FreeBSD, etc), then you probably already know what a terminal is. Most *nix terminals are extremely similar since the default shell is configured at a user level, so use whatever terminal you want.

A terminal is similar to file explorers like Windows File Explorer or Mac Finder, but entirely text-based. By typing commands into the terminal and pressing Enter, you can navigate the file system, view, edit, and even execute files (if they’re executable). While a terminal can perform everything a graphical file explorer can, it also offers functionality that file explorers can’t. This makes terminals indispensable for tasks requiring fine-grained control over your computer, such as software development.

In this course, we’ll be working a bit differently. Instead of using the terminal to control your own computer, you’ll primarily use it to interact with a remote computer. Specifically, we’ll be using powerful machines located in the Kelley Engineering Center’s server room at Oregon State University (OSU). These are referred to as the ENGR servers.

The ENGR servers don’t have physical monitors, mice, or keyboards attached, and access to the server room is restricted to authorized faculty and staff. So, how will we use these servers?

To control the ENGR servers, you’ll use a remote connection via your computer’s terminal. By issuing a single command, your computer will connect to the ENGR servers over the internet, giving you access to a remote shell. This allows you to type commands into your local terminal to control the ENGR servers, as if you were using them directly.

Accessing the ENGR servers requires authentication. If you don’t already have an ENGR account, you’ll need to create one:

  1. Visit the CoE TEACH website.
  2. Click “Create a new account”
  3. Follow the on-screen instructions to create your ENGR account.

Once your account is created and you have internet access, you’ll be ready to connect to and work on the ENGR servers.

To do this, type the following command into your terminal and press enter, substituting <ONID> with your ONID username (e.g., mine is ulbrical):

SSH Command to Access ENGR Servers
ssh <ONID>@access.engr.oregonstate.edu

ssh stands for Secure Shell, a cryptographic network protocol that allows you to securely connect to and control a remote computer. It uses predefined user accounts and permissions to authenticate and manage access.

When you connect to the ENGR servers using ssh, your terminal will prompt you for a password. If this doesn’t happen, it may indicate an issue with your internet connection or that the ENGR servers are temporarily unavailable.

  1. Type your ONID password (the same one you use for OSU services like Canvas and Outlook) and press Enter. Your password will not appear as you type—it’s invisible for security reasons. This is expected.
  2. After entering your password, you’ll be prompted to verify your login using Duo.
    • If you have multiple Duo devices, the terminal will ask you to select which device to use. Type the corresponding number and press Enter.
    • Approve the Duo push notification on your device.

Once authenticated, you should see a screen indicating that you are now logged into the ENGR servers.

ulbrical@flip4:~
===================================================================
You Are Accessing an Oregon State University System
Unauthorized Access Prohibited
Use Constitutes a Consent to Monitoring
Users have No Expectation of Privacy
===================================================================
(ulbrical@access.engr.oregonstate.edu) Password:
(ulbrical@access.engr.oregonstate.edu) Duo two-factor login for ulbrical
Enter a passcode or select one of the following options:
1. Duo Push to XXX-XXX-2321
Passcode or option (1-1): 1
Success. Logging you in...
Success. Logging you in...
===================================================================
Beginning Friday 12 July 2019 at 500pm, two-factor Duo authentication will be required on the following College of Engineering linux SSH servers:
access.engr.oregonstate.edu
flip.engr.oregonstate.edu
nome.eecs.oregonstate.edu
Students can sign up for two-factor Duo at:
https://beav.es/duo
-------------------------------------------------------------------
If you have any problems with this machine, please mail support@engr.orst.edu
===================================================================
Last login: Wed Dec 6 14:13:38 2023 from 10.197.135.26
flip4 ~ 49$

The ENGR servers run Linux, so any commands you type into the terminal will now be interpreted as Linux shell commands. You can customize your shell settings on the TEACH platform if needed, but the default configuration will work fine for this course.

Now that you’re logged in, your terminal is controlling the ENGR servers, not your personal computer. This means:

  • File Operations Are Remote: Any files you create, edit, or manage will exist on the ENGR servers and not on your local computer. These files will not appear in tools like Windows File Explorer or Mac Finder unless you transfer them.
  • Transferring Files: To move files between your local computer and the ENGR servers, you’ll need to use a file transfer protocol such as SFTP (Secure File Transfer Protocol) or SCP (Secure Copy Protocol). If you’re interested, you can look up tutorials for these tools.

The prompt is essentially a marker for where you can type commands. It appears every time the shell is ready to accept input. A simple example of a default prompt might look like this:

Simple Shell Prompt
user@hostname:~$

The prompt typically provides useful contextual information. Here’s a breakdown of common elements.

  • Username (user): indicates the user currently logged into the system.
  • Hostname (hostname): shows the name of the computer or server you’re connected to, it’s helpful in identifying the machine when working on multiple systems.
  • Current Working Directory: shows the directory you’re currently in, ~ means it’s your /home directory, but it can be specific, e.g. /var/log.
  • Shell Account Type: $ means you’re’ a normal user, while # indicates elevated permissions (superuser/root).
  • Tab Completion
  • Command History
  • Aliases

Now that our terminal is connected to the ENGR servers, we should learn how to use it. To summarize, here is a table briefly describing some important Linux shell commands:

CommandDescription
ssh <connection_string>Connects to the SSH server specified by the connection string. You already used this command locally (from your computer) to connect to the ENGR servers.
pwdPrints the working directory.
ls <path>Lists the files and directories within directory located at the specified path. Lists the files and directories within the working directory if <path> is omitted.
mkdir <path>Creates a new directory at the specified path.
cd <path>Navigates to the directory at the specified path, making it the new working directory. Navigates one level up in the directory tree if <path> is omitted or is ...
clearClears the text on-screen in the terminal.
cp <path1> <path2>Copies the file located at the specified <path1> to the location specified by <path2>. cp -r <path1> <path2> can be used to copy an entire directory and all of its contents.
mv <path1> <path2>Moves the file or directory located at the specified <path1> to the location specified by <path2>. This can also be used to rename files/directories. If the specified <path2> already exists and is itself a directory, this will move the file/directory located at the specified <path1> into the directory located at the specified <path2>.
rm <path>Removes (deletes) the file located at the specified path. To remove an entire non-empty directory, use rm -r <path>. To remove an empty directory, you can also use rmdir <path>.
cat <path1> <path2> ... <pathN>Concatenates the contents of the files at all of the specified paths in the order provided and prints the concatenated content to the terminal. Note that this is also used for just printing the contents of a single file.
vim <path>Opens the file at the specified path in the vim text editor (see next section).
Basic Command Structure
command [options] [arguments]

The name of the program or script or utility that you want to execute.

Example: ls the command to list directory contents.

Options modify the behavior of the command. They are usually optional.

They often start with a - (single dash) for short options or -- (double dash) for long options.

Example: ls -l --color, where -l enables long-format listing and --color highlights file types and permissions with colors (default is always).

You can also combine short options such as ls -lsh, where -s prints the allocated size of each file, in blocks, and -h makes things human-readable (when combined with -s).

Inputs to the command, such as file names, directories, or specific data to operate on.

Example:

Cat Command Example
cat myfile.txt

where myfile.txt is the argument to the cat command, which concatenates file(s) to the standard output.

Commands can accept multiple arguments:

Copy Command Example
cp file1.txt file2.txt destination/

where file1.txt and file2.txt are source files, and destination/ is the target directory.

Options and arguments can be combined in various ways, depending on the command syntax.

Tar Command Example
tar -czf archive.tar.gz file1 file2

where -czf is a combination of options for creating (c), compressing (z), and specifying a file (f), archive.tar.gz is the argument specifying the output file, and file1 and file2 are the files to archive.

A terminal can be thought of as a text-based version of a file explorer. At any given time, your terminal (or shell) operates within a specific folder, referred to as a directory. The directory you are currently working in is called the working directory.

To see your current working directory, use the following command:

Print Working Directory
pwd

pwd stands for “print working directory,” which means it will display your current directory in the terminal. For example:

Print Working Directory Example Output
/nfs/stak/users/ulbrical

After logging into the ENGR servers, your working directory will default to your home directory. This directory is specific to your account, and its path will include your ONID username.

To view the files and directories within your working directory, use:

List Directory Contents
ls

ls stands for “list.” Its output might include color-coded items.

A path specifies the location of a file or directory. Paths use a path separator (/ on Linux systems) to separate directories. For example:

Path Example
A/B/C.jpg

This path represents a file C.jpg inside directory B, which is inside directory A.

We distinguish between two types of paths:

  • Absolute Paths: Start from the root directory (/) and specify the full path to a file or directory. For example:
Absolute Path Example
/nfs/stak/users/<ONID>/A/B/C.jpg
  • Relative Paths: Start from the current working directory and specify the path relative to it. For example:
Relative Path Example
A/B/C.jpg

We also have some special path shortcuts:

  • . refers to the current directory.
  • .. refers to the parent directory.
  • ~ represents your home directory. For example, ~/A is equivalent to /nfs/stak/users/<ONID>/A.

To create a new directory, use:

Make Directory Command
mkdir <path>

For example

Make Directory Example
mkdir A

This creates a directory named A in the current working directory. If you want to create a directory along with its parent directories, use the -p flag:

Make Parent Directories Example
mkdir -p A/B/C

This command creates A, B, and C if they don’t already exist.

To move to a different directory, use:

Change Directory Command
cd <path>

For example:

Change Directory Example
cd A

This sets your working directory to A. You can return to your home directory by running either of the following:

Change to Parent Directory
cd
cd ..

To clean up your terminal screen, use:

Clear Terminal Command
clear

This command behaves differently depending on the terminal:

  • Some terminals scroll down to clear the screen.
  • Others erase the entire presentation buffer, preventing you from scrolling back up.

Experiment with your terminal to understand how it behaves.

To copy a file, use:

Copy Command
cp <source_path> <destination_path>

For example:

Copy File Example
cp file1.txt file2.txt

This copies file1.txt to file2.txt. To copy an entire directory, add the -r flag (recursive):

Copy Directory Example
cp -r dir1 dir2

To move a file or directory, use:

Move Command
mv <source_path> <destination_path>

For example:

Move File Example
mv file1.txt dir1/

This moves file1.txt into dir1/. You can also use mv to rename files:

Rename File Example
mv old_name.txt new_name.txt

This renames the file from old_name.txt to new_name.txt.

To delete a file, use:

Remove Command
rm <path>

For example:

Remove File Example
rm file1.txt

To remove a directory and all its contents, use the -r flag:

Remove Directory and its Contents Example
rm -r dir1

Most shell commands require a path as an argument. For example, to list the contents of a specific directory, use:

List Directory Contents at Specific Path
ls <path>

This command displays the contents of the directory at <path>. Similarly, paths are used with commands like cp, mv, and rm to specify files or directories to operate on.

By mastering these basic commands, you can effectively navigate and manage files within the terminal:

  • Use pwd, ls, and cd to explore directories.
  • Use mkdir, cp, mv, and rm to create, copy, move, or delete files and directories.
  • Understand the difference between relative and absolute paths to work efficiently in the terminal.

In the previous section, we covered essential file and directory management commands to help you navigate and manipulate your system. Now, let’s explore more advanced terminal concepts that enhance the power and flexibility of the command line: pipes, redirection, subcommands, environment variables, and command order and logic.

These concepts allow you to chain commands, manage output and input efficiently, and work with complex logic in the shell.

This section is not necessary for completing assignments in this course, but understanding these concepts will significantly enhance your command-line proficiency and enable you to perform more complex tasks with ease.

A pipe connects the output of one command directly to the input of another, enabling you to chain commands together to perform complex tasks efficiently. The pipe operator (|) makes it easy to process data without creating intermediate files.

Example:

Pipe Example
ls | grep "example"
  • ls lists the files in the directory.
  • grep "example" filters the output, showing only files or directories that contain “example” in their name.

Pipes are powerful for combining commands to handle streams of text, like filtering log files, processing data, or chaining utilities.

Redirection allows you to control where a command’s output goes or where it takes input from. This is particularly useful for saving output to files or providing input to commands.

  • Output Redirection (>) redirects the output of a command to a file, overwriting the file if it exists.
Output Redirection Example: Overwrites File
echo "Hello, World!" > output.txt
  • Append Output (>>) appends the output of a command to a file without overwriting it.
Output Redirection Example: Appends to File
echo "Another line" >> output.txt
  • Input Redirection (<) redirects a file as input to a command.
Input Redirection Example
wc -l < input.txt

Here, the wc -l command counts the lines in input.txt.

Redirection enables you to store results, feed data into commands, or even create complex workflows with minimal effort.

Environment variables are dynamic values stored in the shell’s environment that can influence how commands and programs operate. They’re often used to store system-wide configurations or user-specific settings.

Common Environment Variables:

  • PATH: Directories where the shell looks for executable files.
  • HOME: The current user’s home directory.
  • USER: The name of the current user.
Environment Variable Example
echo $HOME

This command prints the value of the HOME environment variable, which should return something like /nfs/stak/users/<ONID> on the ENGR servers.

You can also define your own variables:

Defining Environment Variable Example
MY_VAR="Hello, World!"
echo $MY_VAR

Environment variables are invaluable for customizing your shell, managing system settings, and scripting.

The shell allows you to execute commands in specific orders and combine them using logical operators for advanced control. This lets you define conditions for when commands should run.

  • && executes the next command only if the previous command succeeds.
Logical AND Example
mkdir new_dir && cd new_dir
  • || executes the next command only if the previous command fails.
Logical OR Example
cd nonexistent_dir || echo "Directory not found"
  • ; executes commands sequentially, regardless of success or failure.
Sequential Execution Example
echo "First" ; echo "Second"

These operators provide fine-grained control over the flow of commands, enabling you to automate and script tasks with precision.

A subshell is a separate child process created by the shell to execute commands. It inherits the environment of the parent shell but operates independently. When a subshell runs a command or a group of commands, changes made in the subshell (like variable assignments or directory changes) do not affect the parent shell.

Subshell Example
(cd /tmp && ls)
  • ( ... ) runs the enclosed commands in a subshell.
  • Here, the subshell changes to /tmp and lists its contents.
  • The parent shell remains in its original directory after the subshell completes.

Command substitution is a way to capture the output of a command and use it in another command. This is achieved using the $() syntax, making it a crucial tool for dynamic command generation and scripting. When using $(), the shell spawns a subshell to execute the command inside the $() and replaces the substitution with the command’s output.

Command Substitution Example
echo "Today is $(date)"

By now, you should have a solid understanding of how to navigate a file system in the terminal. The next step is learning how to create and edit text-based files directly in the terminal. To do this, we’ll use a terminal-based text editor—a program that runs within the terminal instead of a separate window (like Notepad or Microsoft Word). On the ENGR servers, you have access to editors like vim, nano, and emacs. For this course, we’ll focus on vim.

To open a file in vim, use the following command:

Open File in vim Command
vim <path>

This opens the file at the specified path. If the file doesn’t exist, vim will create it. For instance, to create a file named hello.txt in your current directory, you would run:

Create and Open hello.txt in vim
vim hello.txt

Vim is similar to editors like Notepad or Word, but it’s entirely terminal-based, so there are no visible menu buttons. For example, after opening hello.txt, your terminal might look something like this:

vim hello.txt
~
~
~
~
~
"hello.txt" [New File] 0,0-1 All

Your screen might differ slightly (e.g., it might not show line numbers), but the general interface will be similar. Note that any menu-like elements belong to your terminal, not vim itself. Actions like saving, quitting, and copying text in vim are done via text-based commands.

Vim operates in several modes, and understanding these is key to using it effectively. By default, vim starts in normal mode, which is used for issuing commands (e.g., saving a file, quitting vim, copying, pasting). If you want to write text into a file, you need to switch to insert mode:

  • Press the i key to switch to insert mode.
  • You can now start typing into the file. For example, write the text Hello, world! into hello.txt:
vim insert mode
Hello, World!█
~
~
~
~
~
-- INSERT -- 1,14 All

Saving a file and quitting vim requires issuing commands in normal mode. Since you cannot issue commands in insert mode, you must first switch back to normal mode:

  1. Press the Esc key to exit insert mode and return to normal mode.
  2. To issue a command, type a colon :. The colon will appear at the bottom-left of the screen.
  3. Follow the colon with the desired vim command.
CommandDescription
wWrite (save) the file
qQuit vim (without saving)
wqWrite (save) the file and quit
set mouse=aEnable the mouse in vim (it’s disabled by default)
set nuDisplay line numbers
syntax onEnable syntax highlighting (usually enabled by default, but may need to be enabled in certain circumstances)
colorscheme <colorscheme>Set the syntax highlighting colorscheme. Writing :colorscheme and pressing tab should cycle you through the available options.

To save and quit the file, use the :wq command:

vim save and quit
Hello, World!
~
~
~
~
~
:wq█

After pressing Enter, you’ll return to your regular SSH session.

You can customize vim by creating a file named .vimrc in your home directory. Open it in vim:

Open .vimrc in vim
vim ~/.vimrc

Add vim commands (without colons) to configure default settings. For instance:

  • Enable line numbers.
  • Allow mouse usage.

Each command should go on its own line.

.vimrc
1 set mouse=A
2 set nu█
~
~
~
~
~
"~/.vimrc" 2L, 19B 2,7 All

To confirm that a file was saved, run the following command in the correct directory:

List Directory Contents Command
ls

This will show hello.txt in your working directory.

To show hidden files (like .vimrc), use the -a flag:

List All Files Command
ls -a ~

You can use the cat command to view the contents of a file. Originally designed to concatenate files, cat also works for a single file, printing its contents to the terminal. For example:

Cat Command Example
cat hello.txt

This will display the text you wrote in hello.txt. If you want to view the contents of a file without opening it in an editor, cat is a quick and easy way to do so.

The cat command can also concatenate multiple files. For example:

Concatenate Multiple Files Command
cat file1.txt file2.txt file3.txt

This will combine the contents of file1.txt, file2.txt, and file3.txt in order, displaying the result in the terminal.

By following these steps, you’ve learned how to create, edit, save, and view text-based files directly in the terminal. With vim and cat, you’re equipped to efficiently manage text files on the ENGR servers.

Integrated Development Environments (IDEs)

Section titled “Integrated Development Environments (IDEs)”

While this course focuses on using terminal-based tools like vim for text editing and g++ for compiling C++ code, you might find it beneficial to use an Integrated Development Environment (IDE) for a more user-friendly experience. IDEs provide a graphical interface that combines code editing, building, and debugging features in one application.

Many modern IDEs can streamline your workflow by integrating the tools we’ve discussed:

  • Integrated Terminal: You can open a terminal directly inside the IDE to run commands.
  • Remote Development: Some IDEs (like VS Code) allow you to connect to the ENGR servers via SSH, letting you edit remote files using the IDE’s interface.
  • Version Control: Built-in Git support allows you to stage, commit, and push changes without leaving the editor.
  • Intelligent Code Completion: Features like IntelliSense help you write code faster and with fewer errors.

Some popular IDEs for C++ development include:

  • Visual Studio Code: A lightweight, extensible code editor. It is highly recommended if you want to try an IDE, especially for its Remote - SSH extension which works seamlessly with the ENGR servers.
  • CLion: A powerful, full-featured C++ IDE by JetBrains.
  • Zed: A high-performance, multiplayer code editor.
  • Eclipse CDT: A classic open-source IDE.