There are many good arguments for getting used to the command line interface (CLI). However, as a complete beginner, it can be difficult to start, and a new shell session can feel a bit intimidating:
Let’s go through CLI basics!
Where to start
The first thing you need is a terminal emulator: a program that emulates the text-only access to your machine. Any operating system (OS) will have a big choice of emulators: they are all pretty similar, and the main differences will be
- the number of colors supported,
- available options for font types, size, or color schemas,
- key shortcuts for increasing font size, etc.
At the very beginning, you should be fine with what is available there in your OS or integrated development environment (IDE).
Shell is a program that interprets your commands and runs programs for you. It’s a different thing than the terminal simulator we talked about above. In a way, in your graphic interface, you open the terminal, and inside the terminal you have a text-only interpreter of commands. There are many options available, with subtle differences that can alter the user experience a lot.
Z shell, or Zsh, is a modern and popular command interpreter. Its interface is user-friendly, and there are community packages available that allow you to customize your shell experience: Oh My Zsh. I have used it for a few years, and most of my CLI habits are adapted from it.
Bash is a slightly older alternative to Zsh. It’s very common, so you can expect it to be available on many machines that you’ll encounter out there. Many shortcuts from Zsh work there too, but it’s using different configuration files, and the scripting language is a bit different.
The standard shell. It’s part of the standard Unix commands, and it’s mostly guaranteed to be on any Unix-like machine you will find. Therefore, it’s a safe bet when it comes to writing scripts. The user interface lacks many modern improvements, so I wouldn’t use it for anything besides wiring scripts.
What is my shell anyway?
You can check your shell with
In my case, it’s
How to change your shell
Every shell is a program and can be run directly from another shell. For example:
In this way, you can check what shells you have installed and test them quickly. To change the shell permanently, you can use the command
chsh (change shell), in both Linux and macOS:
If you lack the shell you want to use, you need to install it first—the exact command depends on your OS or Linux distribution.
So, once you have your terminal up and running, how do you use it?
CLI allows you to run commands by typing their name in the terminal and pressing enter. Each command is a separate program that offers an extensive interface, and each comes with its own documentation. Likewise, each OS brings its own set of commands, but they share similarities—especially with systems inspired with Unix, macOS and Linux. On Windows, the standard command line
cmd has a very different set of commands, but there are many options available to get a similar interface there as well:
- Native Windows Subsystem for Linux
- Git BASH provided by Git for Windows
Unix was an OS that became publicly available in 1973, and it influenced plenty of things that came later. Its current specification defines 161 commands, but luckily you only need a handful of them to benefit from CLI.
Example of commands:
lslist files in a folder—by default, it shows the contents of the current folder:
pwdshows the current path in which you are running your commands:
cdchanges the directory—by default it goes to the home directory (https://asciinema.org/ recording or screenshot)
Each command can take additional arguments. Arguments are space-separated values that come after the command name. The meaning of the arguments depends on the program. You can read about the different arguments in the command documentation:
Many standard commands come with different options that allow you to modify the program behavior. For example,
ls is very often used with the following options:
-a—to show all files, including ones that start with
.—a Unix convention for hidden files
-l—show files in the long format—providing more information
A common convention is to allow options as separate parameters,
ls -a -l, or combined into one parameter,
A parameter is an argument that provides a value to the command, or one of its options.
So for instance, with the example from above, you can provide a path to change the default behavior:
ls workspace—lists files in workspace folder:
cd workspace—changes current directory to workspace:
cat file—shows the file content on the screen:
The meaning of parameters depends on the program—at first, you can expect to need to check the documentation a lot.
Standard output is the text that is added to the command line when you run the program. It’s text shown by the happy path of the execution. The examples we’ve seen so far have shown the standard output of different commands.
When learning C++, one of the first things you learn is
cout—the standard output.
By default, the standard output is just shown on the screen, but you can easily redirect it to a file with
> operator. Example:
Error output is where programs display information about issues encountered during execution. While running commands directly from the terminal, error output and standard output are treated the same—they’re just displayed on the screen. For example, when I try to
ls a non-existing file:
The difference becomes obvious when you redirect the output to a file:
In a normal workflow, standard input is what you type into your program. The commands we’ve seen so far are not typically used in an interactive mode. A simple example can be a
man page that allow for scrolling:
For those with C++ experience, you’ve heard this term for
cin >> variable;
For many common commands, the standard input becomes especially important because of the pipe operator.
Pipes are ways of connecting the standard output of one program with the standard input of another. This is how CLIachieves the interoperability I mentioned in my previous article. Using pipes allows you to combine different commands in plenty of creative ways—I’ll be showing some examples later in this series. For now, a simple example is:
cat …—reads files and returns their content in standard output,
less—gets the value from standard input, and makes it fit to the the screen
Similarly, with using the search utility
cat …—as above
grep 1—gets the value from standard input, filter it to only the lines that contains
Writing to files
We have already mentioned the
> operator, used to write the standard output of a command to a file. This operator overrides the file with the output we provide. If you would like to append to an existing file, you can use
Everything that happens in the command line is done in the context of a specific disk location—a working directory. When you specify relative file paths—for reading or writing—they are resolved from the working directory. Usually, you set your working directory to a top folder of the project you are working on. When you start a new session, usually the working directory is set to your home directory.
Shell interpreters offer you many shortcuts to speed up your work. With time, you’ll start using them intuitively, without thinking about them. Often when I screen-share with beginners, I’m reminded that those shortcuts are nothing but obvious—below I’ll show you a few productivity tricks for working with the command line.
I’m using Zsh myself, and these shortcuts work there. At least some of them should work in Bash, too, but it can depend on the exact version and configuration.
Don't type twice—use arrows
The main trick to be fast with CLI is not typing everything all the time. The most basic case is to get back a command you’ve run a few lines before. You can do so by pressing the up arrow key. With arrow up and arrow down, you can scroll through the recent commands, and once you find a one similar to what you want to run now, you can edit it. This speeds up the whole process a lot because you often run similar commands, with some tiny difference in arguments.
Search older commands
Manual scrolling is fine for getting one of or a handful of most recent commands. If you want to get something further from the past, however, you can use a search functionality. By default, the command is you can use CTRL + R to begin a search in your command history:
Use to autofill
You don’t have to type the entire commands you would like to run. Both Zsh and Bash support the tab key as a way of asking for autofill—they will fill up the command or file name if they are unique or show you all the available options if what you type matches many possibilities. Zsh provides autofill for command options as well.
The autofill is a great feature on two levels: it helps you save time on typing, and it reduces mistakes. As you learn CLI, you should make sure to get into the habit of using autocomplete as much as possible.
File names wildcards
You can speed up typing even more by using wildcards to match the names of multiple files:
Often, when a program has so much output that it doesn't fit into the screen, it uses another program as a pager—a tool that lets you navigate the output and scroll up and down. Most often the program used for that is
less. There are a few things worth noting when you use it.
First and foremost, don’t scroll with the scrollbar provided by your terminal emulator.
less redraws the whole screen of text at the end of the output. If you scroll up inside the terminal emulator, you will see what was returned by other programs before, not the contents of the file you want to read. Instead of scrolling with the scroll bar (scroll wheel) use arrow up and down to move around the file.
Another common point of confusion—how do I leave now? You can leave the full screen mode of ‘less’ by pressing
q. It’s often styled as
:q because other programs (for example
: to start a command.
In the command line, everything is text, and text is straightforward to search through. You can search inside the content shown by less by typing
/<search term>, and navigate through results by typing
less supports other navigation command similar to what you can find in
j—scroll down one line
k—scroll up one line
gg—scroll to the beginning of the file
G—scroll to the end of the file
d/u—down/up half screen
Those shortcuts will help you navigate quickly through the file.
Are you interested in learning more?
That’s great! The command line is a great tool to boost your efficiency while programming. You can sign up here to get updates from me as I publish other command line related materials.
Top comments (2)
Thanks for an easy to comprehend article:).
Command line looks so initimidating at first, but looks the invested effort repays back soon.
What is your reason to sticking with zsh instead of using bash? Is it more popular among developers/your job or is it matter of personal taste?
Good question! It's been a long time when I decided on Zsh, and I just followed recommendations online—I don't have well researched arguments in favor of Zsh. From my recent experiments, it seems to me that Bash lacks some autocomplete features I'm used to—but this can be matter of comparing Bash alone to my Zsh + some additional tooling I installed.