This chapter introduces the command line interface in Linux. Examples are used to demonstrate various tasks of interacting with the operating system (including files and directories) and applications with commands. Many of the commands are only really understood after practice. You are recommended to explore your Linux computer using the command line. Having a cheat sheet, such as the Linux Reference Card, printed and by your side when exploring can also be useful.
This chapter assumes you have knowledge of:
All of the practical tasks in this chapter can be completed on a single Linux computer. Although virtnet (Chapter 3) is not required, if you do use it, as only a single computer is necessary, topology 1 is appropriate (or in fact any topology—just use a single node).
The terminal application prompts you for a command, you type in the command and then press ENTER causing the command to execute, and then optionally the command may output messages on the terminal.
An example prompt is:
network@node1:~$
The cursor is after the dollar sign ($), and it is there that the command is typed in. The format of the prompt may differ across computers (and you can customise it), however the default prompt on Ubuntu shows:
The username and host name are separated by the at sign (@), the host name and directory are separated by the colon character (:), and the prompt ends with the dollar sign ($).
Note that if you change directories, users (e.g. login as a different user) or even hosts (e.g. remotely login to another computer) the prompt will change. Use the prompt as a quick reminder of “where” and “who” you currently are.
In this book, for brevity, when not relevant the information before the dollar sign may be omitted. For example, in this chapter, since the username and computer host name are not important, we will simply use:
$
Normally, when a command executes, you have to wait for the execution to complete until you are returned to the prompt. That is, you can enter and execute only one command at a time. Section 4.7 will show you how to execute multiple commands, and to return to the prompt while a time-consuming command is still executing.
If you find yourself typing commands when there is no prompt, that will most likely mean something is wrong, e.g. a previous command is still executing.
The terminal uses a shell to interpret the commands you want to execute. There are different shells available, but a common one is bash. In addition to executing commands, shells such as bash provide a basic programming environment, allowing you to use conditionals (if), loops (for, while) and variables. Chapter 6 will show you some simple examples of shell scripts that use these features. For now we will simply use the shell to execute commands.
Most commands are standalone executable applications. Some commands are not applications, but commands built-in to the shell. At this point, we won’t distinguish between the two, and just refer to them as commands.
To run a command, type the command name at the prompt. An example is the command ls, which lists the files in a directory.
$ ls
app example.txt README.txt
$
The output of the command execution is shown (in this example, three files called app, example.txt and README.txt), and you are returned to the prompt.
Some commands take parameters, which are entered following the command name. For example, with ls you can specify a subset of files to list using the * wildcard.
$ ls *.txt
example.txt README.txt
The command ls with the parameter *.txt lists all files that end with .txt. Some commands may accept multiple optional parameters, each separated by space.
Some commands also have options, which are normally entered following the command name and before any parameters (although in most cases can be anywhere after the command name). Options enable or disable features of the command. There are two methods of specifying an option:
Continuing our example with ls, the -a option shows all files, including any “hidden” files. We will see in Section 4.3 that hidden files (and directories) are simply those whose name start with a dot (.).
$ ls -a
. .. app example.txt .my_secret.txt README.txt
There is an additional “hidden” file listed, as well as two special directories (. and .. as discussed in Section 4.3).
The long format option equivalent of above is:
$ ls --all
. .. app example.txt .my_secret.txt README.txt
Multiple options can be listed, usually in any order. The -l option lists files with more details. Below is an example also combined with parameter.
$ ls -a -l
total 152
drwxr-xr-x 2 sgordon sgordon 4096 Nov 23 10:05 .
drwxr-xr-x 9 sgordon sgordon 4096 Nov 23 09:45 ..
-rwxr-xr-x 1 sgordon sgordon 133792 Nov 23 09:46 app
-rw-r--r-- 1 sgordon sgordon 19 Nov 23 09:46 example.txt
-rw-r--r-- 1 sgordon sgordon 7 Nov 23 10:01 .my_secret.txt
-rw-r--r-- 1 sgordon sgordon 7 Nov 23 09:46 README.txt
The meaning of the output will be explained in Section 4.3.
Finally, to save typing, single dash options can be combined together. The following example is identical to above. The options -a -l can be shortened to -al or -la.
$ ls -al
total 152
drwxr-xr-x 2 sgordon sgordon 4096 Nov 23 10:05 .
drwxr-xr-x 9 sgordon sgordon 4096 Nov 23 09:45 ..
-rwxr-xr-x 1 sgordon sgordon 133792 Nov 23 09:46 app
-rw-r--r-- 1 sgordon sgordon 19 Nov 23 09:46 example.txt
-rw-r--r-- 1 sgordon sgordon 7 Nov 23 10:01 .my_secret.txt
-rw-r--r-- 1 sgordon sgordon 7 Nov 23 09:46 README.txt
We have seen in the previous section that when a command executes it may print output on the screen. The output from a command due to normal operation is sent to standard output, or stdout. By default, the standard output it displayed on the terminal.
$ ls
app example.txt README.txt
$
If something goes wrong with command execution, then error messages may be produced. These are sent to standard error, or stderr. Again, the standard error is displayed on the terminal.
$ ls *.doc
ls: cannot access '*.doc': No such file or directory
There is also standard input, or stdin, which refers to what you type in to an interactive command.
In Section 4.6 we will see an example of standard input, and also how to redirect the standard output and error to a file. That is, instead of the output of a command displaying on the terminal, it is written to a file.
We have given a brief introduction to executing commands in a terminal, and introduced the concept of options and parameters of commands. The following sections will demonstrate useful commands. However there are many more, and most commands have multiple options and parameters. There is no way for you to remember all of them. Luckily there are ways to get help with known commands, and also discover unknown commands.
Most commands which are standalone applications have a manual, or man page. The man page can be viewed using the man command, followed by the name of the command. For example, to read the manual of the ls command:
$ man ls
This displays an interactive text version of the manual, including a list of options and parameters. If you cannot remember an option, read the man page. You can scroll up and down with your keyboard arrows and page up/down keys. To exit or quit the man page and return to the prompt, press q. For more help on navigating man pages, read the man page:
$ man man
Some commands do not have a man page. There may be different reasons, but you have several options to look for help.
Commands built-in to the shell do not have a man page, but the shell has a help command. For example, the command cd (for changing directories) is a built-in command.
$ man cd
No manual entry for cd
$ help cd
cd: cd [-L|[-P [-e]] [-@]] [dir]
Change the shell working directory.
...
If man or help do not provide any information, then sometimes using the -h or -? option displays help, or even running a command that normally expects arguments, without arguments.
Yet another option, while the man pages are quite extensive, some commands use a different system/command called info. If you are up for some reading, then the GNU core utilities, or coreutils section contains a great summary of common commands. In fact reading about the core utilities is probably better than reading this chapter.
$ info coreutils
All of the above help systems are available directly on your Linux system (assuming they are installed). You don’t need a network connection to access them. Of course, searching on the web is a good way to learn about how to use commands.
As with many operating systems, in Linux directories (or folders) are organised in a hierarchical manner, with a root directory at the top, and sub-directories within the root directory. Those sub-directories may have their own sub-directories and so on. Files may exist in any directory (including the root directory).
The full path of a directory or file can be specified by listing all the directories above it, using the forward slash character (/) as a separator. (Directories and files are very similar and sometimes we will not clearly distinguish between them. Later we will see ways for distinguishing). The root directory is specified by a single forward slash. That is, / refers to the root directory, /home refers to the home directory which is a sub-directory of the root directory, and /home/network refers to the network directory which is a sub-directory of the /home directory. In Chapter 7 you will learn about users in Linux; for now note that the user in this demo is called network and their home directory is /home/network. Finally, /home/network/file.txt refers to the file file.txt within the network directory.
Let’s see some commands for performing operations on directories (and files).
When you open a terminal and execute commands in a prompt, they are executed while you are in a particular directory. To print your current or working directory:
$ pwd
/home/network
To change directories we use cd, normally followed by an argument indicate where to change to. To change to a specific directory, pass the full path (also referred to as an absolute path) as an argument:
$ cd /
$ pwd
/
$ cd /home/network
$ pwd
/home/network
You can also specify a relative path, indicating the directory relative to your current working directory:
$ cd /
$ pwd
/
$ cd home
$ pwd
/home
$ cd network
$ pwd
/home/network
The above illustrated changing to the root directory using an absolute path in the first cd command, and then changing down in the hierarchy using relative paths in the second two cd commands. You can change up in the hierarchy by specifying the special .. argument:
$ pwd
/home/network
$ cd ..
$ pwd
/home
$ cd ..
$ pwd
/
Other special directories are . for the “this current directory”, for your home directory and - for the previous directory. Finally, not passing an argument to cd returns you to your home directory.
$ pwd
/
$ cd
$ pwd
/home/network
$ cd ..
$ pwd
/home
$ cd -
/home/network
$ pwd
/home/network
$ cd /
$ pwd
/
$ cd .
$ pwd
/
$ cd ~
$ pwd
/home/network
Now that we can move between directories, let’s look inside a directory. You can list the contents of a directory using ls:
$ pwd
/home/network
$ ls
lynx.cfg virtnet
$ cd /
$ ls
bin dev home lib media opt root sbin sys usr vmlinuz
boot etc initrd.img lost+found mnt proc run srv tmp var
Note in the above example, there are two files or directories inside the network users home directory: lynx.cfg and virtnet. There are 21 entries in the root directory. We will return to ls shortly to list more information, including using it to identify whether a particular entry is a file or directory. But first let’s make/create some directories with mkdir and remove/delete directories with rmdir.
$ cd
$ mkdir demo
$ ls
demo lynx.cfg virtnet
$ cd demo
$ pwd
/home/network/demo
$ mkdir stuff
$ ls
stuff
$ mkdir another
$ ls
another stuff
$ rmdir another
$ ls
stuff
$ pwd
/home/network/demo
$ cd ..
$ pwd
/home/network
$ ls
demo lynx.cfg virtnet
$ rmdir demo
rmdir: failed to remove 'demo': Directory not empty
$ ls
demo lynx.cfg virtnet
We create a directory demo and then two directories within that, stuff and another. Then we deleted the directory another and finally changed back to our home and tried to delete the demo directory. Note that the last rmdir demo did not work. It returned an error saying the directory is not empty. By default, we can only delete empty directories. Let’s remove stuff and then demo:
$ pwd
/home/network
$ rmdir demo/stuff/
$ ls demo
$ rmdir demo
$ ls
lynx.cfg virtnet
Now let’s see some operations on files.
We know ls lists both files and directories. Let’s find an existing file on our Linux node and then copy it to our home directory. For this demo, we will use the file hostname within the /etc directory. Although it is not important, hostname is a plain text file that stores the name of the host, i.e. node1.
$ cd
$ mkdir demo
$ cd demo
$ pwd
/home/network/demo
$ cp /etc/hostname /home/network/demo/
$ ls
hostname
The cp command takes a source and destination as arguments. We specified the full file name (including absolute path) as the source, and the full/absolute destination directory. We can use relative paths, and also change the name of the file saved at the destination:
$ cp /etc/hostname myfile.txt
$ ls
hostname myfile.txt
We can remove/delete files with rm:
$ rm hostname
$ ls
myfile.txt
Be careful! There is no trash or recycle bin. Without some digital forensics, the file is lost once you remove it.
If we won’t to copy to the current directory, keeping the same file name, specified . as the destination:
$ cp /etc/hostname .
$ ls
hostname myfile.txt
Files can be moved between directories and within the same directory using mv. Moving within the same directory is effectively renaming the file.
$ mv hostname hostname.txt
$ ls
hostname.txt myfile.txt
$ mv myfile.txt ..
$ ls
hostname.txt
$ ls ..
demo lynx.cfg myfile.txt virtnet
Note: File Extensions
In Linux file extensions are not required, and often not important for applications. That is, a
plain text file can be called file.txt or file.text or file.exe or just file. No
matter the file extension, it is still just a plain text file. Essentially, the characters
following a dot are just part of the file name. Despite this, it is good practice to
use sensible/common file extensions. A few extensions you may come across in this
book:
Let’s now return to listing files with ls and see some of the options available. Recall from Section 4.2.2, options can be specified with a dash (-). To see what options are available consult the command man page. For ls, a very useful option is to list the output in long format:
$ ls
hostname.txt
$ ls -l
total 4
-rw-r--r-- 1 network network 6 Jan 14 15:53 hostname.txt
$ ls ..
demo lynx.cfg myfile.txt virtnet
$ ls -l ..
total 16
drwxrwxr-x 2 network network 4096 Jan 14 15:55 demo
-rw-rw-r-- 1 network network 174 Mar 2 2017 lynx.cfg
-rw-r--r-- 1 network network 6 Jan 14 15:51 myfile.txt
drwxrwxr-x 6 network network 4096 Feb 10 2017 virtnet
The long format output includes:
Another ls option is to show “hidden” files. In Linux, hidden files are simple files/directories whose name start with a dot (.). There is no security in hidden files—anyone with correct permissions can access them. The are only hidden from the default ls output. Here we will first create a hidden file than list all files with ls:
$ cp hostname.txt .hidden-hostname.txt
$ ls
hostname.txt
$ ls -a
. .. .hidden-hostname.txt hostname.txt
Note that . (current directory) and .. (parent directory) are also listed, since they are also kept track of.
A final demo of ls showing human friendly sizes:
$ ls -alh
total 16K
drwxrwxr-x 2 network network 4.0K Jan 14 17:11 .
drwxr-xr-x 8 network network 4.0K Jan 14 15:55 ..
-rw-r--r-- 1 network network 6 Jan 14 17:11 .hidden_hostname.txt
-rw-r--r-- 1 network network 6 Jan 14 15:53 hostname.txt
Performing tasks in Linux (and UNIX-based operating systems in general) commonly depends on manipulating files, especially files containing plain text. Some examples are:
As a result, many applications in Linux are written to be able to read plain text as input, and output plain text. In turn, there are many commands to view, process and edit plain text files.
First we will show several ways for viewing text files.
To show the entire contents of a file on the screen use cat, which means “concatenate”:
$ cat /etc/legal
The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
As the name suggests, you can display one file after another, i.e. concatenate two files:
$ cat /etc/legal /etc/hostname
The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
node1
Note we are using files in the /etc directory as they are most likely to already exist on your computer. In Section 4.4.2 we will create our own text files.
Observe what happens when you cat a long file:
$ cat /etc/services
# Network services, Internet style
#
# Note that it is presently the policy of IANA to assign a single well-known
# port number for both TCP and UDP; hence, officially ports have two entries
# even if the protocol doesn't support UDP operations.
#
# Updated from http://www.iana.org/assignments/port-numbers and other
# sources like http://www.freebsd.org/cgi/cvsweb.cgi/src/etc/services .
# New ports will be added on request if they have been officially assigned
# by IANA and used in the real-world or are needed by a debian package.
# If you need a huge list of used numbers please install the nmap package.
tcpmux 1/tcp # TCP port service multiplexer
echo 7/tcp
echo 7/udp
discard 9/tcp sink null
discard 9/udp sink null
...
The entire file is displayed, making it hard to see the start of the file. Unless you have scrolling enabled in the terminal, you will only see the last “page” or screen of the file. This is inconvenient.
To view files page-by-page, including the ability to scroll up and down by line or by page, use less:
$ less /etc/services
# Network services, Internet style
#
# Note that it is presently the policy of IANA to assign a single well-known
# port number for both TCP and UDP; hence, officially ports have two entries
# even if the protocol doesn't support UDP operations.
#
# Updated from http://www.iana.org/assignments/port-numbers and other
# sources like http://www.freebsd.org/cgi/cvsweb.cgi/src/etc/services .
# New ports will be added on request if they have been officially assigned
# by IANA and used in the real-world or are needed by a debian package.
# If you need a huge list of used numbers please install the nmap package.
tcpmux 1/tcp # TCP port service multiplexer
echo 7/tcp
echo 7/udp
discard 9/tcp sink null
discard 9/udp sink null
systat 11/tcp users
daytime 13/tcp
daytime 13/udp
netstat 15/tcp
qotd 17/tcp quote
msp 18/tcp # message send protocol
/etc/services
You can now use the arrow keys (UP, DOWN) and PGUP (or SPACE) and PGDN keys to scroll through the file. To quit/exit, press q.
If you want to view only the start of a file, or the end of a file, you can use head or tail:
$ head /etc/services
# Network services, Internet style
#
# Note that it is presently the policy of IANA to assign a single well-known
# port number for both TCP and UDP; hence, officially ports have two entries
# even if the protocol doesn't support UDP operations.
#
# Updated from http://www.iana.org/assignments/port-numbers and other
# sources like http://www.freebsd.org/cgi/cvsweb.cgi/src/etc/services .
# New ports will be added on request if they have been officially assigned
# by IANA and used in the real-world or are needed by a debian package.
By default, head shows the first 10 lines of a file. And tail shows the last 10 lines. You can use the -n option to specify the number of lines to show:
$ tail -n 3 /etc/services
fido 60179/tcp # fidonet EMSI over TCP
# Local services
A nice feature of tail is to “follow” a file. For files that are regularly changing, such as log files being written to by servers, using the -f option will cause tail to run forever (or until someone tells it to stop), showing any updates to the file when they occur. To test this, follow the system log /var/log/syslog:
$ tail -f /etc/log/syslog
Jan 18 15:58:47 node1 systemd[1377]: Reached target Timers.
Jan 18 15:58:47 node1 systemd[1377]: Reached target Sockets.
Jan 18 15:58:47 node1 systemd[1377]: Reached target Paths.
Jan 18 15:58:47 node1 systemd[1377]: Reached target Basic System.
Jan 18 15:58:47 node1 systemd[1377]: Reached target Default.
Jan 18 15:58:47 node1 systemd[1377]: Startup finished in 98ms.
Jan 18 15:58:47 node1 systemd[1]: Started User Manager for UID 1000.
Jan 18 16:09:01 node1 CRON[1490]: (root) CMD ( [ -x /usr/lib/php/sessionclean ] && /usr/lib/php/sessionclean)
Jan 18 16:17:01 node1 CRON[1576]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
Jan 18 16:39:01 node1 CRON[1730]: (root) CMD ( [ -x /usr/lib/php/sessionclean ] && /usr/lib/php/sessionclean)
You will see the last 10 lines of the log file, but note that tail does not exit. Now open another terminal, and login to your Linux machine (don’t close the terminal running tail). You should see at least one more line appended to the output, similar to below.
Jan 18 16:46:17 node1 systemd[1]: Started Session 8 of user network.
tail will keep showing the last 10 lines of the file, even as the file is updated. To stop tail use the Ctrl-C key combination.
less, head and tail are useful for viewing a selected part of a text file. However they can go beyond text files. Since many commands output text, you can combine those commands with less, head or tail to view a selected part of the output. Combining two commands is performed using pipes. While pipes are explained in detail in Section 4.6, here we introduce a simple and common example.
Consider the output of the ls command, which in some cases be quite long, especially when used with the -1 option which shows one entry per line. To scroll through the output we can perform the ls -1 command and pipe (the vertical bar, ) the output into the less command:
$ ls -1 /etc | less
acpi
adduser.conf
alternatives
apache2
apparmor
apparmor.d
apport
apt
at.deny
bash.bashrc
bash_completion.d
bindresvport.blacklist
binfmt.d
ca-certificates
ca-certificates.conf
calendar
console-setup
cron.d
cron.daily
cron.hourly
cron.monthly
crontab
cron.weekly
:
You can now scroll through the output of ls. Similarly we can see the last 5 lines of output:
$ ls -1 /etc | tail -n 5
vtrgb
wgetrc
X11
xdg
xml
Using pipes () to combine commands is covered in Section 4.6.
So far we have only viewed existing files. Now we will show some very basic ways to create files. Full text editors, which will be more practical in many cases, are covered in Section 4.4.3.
To create an empty file use touch:
$ touch myfile.txt
$ ls -l myfile.txt
-rw-rw-r-- 1 network network 0 Jan 18 16:52 myfile.txt
The output of ls indicates the file is 0 Bytes in length. Not much use yet.
Before we put some text into a file, lets introduce echo, a command that simply displays the string passed as parameter as output:
$ echo "hello"
hello
$ echo "My name is ..."
My name is ...
Now a powerful concept: redirection. While most of the commands we have seen so far output to the screen (such as echo), we can tell the command to instead redirect the output to a file. To perform output redirection, follow the command with the greater than sign () followed by the name of a desired output file:
$ echo "hello" > myfile.txt
$ cat myfile.txt
hello
$ ls -l myfile.txt
-rw-rw-r-- 1 network network 6 Jan 22 09:13 myfile.txt
Rather than echo displaying “hello” on the screen, it writes to the file myfile.txt. Note that the output file does not need to exist (a new one will be created), and that the contents are overwritten. To append to a file, use two greater than signs ():
$ echo "there" >> myfile.txt
$ cat myfile.txt
hello
there
$ ls -l myfile.txt
-rw-rw-r-- 1 network network 12 Jan 22 09:14 myfile.txt
Redirection is covered in more depth in Section 4.6.
While these basic methods for creating text files may some inconvenient for writing a large file, they are useful for automating file creation. Section 4.4.3 covers more traditional text editors.
There are different text editors available in Linux, some very simple and others with advanced features resembling Integrated Development Environments (IDEs). Two text editors commonly installed in Linux are vi and nano, with the former most powerful and installed on almost all systems, and the latter being the simplest to get started with. We will start with nano.
To open an existing file or start with a new named file:
$ nano demofile.txt
This brings up a screen with a menu bar at the top and two rows of commands at the bottom. In the middle you write your text. We don’t cover the details of using nano here (press Ctrl-G to get help) but some useful things to know to get started are:
While vi is a more powerful text editor, it is quite different than what most people are used to with GUI based text editors (e.g. Notepad in Windows). You can find many tutorials online to get started with vi.
Other text editors include emacs, which is a powerful alternative to vi, and gedit, which is more typical like Notepad. However gedit requires a GUI in Linux.
Video: nano for Text Editing in Ubuntu (5 min; Mar 2018)
Typing commands, files and directories can be time consuming, and also error prone. Typing a long command, executing it, and then realising a spelling mistake can be very annoying. Even worse if a mistake causes unexpected consequences (e.g. deleting the wrong file). Bash has numerous shortcuts that allow you to be more efficient when typing commands. The following are valuable for getting started.
The Bash manual describes many more keyboard shortcuts in the Bindable Readline Commands section.
Video: Redirection and pipes including grep, whoami, , cut (25 min; July 2016)
Video: Linux Command Line: Processes (29 min; Jul 2016)
Video: Searching for and in files including locate, find, which (6 min; July 2016)
Video: File operations including cat, head, tail, cp, mv, rm (10 min; July 2016)
For more examples, mainly of the same commands and concepts introduced in the previous sections, a series of videos are available.
If you just need to use the command line for virtnet (e.g. to achieve specific networking or security tasks), then the following two videos provide a short introduction to the basics.
Video: Linux Commands for virtnet 1: Files and Directories, including cd, ls, pwd, mkdir, rmdir, cp, mv. (11 min Feb 2017)
Video: Linux Commands for virtnet 2: Text Files, including grep, redirection and pipes (8 min; Feb 2017)
If you want to see almost all of the commands covered in this chapter, then the following is a series of eight videos taken from an old lab class.
Video: Linux Command Line 1: Directory operations including pwd, cd, ls, mkdir, rmdir, TAB autocomplete (29 min; Jul 2016)
Video: Linux Command Line 2: File operations including touch, nano, wc, man (8 min; Jul 2016)
Video: Linux Command Line 3: File operations including cat, less, head, tail, cp, mv, rm (10 min; Jul 2016)
Video: Linux Command Line 4: Finding files including locate, find, which (6 min; Jul 2016)
Video: Linux Command Line 5: Redirection and pipes including grep, whoami, , cut (24 min; Jul 2016)
Video: Linux Command Line 6: Processes including Ctrl-C (kill), yes, Ctrl-Z (suspend), jobs, fg, bg, ps, kill, top (29 min; Jul 2016)
Video: Linux Command Line 7: Users including whoami, /etc/passwd, /etc/shadow, su, sudo (18 min; Jul 2016)
Video: Linux Command Line 8: File Permissions including groups, chown, chgrp, chmod (15 min; Jul 2016)