The Shell

 

Using the shell

When you log into remote Eos, you will see a welcome screen that looks similar to this with a prompt:

*-----------------------------------------------------------------------------*
|                                     |    @@@@@@@     @@@@@@@     @@@@@@@@   |
|                                     |   @@@   @@@   @@@   @@@   @@@         |
|   North Carolina State University   |   @@@   @@@   @@@   @@@   @@@         |
|            College of Engineering   |   @@@@@@@@    @@@   @@@    @@@@@@@    |
|         Eos Computing Environment   |   @@@         @@@   @@@         @@@   |
|                                     |   @@@         @@@   @@@         @@@   |
|                                     |    @@@@@@@@    @@@@@@@    @@@@@@@@    |
*-----------------------------------------------------------------------------*
|                                                                             |
| You have logged in to NCSU College of Engineering remote access servers,    |
| which provide computing resources to faculty and students working remotely. |
|                                                                             |
| If you need assistance, please contact eoshelp@ncsu.edu.                    |
*-----------------------------------------------------------------------------*
Last login: Tue May  6 08:38:30 2025 from 136.47.231.18
type "man eos" (without quotes) for information on software installed
Filesystem                      Size  Used Avail Use% Mounted on
dc2isi00nfs.oit.ncsu.edu:/home   20G  2.7G   18G  14% /mnt/ncsudrive
[ahaque3@engr-ras-207 ~]$
 

This is the main textual interface to the shell. It tells you that you are on the machine engr-ras-207 and that your “current working directory”, or where you currently are, is ~ (short for “home”). The $ tells you that you are not the root user (more on that later). At this prompt you can type a command, which will then be interpreted by the shell. The most basic command is to execute a program:

[ahaque3@engr-ras-207 ~]$ date

Tue May  6 13:23:00 EDT 2025

Here, we executed the date program, which (perhaps unsurprisingly) prints the current date and time. The shell then asks us for another command to execute. We can also execute a command with arguments:

[ahaque3@engr-ras-207 ~]$ echo hello

hello

In this case, we told the shell to execute the program echo with the argument hello. The echo program simply prints out its arguments. The shell parses the command by splitting it by whitespace, and then runs the program indicated by the first word, supplying each subsequent word as an argument that the program can access. If you want to provide an argument that contains spaces or other special characters (e.g., a directory named “My Photos”), you can either quote the argument with ‘ or ” (“My Photos”), or escape just the relevant characters with \ (My\ Photos). Better yet is to use camel case or snake case to differentiate between words (look it up if you’re interested!)

But how does the shell know how to find the date or echo programs? Well, the shell is a programming environment, just like Python or Ruby, and so it has variables, conditionals, loops, and functions. When you run commands in your shell, you are really writing a small bit of code that your shell interprets. If the shell is asked to execute a command that doesn’t match one of its programming keywords, it consults an environment variable called $PATH that lists which directories the shell should search for programs when it is given a command:

[ahaque3@engr-ras-207 ~]$ echo $PATH

/mnt/ncsudrive/a/ahaque3/.cargo/bin:/mnt/ncsudrive/a/ahaque3/.local/bin:/mnt/ncsudrive/a/ahaque3/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/mnt/ncsudrive/a/ahaque3/.dotnet/tools:/opt/puppetlabs/bin

When we run the echo command, the shell sees that it should execute the program echo, and then searches through the :-separated list of directories in $PATH for a file by that name. When it finds it, it runs it (assuming the file is executable; more on that later).

Navigating in the shell

A path on the shell is a delimited list of directories; separated by / on Linux and macOS and \ on Windows. On Linux and macOS, the path / is the “root” of the file system, under which all directories and files lie, whereas on Windows there is one root for each disk partition (e.g., C:\). This class assumes that you are using a Linux filesystem in this class, usually remote Eos. A path that starts with / is called an absolute path. Any other path is a relative path. Relative paths are relative to the current working directory, which we can see with the pwd command and change with the cd command. In a path, . refers to the current directory, and .. to its parent directory:

[ahaque3@engr-ras-207 ~]$ pwd

/mnt/ncsudrive/a/ahaque3

[ahaque3@engr-ras-207 ~]$ cd AlicePractice/

[ahaque3@engr-ras-207 AlicePractice]$ pwd

/mnt/ncsudrive/a/ahaque3/AlicePractice

[ahaque3@engr-ras-207 AlicePractice]$ ls

file1.txt

[ahaque3@engr-ras-207 AlicePractice]$ cd ..

[ahaque3@engr-ras-207 ~]$ pwd

/mnt/ncsudrive/a/ahaque3

Notice that my shell prompt kept us informed about what my current working directory was. Note that I have a directory called AlicePractice that I could move into, and then use .. to move back up.

In general, when we run a program, it will operate in the current directory unless we tell it otherwise. For example, it will usually search for files there, and create new files there if it needs to. To see what lives in a given directory, we use the ls command:

[ahaque3@engr-ras-207 AlicePractice]$ ls

file1.txt


Unless a directory is given as its first argument, ls will print the contents of the current directory. I am currently in my AlicePractice directory, which has one file named file1.txt in it. Most commands accept flags and options (flags with values) that start with – to modify their behavior. Usually, running a program with the -h or –help flag will print some help text that tells you what flags and options are available. For example, ls --help tells us:

  -l                         use a long listing format

[ahaque3@engr-ras-207 AlicePractice]$ ls -l

total 24

-rwxrwx---+ 1 ahaque3 NCSU 0 Oct 10  2024 file1.txt

 

This gives us a bunch more information about each file or directory present. Follow three groups of three characters (rwx). These indicate what permissions the owner of the file, the owning group, and everyone else respectively have on the relevant item. A   indicates that the given principal does not have the given permission. Above, only the owner is allowed to modify (w) the missing directory (i.e., add/remove files in it). To enter a directory, a user must have “search” (represented by “execute”: x) permissions on that directory (and its parents). To list its contents, a user must have read (r) permissions on that directory. For files, the permissions are as you would expect. Some other handy programs to know about at this point are mv (to rename/move a file), cp (to copy a file), and mkdir (to make a new directory).

If you ever want more information about a program’s arguments, inputs, outputs, or how it works in general, give the man program a try. It takes as an argument the name of a program, and shows you its manual page. Press q to exit.

[ahaque3@engr-ras-207 AlicePractice]$ man ls

Connecting Programs

In the shell, programs have two primary “streams” associated with them: their input stream and their output stream. When the program tries to read input, it reads from the input stream, and when it prints something, it prints to its output stream. Normally, a program’s input and output are both your terminal. That is, your keyboard as input and your screen as output. However, we can also rewire those streams!

The simplest form of redirection is < file and > file. These let you rewire the input and output streams of a program to a file respectively:

[ahaque3@engr-ras-207 AlicePractice]$ echo hello > hello.txt

[ahaque3@engr-ras-207 AlicePractice]$ cat hello.txt 

hello

[ahaque3@engr-ras-207 AlicePractice]$ cat < hello.txt

hello

[ahaque3@engr-ras-207 AlicePractice]$ cat < hello.txt > hello2.txt

[ahaque3@engr-ras-207 AlicePractice]$ cat hello2.txt 

hello

Demonstrated in the example above, cat is a program that concatenates files. When given file names as arguments, it prints the contents of each of the files in sequence to its output stream. But when cat is not given any arguments, it prints contents from its input stream to its output stream (like in the third example above).

You can also use >> to append to a file. Where this kind of input/output redirection really shines is in the use of pipes. The | operator lets you “chain” programs such that the output of one is the input of another:

[ahaque3@engr-ras-207 AlicePractice]$ ls -l ~ | tail -n1

drwxrwx---+  2 ahaque3 NCSU      0 Jan 10  2023 Videos


 

Next steps

We want you to know your way around a shell enough to accomplish basic tasks. You should be able to navigate around to find files of interest and use the basic functionality of most programs. We have more chapters in this text that expand upon the commands we explained here, with more examples.

We will also explain how to perform and automate more complex tasks using the shell and the many handy command-line programs out there.

Exercises

The exercises following either give you a specific task to do, or are open-ended, like “try using X and Y programs”. We encourage you to try them out.

We have not written solutions for the exercises. If you are stuck on anything in particular, message the teaching staff, describing what you’ve tried so far, and we will try to help you out.

  1. Log onto remote Eos, or use your terminal locally. For local terminal, if you are on Linux or macOS, you don’t have to do anything special:  just open the terminal. If you are on Windows, you need to make sure you are not running cmd.exe or PowerShell; you can use Windows Subsystem for Linux or a Linux virtual machine to use Unix-style command-line tools (for Windows user, remote Eos with PuTTY or PowerShell may be easiest). To make sure you’re running an appropriate shell, you can try the command echo $SHELL. If it says something like /bin/bash or /usr/bin/zsh, that means you’re running the right program.
  1. Create a new directory called books under ~.
  2. Look up the touch program. The man program is your friend.
  3. Use touch to create a new file called dracula.
  4. Try to execute the file, i.e. type the path to the script (./dracula) into your shell and press enter. Does it work? Consult the output of ls to see why it would/wouldn’t work. (hint: look at the permission bits of the file).
  5. Look up the chmod program (e.g. use man chmod).
  6. Use chmod to make it possible to run the command ./dracula. How does your shell know that the file is supposed to be interpreted using sh? See this page on the shebang line for more information.
  7. Use | and > to write the “last modified” date output by semester into a file called last-modified.txt in your home directory.

 

Page modifies information from The Missing Semester of Your CS Education (https://missing.csail.mit.edu/). Copied freely thanks to the license: CC BY-NC-SA.