Getting Started With The Command Line (Unix/MacOS/Windows)
Getting started using the command line is a daunting task. It’s an empty black box where you have to know what you’re doing to use it at all. There is no fumbling your way through, as you must specify exactly what you mean. There is no hovering over icons like in Word or Photoshop equivalent, it’s all text input.
That being said, most people don’t need to understand more than the basics to start navigating around the terminal and getting done what is needed. I’m not sure of your use-case for learning the command line, whether it’s of interest, for a class, to execute one line someone gave you, or to use a tool that doesn’t have a GUI (Graphical User Interface, or a visual window that is interactable via mouse). Regardless, this guide should get you started. The command line is a versatile tool. If you’re a game developer for instance, you may be looking to create an automated build pipeline for your game. The command prompt is essential to completing a task like this, and this is just one example of how you could use command line in game development. Personally, I am always using the command line to run git, starting up programs, and running custom created batch or bash scripts. So, without further adieu let’s get started!
Preface
One thing I’d like to preface is that the Windows command prompt, and the Unix/Mac OS terminal operate a little differently. Some commands are the same, however the vast majority are different. Both are powerful, however, it is commonly accepted that the Unix/Mac OSX style terminal is easier to use, and more powerful. I will be covering generics of a terminal, regardless of OS, but also covering these two styles of terminal separately, as they require such attention.
What Is The Command Line?
The command line, command prompt, shell, or terminal (all names for basically the same thing), allows you to interact with your computer, and programs installed on it via text. Just like how you interact with your computer via mouse, the command prompt has a text version of most things you can do with your mouse. What’s the benefit then? Not all functionality is exposed through a GUI. Some functionality is never exposed through GUI. That’s for a number of reasons, such as the fact that GUIs take considerable development work, and GUIs are supposed to be user friendly. This means that some, lesser used, or more complicated functionality may wish to be hidden from the user. Other benefits to the command line include the fact that someone has to build a GUI, and that GUI in it of itself may have bugs and issues that are unrelated to the underlying functionality of the function you are trying to perform. Command prompts also are fast because you can access anything through one window, no searching for a settings window, finding the right sub-window, navigating to a tab, finding the option, and changing it.
In a terminal, not only do you have access to most things you can do with a GUI, there are many operations that simply would be a huge undertaking in another application. For example, using one line, you can output the contents of all the files within a specific folder, then get only the lines that start with a ‘#’ symbol, strip the ‘#’ symbols and then swap all the characters to uppercase, and put the result in a new file. This is incredibly simple to do with command line tools, at least in UNIX, this could be achieved via:
cat ./data/* | grep -E "^#" | sed 's/#//g' | tr '[:lower:]' '[:upper:]' > output.txt
The above command requires knowledge of many tools, such as “cat”, “grep”, “sed”, “tr” as well as command line tools like piping, directory structure, and basic regex. But once you have these skills, typing this out is so fast compared to trying to figure this out via some other method. Given the following files and contents:
data/fileData1.txt
#Start
Hello
#What's up
I # am # loving # this
data/fileData2.txt
popcorn style!
#this is file 2
data/fileData3.txt
File 3
#this is File 3
The above command outputs the following text:
START
WHAT'S UP
THIS IS FILE 2
THIS IS FILE 3
This example may seem really irrelevant, who would ever need to do something like this? However, it’s operations like this that I use all the time in my job. Whether I’m searching log files, creating monitoring tools, or scripts to perform advanced actions, I am constantly utilizing commands such as these in my command line interface.
Getting Started With the Command Line
When you first launch the command line, you will be greeted with something like this, on Unix.
On Windows it will look similar. On Windows you can boot the command prompt in either “regular mode” or “administrator mode.” When you search for “command prompt” in the start menu, you can right-click on the icon, and select “Launch as administrator,” and then give the proper permissions. It should then look like this:
In both cases, the system ends with the current file path, and then a ‘$’ on Ubuntu, or a ‘>’ on Windows. Knowing what file paths are on a command prompt is critical, and if you’ve never used a command prompt before, you may not know what a file path is.
What is a file path?
Every file and folder on your computer has a path to get there. When you go onto your internet browser and download a program, it most likely goes to your “Downloads” folder. When you open your “Downloads” folder in your “File Explorer” on windows, or “Files” in Ubuntu, it should look like this:
The address bar at the top is the “path” to get to this “directory” (directory is another word for folder). If you click on this address bar, you can select the path as text.
You’ll notice that it becomes text, where names of folders are separated by ‘/’ characters or ‘\’ characters on Windows.
Looking back at our Ubuntu terminal, we can see that our current path is simply “~“. Well, this doesn’t look right does it? That’s because “~” is a special character that is equal to “/home/{user}”. So really, “/home/mccole/Downloads/” is the same as “~/Downloads”.
The Windows Administrator command prompt doesn’t put you at your user’s home address. They put you somewhere in the Windows system files, as you can see there “C:\WINDOWS\system32”. This means, the hard-drive we are on is “C” and on the “C” drive, we are in the “WINDOWS” folder, and then inside that folder, we are in the “system32” folder.
It’s worth noting that many system folders on both Windows and Linux are hidden in the File Explorer views and you need to turn on special features to see these “hidden” folders and files.
When operating in the terminal, everything you do is relative to where you are currently in your file path. If you want to open a file, you have to be in the folder, or supply the whole path to that folder from where you are now, or specify the entire filepath (from the first folder on your system “/” on Linux, or “C:” in Windows, or whatever the base directory letter is on your system).
Basic Terminal Navigation and Operations
Because our terminal commands operate based on what our current file path is, let’s navigate to our “Downloads” folder that we highlighted from earlier. Copy this path from your file explorer, and paste it into your terminal. You should get some kind of output like “{PathCoppiedFromFileExplorer} Is a directory”. And nothing else happens. To actually move ourselves to the downloads folder, we have to type in a special command cd. cd stands for “change directory”, so in essence, we say “change directory”. And then we specify what directory we want to change to. In this instance, you want to change to the filepath that you copied, so paste that into the terminal after cd. NOTE: commands should always have a space after them.
cd /home/mccole/Downloads
Please note! If your path has any spaces in it at all, such as if my username was “chris mccole” you would have to wrap your file path in quotes. This is why it is generally advised that you NEVER put space characters “ “ inside of folder names, or file names. The more standard convention is lowerCammelCase, or underline_delimited, or even hyphenated-delimited. An example with spaces would be like the following:
cd "/home/chris mccole/Downloads"
Now, after you run this command, you should see your copied path before the “$’ or “>” symbol on your terminal. From here, we can double-check what our current directory is with the pwd command on Linux or cd with no parameters on Windows, and it will print out the current directory for you!
Assuming that we are in the Downloads folder, and assuming you have downloaded some files, we can print out all of the files in our current directory quite simply. If we type ls on Linux (and that’s a lowercase L, followed by s, not a 1.), or dir in Windows, it should print out all of the files in our directory.
Here we can see all of our files listed. We can further confirm our correct location by looking at these in our file explorer. We can open our current directory in the file explorer by typing xdg-open . in Linux or explorer . in Windows.
The ‘.’ is another special character when it comes to file paths that means: “the file path that you are at right now”. Similarly, we have another special set of characters “..” which means “one folder UP from where we are right now.” Basically, if you were to “back out” one folder.
For example the path “~/Downloads/..” is the same as “~”. This is because we go into Downloads, and then back out of Downloads right after.
Running programs/scripts is another essential ability to be able to use, whether it’s python, or starting up Firefox. Running programs is actually quite simple. In both Linux and Windows you can start a program simply by writing out the full path to the file that you want to run. For example, the command:
~/godot/bin/godot.linuxbsd.editor.x86_64
would start up the godot application for me. One thing to note, is that by starting a long-running application like I just did above, this will hold your terminal, and you won’t be able to type into the terminal again until the application “terminates” or “closes”. This is okay, as you can open another terminal. Instead of locking your terminal, you could start this application with a different command. You can use the ‘&’ symbol at the end of a command, to open a program in the background, which does not lock your terminal from being used.
~/godot/bin/godot.linuxbsd.editor.x86_64 &
On Windows, the syntax for running in the background is a little different. using the start command with a application title and filepath.
start "Godot, or other name" "C:\Users\mccole\Downloads\Godot\godot-64.exe"
Every command that you run operates in this same way, where you must supply the whole filepath, this is true even for basic commands such as ls. You might inquire: “Well, how can this be true? We call ls from anywhere and don’t specify a file path.” This is because ls and other special, operational commands live in a special place on your computer. You can find where ls lives on your computer via the following command:
whereis ls
And you should get /usr/bin/ls
On Windows this command is very similar
where dir
The reason that you don’t have to specify these full paths when you call them, is because, when you type in the name of an application to execute, the first place that your computer looks to call a program is the PATH. The PATH is a variable (will cover in the next section) that holds a list of file paths to look at to find programs. Your computer looks here first before your current directory. We can use the echo command to see what file paths are in our PATH variable.
echo $PATH
outputs:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin
On Linux, each of these file paths are separated by colons, so really we are looking at the following paths:
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
/snap/bin
Not sure why /snap/bin is on our path twice, but I guess that’s what it’s doing. As you can see, the /usr/bin/ directory, is listed here, which is the parent directory of where our ls command is located. To call this in Windows:
echo %PATH%
Other simple operations that you will commonly want to perform may be:
Copy a file (cp) -Linux/Windows
Remove a file (rm) - Linux
Remove a file (del) - Windows
Make a new directory (mkdir) -Linux/Windows
NOTE On Running Programs in Linux
You can only actually run programs that you have the permissions to run. A common issue occurs when you make a new script and you can’t execute that script, as it doesn’t have permissions yet. The way to add these permissions is with the chmod command. This command grants or restricts permissions for a specified file. We want to ADD EXECUTE permissions, so we can use the “+x” option to add execute to the file.
chmod +x path/to_the/file.sh
Using the -l option on ls you can see the read, write, execute permissions listed for the file owner, members of the group, and others.
-rwxrwxr-x means, owner:rwx (read, write execute), group:rwx (read write execute), other:r-x (read, execute).
If you’re working on your own PC, no worries thinking much about groups or others.
Variables In Terminal
A variable, for those that don’t know, is something that you refer to by a name, that stores a value, like text, or a number. In Linux and Windows terminals we have these as well and some are already set on our computer by default! In Linux, variables are always refereed to with a “$” in front of their name, while in Windows, variables are wrapped in “%” symbols. On Linux, a variable that exists already is HOME, and this refers to your HOME path (ie “~” or “/home/mccole”). In Windows, a similar variable exists already called HOMEPATH which should point to “C:\Users\mccole”. To print the contents of these variables, or to print anything in general, you can use the echo command. To print this variable on Linux, we’ll use the $ to de-reference the text as a variable. Without the $ symbol, echo will treat the text as text and just print the word HOME back at you.
echo $HOME
and on Windows
echo %HOMEPATH%
We can also create our own variables! This is mostly used in scripts. Windows has “batch” scripts, while Linux has “bash” scripts. Scripting is going to be out of the scope of an introduction to the command line, however, it’s good to be aware that scripting in the command line is essentially just using the same exact commands you use in a command line, but bundling them all together and executing them one after another. For example, we could have a bash or batch script that was simply this echo statement we wrote above, and all we would need to do to output the contents of HOME or HOMEPATH, would be to run our script.
Operating as Administrator On Linux
On Windows, you select “Open Command Prompt as Administrator”. However, in Linux, there is no such concept. Instead, you must call specific commands in an administrator elevated mode. To access this mode, you can use the command sudo (note that you will need to enter your password when executing a sudo command). Package installation is one instance where you will need to use the sudo command. Package installation will be covered in the next section, however, I can show here how to update and upgrade your applications already on your computer. In this instance Update is like finding out what is old and downloading packages. Where Upgrade is like installing the packages that you have downloaded. You can Update and Upgrade via:
sudo apt update; sudo apt upgrade
Note that the “;” symbol tells the shell (the terminal) to stop processing and split this long line of text as two commands: everything before the “;” and everything after.
Package Installation (Linux Only)
This is Linux only, as Windows does not have a built-in way to install packages from the command line. There are tools in Windows such as chocolatey, but those are external to the built-in command line. Also chocolatey only runs in Powershell.
In Linux, you can install packages from the command line using:
sudo apt install package-name
An example of such a package would be “python” or “cmake” or “git”, whatever you need. Some applications will have more complicated names, or require access to non-standard servers, so it’s best to look up the application you want to install online and find the proper command associated with installing that package.
Pipes (|)
The character “|” (the long straight vertical line) is called a pipe. Pipes are useful tools to take the output of the command on the left of the pipe, and put it into the command on the right as input. For instance, if we were to output the contents of a file in Linux with the command, cat, all of the contents of the file would go to the terminal. However, if we wanted to search for text within the file, we would want to use that text as input for a grep command, which searches for text. We can do that with pipes!
cat file.txt | grep "hello"
This will search for hello in the contents of the file, and when it comes across a match, it will output that to the screen for us! Pipes allow us to take a series of simple tasks, and create something rather complex.
Directing Output
Typically when we have output from a command, it goes straight to the terminal, or through a pipe, which we saw above. But then the output of the final operation still ends up in our terminal. Say we wanted to print all of that to a file instead? We can do that really simply with two types of commands “>>” and “>”
> - This will create a new file, or delete and recreate an existing file and replace it’s contents with the output that would go to the terminal.
>> - This will keep the existing contents within the file and “append” or “add onto the bottom of” that file. So if we had a log file, and wanted to keep the current logs and just add new logs, we would use “>>” instead of “>”
Now, if we ran the command from the pipe example with Output directing, we can store the result in a file
cat file.txt | grep "hello" > helloResult.txt
Intermediate To Advance Command Line Use/Tools (Linux)
So we have the basics of the terminal, we can move around, find files, and start up applications. We want to be able to use some more intermediate or advanced tools as well. I’ll list some of the most common tools and what they do in basic terms. Many of these tools have series of tutorials or books dedicated to their abilities. This list will give you a starting point of what to look for when trying to figure out how to do something.
man - short for manual. Use this command to read about any other command! This is a great place to start when using a new command
For example : man awk
This will give you the manual on the awk command.
find - finds the location of a file of a particular name
For example: find . -name “godot*”
In this case, I’m asking for anything that has “godot” and then “*” means match anything that comes afterwards.
cp / rsync - copy files
rm - remove files (delete)
less - opens a file as text and provides a way to read through the file
cat - output the contents of a file
head - output the upper contents of a file
tail - output the lower contents of a file
vim - a complex text editor that requires a whole series of tutorials all on it’s own!
emacs - alternate to vim, but just as powerful!
nano - alternate to emacs/vim. Simpler to use but not nearly as powerful, nobody really uses this.
grep - searches for a given string from an input
For example: cat file.txt | grep “error”
This will search the text “error” in the file file.txt
awk - a text interpreter that allows for easy splitting and display of delimited text
awk ‘{ print $4 }’
Awk splits on space characters, and so this will print the fourth word on each line.
sed - a great text processing tool, great for performing find-replace operations in-place
For example: sed ‘s/hello/goodbye/g’
This will replace the text “hello” with the text “goodbye”
td - translate or delete characters - another text interpreter that does special operations on characters
wget - given a url, this will download contents from an ftp or page onto your computer
Intermediate To Advance Command Line Use/Tools (Windows)
findstr - find matching text found within files
HELP - find information about a given command
cp - copy files
del - delete files
Pulling it all together
cat ./data/* | grep -E "^#" | sed 's/#//g' | tr '[:lower:]' '[:upper:]' > output.txt
Now, using all that we know above, we can look at the first command I showed before and break this down into all of it’s components. Let’s take stock again of where we are and what the contents of our files look like.
We are at ~/ and I have a folder named “data” and inside that folder I have the following files:
file_data_1.txt
file_data_2.txt
file_data_3.txt
Inside of those files, here are their contents:
data/fileData1.txt
#Start
Hello
#What's up
I # am # loving # this
data/fileData2.txt
popcorn style!
#this is file 2
data/fileData3.txt
File 3
#this is File 3
Looking at our command, we can see that there are four commands separated by three pipes, and we are directing the output to a file named output.txt. Let’s break up those commands
cat ./data/*
Cat outputs the contents of a file to the terminal
In this case, we are using the ‘*’ operator to match anything. So we are saying print the contents of anything in the data folder.
So this will print the contents of all of our files in the data folder
The output of the cat operation is so:
#Start
Hello
#What's up
I # am # loving # this
popcorn style!
#this is file 2
File 3
#this is File 3
grep -E “^#”
This output you see above is piped into a grep statement, this will search for text.
In this case, we use the “-E” option to “enable regex” regex allows for fancy searching. One fancy thing I’m doing is using the “^” character, which in regex means “starts with” so we are searching for lines that start with the “#” character. Meaning the line “I # am # loving # this” will not be picked up.
Here is the output after the grep is finished:
#Start
#What's up
#this is file 2
#this is File 3
sed ‘s/#//g’
sed is going to perform a find-replace operation for us here, where we look for the # symbol, and replace it with nothing. Cutting it from existance.
Here is the output:
Start
What's up
this is file 2
this is File 3
td ‘[:lower:]’ ‘[:upper:]’
This is the final operation we perform, and we are performing operations on each character, where we are transforming their state from lower-case to upper-case letters
Here is the final output
START
WHAT'S UP
THIS IS FILE 2
THIS IS FILE 3
After this, instead of outputting to the terminal, we are choosing to store this in a file named output.txt. If we now cat output.txt, we should get the above output, effectively stored away on our computer until we delete it.
Conclusion
This is a first introduction to getting started with the command line. No matter where you go from here, I fully expect that you will need to Google for commands and solutions, as you will always be learning new tools and techniques on the command line. Even if it’s a tool like grep that I’ve used for years, I may learn new options or arguments to call with it to perform exactly what I need in a given situation.
I hope that this can get you moving around the terminal in a way that you feel comfortable, and like you know the basics of what’s going on.