One of the first giveaways that someone has been working as a developer for a good amount of time is their level of comfort working from the command line. Rarely will you see a seasoned software engineer opening a graphical file explorer to move between project files.
Instead, they will turn to the powerful Swiss army knife that is the computer’s command line. Why bother learning this tool if you can stick the familiar and user-friendly graphic interfaces offered by modern operating systems?
- Precision — the command line allows you to fine-tune your actions in ways that simply aren’t possible in general user interfaces.
- Portability — if you are using SSH to access a remote machine, for example, your only option will often be to interact with that machine through its command line.
- Speed — once you are comfortable interacting with the command line everyday tasks simply take less time.
The learning curve for command line interaction with a computer pays off in very little time provided you know where to start. This article will attempt to demystify some foundational concepts and give you the basic tools necessary to start leveraging the power of the command line.
When talking about dealing with the command line there are a number of common terms that will crop up. You may hear references to things like Bash and CLI and wonder what the difference is. Here is a quick overview of the most frequent terms.
CLI — Command Line Interface, general term for an interface that presents text prompts and allows a user to interact with software and operating systems by typing in commands.
Shell — the interface used to interact with an operating system. In a software engineering context, this generally refers to a CLI as opposed to a GUI (graphical user interface) such as what an end user will use to explore their file system.
Terminal — the program that runs the shell. On MacOS, there is an application called Terminal which allows the user to run shell commands.
Bash — the combination of shell and language used on most Unix based operating systems such as MacOS. Note, I personally use a Mac so commands and terms may vary slightly from those discussed below if you are on a Windows machine.
ZSH, fish — both are alternative shells that can be installed on a Unix based OS to replace Bash and provide some additional functionality.
Anatomy of a Command
As a user, you can interact directly with your machine using the command line. This enables quick navigation and manipulation of files without cumbersome graphical interfaces. To interact, you will enter commands which can look like this:
$ curl -v --fail --data "foo=bar" http://localhost:3000
The example above contains a few elements that you will frequently encounter. The
$ is simply a shorthand way to show that the text is meant to be entered into the CLI, it is not part of the command. If you are trying to copy a command from the internet to use on your own machine, don’t include this prefix if you see it.
The first item,
curl is the actual command being given to the machine. In this case, the command is used to send data to or from a server. Next, the command is being modified by two flags that will alter the behavior of the command. The first,
-v, tells curl to output additional verbose logs. This is an example of a short-form flag. The second is a long-form flag telling curl to fail silently, behavior it would not normally have.
The next item is actually comprised of both
”foo=bar”. This is equivalent to typing
—data=“foo=bar”. This argument sets the value of data to the string that has been passed in, ”foo=bar”. While the terminology used is somewhat fluid, this type of argument is generally not referred to as a flag because it is not a boolean option.
The final argument is the main value being passed to curl. In this example, it is the actual url location being targeted. Curl requires this final argument, but the first three are optional. The documentation for curl denotes this structure as
curl [options] <URL>. Some commands will have similar structures, while others will be simpler and can even be used without any arguments at all.
Now that you know what the command line is and what a command looks like, what kind of things can you use it to accomplish?
When most computer users need to find a file on their machine, they begin by opening their file manager (such as Finder on Mac or Explorer on Windows). They would then double-click on a folder icon and view the files within. This can all be done with command as well.
$ cd foobar
cd is used to move throughout directories (sometimes referred to as folders, they have the same meaning). In the command above, the user is moving from their current location into a directory name “footer”. There must be a folder with that exact name for the command to succeed.
So what is your current location? When you first open the command line, you will start in your home directory. On MacOS, your home directory will look something like
/Users/yourname. Thus if you opened your terminal and entered the command above you would end up in
/Users/yourname/foobar. The tilde symbol is shorthand for this directory, so entering the command
cd ~ will always take you back home, regardless of your current location.
Absolute Paths — a path beginning with a forward slash such as
/usr/local. This type of path always starts from the root directory of the machine (the very topmost directory). It disregards the current location.
Relative Paths — a path without a leading forward slash. This type of path is evaluated from the current location. The “foobar” path above is an example of a relative path.
$ cd ..
The command above navigates up into the directory above the current location.
$ cd ../foobaz
This command navigates up one directory, then from there into the directory named “foobaz”.
So how will you know where to navigate once you are in a directory? For this, you’ll make use of the
ls command to list the files and subdirectories directly within your current location. It is often used in the form
ls -al which includes a combination of two flags.
-a causes the list to include all results, including hidden files and directories.
-l cause the results to be output in a handy formatted list with some additional information. The result will look something like:
$ ls -altotal 0
drwxr-xr-x@ 9 root wheel 288 Sep 20 21:01 .
drwxr-xr-x 29 root wheel 928 Dec 15 08:21 ..
drwxr-xr-x 971 root wheel 31072 Dec 15 08:19 bin
drwxr-xr-x 304 root wheel 9728 Dec 15 08:19 lib
drwxr-xr-x 248 root wheel 7936 Dec 15 08:19 libexec
drwxr-xr-x 14 root wheel 448 Oct 25 14:03 local
drwxr-xr-x 239 root wheel 7648 Dec 15 08:19 sbin
drwxr-xr-x 46 root wheel 1472 Oct 25 13:56 share
The most critical information here is contained in the final three columns. The last is the directory/file name. The second-to-last is the creation time, and the third-to-last is the file size.
Text based files can even be viewed in their entirety within the shell terminal. To do so enter the following command and you will be able to begin scrolling through the contents of your file.
$ less filename.txt
Once you are done viewing the file, hit the q key to quit the previewer.
Manipulating Directories and Files
Once you explore the file system using
cd, you can begin making changes to the items that you find.
Create a New Directory
This will create a brand new empty directory in your current location.
Delete a File
This command will remove, or delete, a single file. It will return a warning if the file does not exist.
Delete a Directory
rm -rf sample_directory
This command will delete an entire directory, if it exists. The
-rf combined flags are short for recursive and force. These allow
rm to remove all contents of the selected folder while suppressing the default warning messages.
Copy a File
mv filename.txt ~/sample/path/filename.txt
This command will move a file, specified in the first argument, to a new location, specified by the path named in the second argument. The first argument, the targeted file, is a path relative to the current location.
Rename a File
mv filename.txt newname.txt
The same command can be used to simply rename a file while leaving it in the same location.
Creating and Editing Files
Once in a directory, entirely new files can be created with the
touch command. The following will create a brand new text file in the current directory.
$ touch newfile.txt
After issuing the command, file.txt will exist but will be entirely empty. If you wish to add simple content to the file, you can use the following command.
$ echo "A sample sentece" >> newfile.txt
Each time this command is issued it will append the input to the end of the file.
For more sophisticated file editing, it is possible to use a text editor that exists completely within the terminal application. There are multiple options for such editors, but one commonly used choice is VIM. Using these editors can be a daunting endeavor for beginners, with guides spanning entire books. To get started, here are a few very basic essentials.
Open a file in VIM with the following command:
$ vim filename.txt
This will open the VIM editor. If you try to start typing, nothing will happen. To make changes, you will need to switch into insert mode. To do this, simply type
i. At the bottom of the screen you should see
— INSERT —, you can now start editing your file. Keep in mind that you will not be able to use your mouse, all navigation must be done by keyboard.
Once you make your changes you will need to save you file and exit the editor. To do so first hit the esc key. Next, type
:wq and hit enter. This command tells VIM to save the changes to the file and exit.
This guide covered only the most basic tools available in the command line. Each of the commands listed have numerous additional flags and options and there are near-infinite available commands and programs that can be used from the command line. That said, knowing these basic commands will allow you to competently manage most everyday tasks right from your terminal. To dive deeper, here are a few additional resources to explore.