Sie sind auf Seite 1von 714

1.

1 Introduction
⁠ The definition of the word Linux depends on the context in which it is used. Technically speaking, Linux is the
kernel of the system, which is the central controller of everything that happens on the computer. People that say
their computer “runs Linux” are usually referring to the kernel and suite of tools that come with it (called a
distribution). If someone says they have Linux experience, it might refer to configuring systems, running web
servers, or any number of other services and programs that operate on top of Linux. Over time, Linux
administration has evolved to encompass just about every task that a modern business, educational, or government
institution might use in their daily operations.

What about UNIX? UNIX was originally an operating system developed at AT&T Bell Labs in the 1970s. It has
been modified and forked (that is, people modified it, and those modifications served as the basis for other systems)
such that now there are many different variants of UNIX. However, UNIX is now both a trademark and a
specification, owned by an industry consortium called the Open Group. Only software that has been certified by
the Open Group may call itself UNIX. Despite adopting most if not all of the requirements of the UNIX
specification, Linux has not been certified, so Linux really isn’t UNIX! It’s just… UNIX-like.

Note

Much of the early material in this chapter is very similar to what can be found in NDG Linux Essentials. If you
have already taken that course, you can use this as an opportunity to refresh your knowledge or feel free to skip
ahead a few pages.
1.1.1 Role of the Kernel
The three main components of an operating system are the kernel, shell, and filesystem. The kernel of the operating
system is like an air traffic controller at an airport. The kernel dictates which program gets which pieces of
memory, it starts and kills programs, it interprets instructions given to it by the user, and it handles more common
and simple tasks such as displaying text on a monitor. When an application needs to write to disk, it must ask the
kernel to complete the write operation.

The kernel also handles the switching of applications. A computer will have one or more CPUs and a finite amount
of memory. The kernel takes care of unloading tasks and loading new tasks, and can manage multiple tasks across
multiple CPUs. When the current task has run a sufficient amount of time, the CPU pauses the task so that another
may run. This is called preemptive multitasking. Multitasking means that the computer is doing several tasks at
once, and preemptive means that the kernel is deciding when to switch focus between tasks. With the tasks so
rapidly switching, it appears that the computer is doing many things at once.

Each application may think it has a large block of memory on the system, but it is the kernel that maintains this
illusion; remapping smaller blocks of memory, sharing blocks of memory with other applications, or even
swapping out blocks that haven’t been used in a while to the disk.
⁠ When the computer starts up, it loads a small piece of code called a bootloader. The bootloader’s job is to give you
a choice (if configured) of options to load one or more versions of Linux, or even other operating systems, and then
to load the kernel of the chosen option and get it started. If you are more familiar with operating systems such as
Microsoft Windows or Apple’s OS X, you probably never see the bootloader, but in the UNIX world, it’s usually
visible so that you can adjust the way your computer boots.

The bootloader loads the Linux kernel and then transfers control. Linux then continues with running the programs
necessary to make the computer useful, such as connecting to the network or starting a web server.

1.1.2 Applications
Like an air traffic controller, the kernel is not useful without something to control. If the kernel is the tower, the
applications are the airplanes. Applications make requests to the kernel and receive resources, such as memory,
CPU, and disk, in return. The kernel also abstracts the complicated details away from the application. The
application doesn’t know if the block of a disk is on a solid-state drive from manufacturer A, a spinning metal hard
drive from manufacturer B, or even a network file share. Applications just follow the kernel’s Application
Programming Interface (API) and in return don’t have to worry about the implementation details

When we, as users, think of applications, we tend to think of word processors, web browsers, and email clients.
The kernel doesn’t care if it is running something that’s user-facing, a network service that talks to a remote
computer, or an internal task. So, from this, we get an abstraction called a process. A process is just one task that is
loaded and tracked by the kernel. An application may even need multiple processes to function, so the kernel takes
care of running the processes, starting and stopping them as requested, and handing out system resources.

1.1.3 Role of Open Source


Software projects take the form of source code, which is a human-readable set of computer instructions. The
source code may be written in any of hundreds of different programming languages. The Linux kernel is mostly
written in C, which is a language that shares history with the original UNIX.

Source code is not understood directly by the computer, so it must be compiled into machine instructions by a
compiler. The compiler gathers all of the source files and generates something that can be run on the computer,
such as the Linux kernel.

Historically, most software has been issued under a closed-source license, meaning that you get the right to use the
machine code, but cannot see the source code. Often the license specifically says that you will not attempt to
reverse engineer the machine code back to source code to figure out what it does!

Open source takes a source-centric view of software. The open source philosophy is that you have a right to obtain
the software and to modify it for your own use. Linux adopted this philosophy to great success.

In 1991, Linux started out as a hobby project by Linus Torvalds. He made the source freely available, allowing
others to join in and shape this fledgling operating system. It was not the first system to be developed by a
volunteer group, but since it was built from scratch, early adopters could influence the project’s direction. People
took the source, made changes, and shared them back with the rest of the group, greatly accelerating the pace of
development, and ensuring mistakes from other operating systems were not repeated.

The Linux kernel is licensed under the GNU Public License (GPL) which requires you to make changes available.
This guarantees that those who use the code will also contribute to the greater good by making those changes
available to anyone.
Alongside this, was the GNU project (GNU’s, not UNIX). While GNU (pronounced "guh-noo”) was building their
own operating system, they were far more successful at building the tools that go along with a UNIX operating
system, such as the compilers and user interfaces. The source was all freely available, so Linux was able to target
their tools and provide a complete system. As such, most of the tools that are part of the Linux system come from
these GNU tools.

There are many different variants on open source. However, all agree that you should have access to the source
code, but they differ in how you can, or in some cases, must, redistribute changes.

1.1.4 Linux Distributions


Take the Linux kernel and the GNU tools, add some more user-facing applications like an email client, word
processors and other programs and you have a full Linux system. People started bundling all this software into a
distribution almost as soon as Linux became usable. The distribution takes care of setting up the storage, installing
the kernel, and installing the rest of the software. The full-featured distributions also include tools to manage the
system and a package manager to help you add and remove software after the installation is complete.

Like UNIX, there are many different flavors of distributions. These days, there are distributions that focus on
running servers, desktops, or even industry-specific tools like electronics design or statistical computing. The
major players in the market can be traced back to either Red Hat or Debian. The most visible difference is the
software package manager, though you will find other differences on everything from file locations to political
philosophies.

Red Hat started out as a simple distribution that introduced the Red Hat Package Manager (RPM) based on the
.rpm file format. The developer eventually formed a company around it, which tried to commercialize a Linux
desktop for business. Over time, Red Hat started to focus more on the server applications such as web and file
serving and released Red Hat Enterprise Linux, which was a paid service on a long release cycle. The release cycle
dictates how often software is upgraded. A business may value stability and want long release cycles, a hobbyist or
a startup may want the latest software and opt for a shorter release cycle. To satisfy the latter group, Red Hat
sponsors the Fedora Project which makes a personal desktop comprising the latest software but still built on the
same foundations as the enterprise version.

Because everything in Red Hat Enterprise Linux is open source, a project called CentOS came to be, that
recompiled all the RHEL packages and gave them away for free. CentOS and others like it (such as Scientific
Linux) are largely compatible with RHEL and integrate some newer software, but do not offer the paid support
that Red Hat does.

Debian is more of a community effort, and as such, also promotes the use of open source software and adherence
to standards. Debian came up with its own package management system based on the .deb file format. While Red
Hat leaves non-Intel and AMD platform support to derivative projects, Debian supports many of these platforms
directly.

Ubuntu is the most popular Debian derived distribution. It is the creation of Canonical, a company that was made
to further the growth of Ubuntu and makes money by providing support.
1.2 Hardware Platforms
Linux started out as something that would only run on a computer like Linus’: a 386 with a specific hard drive
controller. The range of support grew, as support for other hardware was built. Eventually, Linux started
supporting other chipsets, including hardware that was made to run competitive operating systems!

The types of hardware grew from the humble Intel chip up to supercomputers. Smaller sized Linux-supported chips
were eventually developed to fit in consumer devices (called embedded devices). The support for Linux became
ubiquitous such that it is often easier to build hardware to support Linux and then use Linux as a springboard for
your custom software than it is to build the custom hardware and software from scratch.

Eventually, cellular phones and tablets adopted Linux. A company, later bought by Google, came up with the
Android platform which is a bundle of Linux and the software necessary to run a phone or tablet. This means that
the effort to get a phone to market is significantly less. Instead of long development on a new operating system,
companies can spend their time innovating on the user-facing software. Android is now one of the market leaders
in the phone and tablet space.

Aside from phones and tablets, Linux can be found in many consumer devices. Wireless routers often run Linux
because it has a rich set of network features. The TiVo is a consumer digital video recorder built on Linux. Even
though these devices have Linux at the core, the end users don’t have to know. The custom software interacts with
the user and Linux provides the stable platform

1.3 Shell
An operating system provides at least one shell that allows the user to communicate with the operating system. A
shell is sometimes called an interpreter because it takes the commands that a user issues and interprets them into a
form that the kernel can then execute on the hardware of the computer. The two most common types of shells are
the Graphical User Interface (GUI) and Command Line Interface (CLI).

Microsoft Windows™ typically uses a GUI shell, primarily using the mouse to indicate what you want to
accomplish. While using an operating system in this way might be considered easy, there are many advantages to
using a CLI, including:

 Command Repetition: In a GUI shell, there is no easy way to repeat a previous command. In a CLI there
is an easy way to repeat (and also modify) a previous command.
 Command Flexibility: The GUI shell provides limited flexibility in the way the command executes. In a
CLI, options are specified with commands to provide a more flexible and powerful interface.
 Resources: A GUI shell typically uses a relatively large amount of resources (RAM, CPU, etc.). This is
because a great deal of processing power and memory is needed to display graphics. By contrast, a CLI
uses very little system resources, allowing more of these resources to be available to other programs.
 Scripting: In a GUI shell, completing multiple tasks often requires multiple mouse clicks. With a CLI, a
script can be created to execute many complex operations by just typing the name of the script. A script is a
series of commands placed into a single file. When executed, the script runs all of the commands in the file.
 Remote Access: While it is possible to execute commands in a GUI shell remotely, this feature isn't
typically set up by default. With a CLI shell, gaining access to a remote machine is easy and typically
available by default.
 Development: Normally a GUI-based program takes more time for the developers to create when
compared to CLI-based programs. As a result, there are typically thousands of CLI programs on a typical
Linux OS while only a couple hundred programs in a primarily GUI-based OS like Microsoft Windows.
More programs mean more power and flexibility.
The Microsoft Windows operating system was designed to primarily use the GUI interface because of its
simplicity, although there are several CLI interfaces available, too. For simple commands, there is the Run dialog
box, where you can type or browse to the commands that you want to execute. If you want to type multiple
commands or if you want to see the output of the command, you can use the Command Prompt, also called the
DOS shell. Recently, Microsoft realized how important it is to have a powerful command line environment and
introduced Powershell.

Like Windows, Linux also has both a CLI and GUI. Unlike Windows, Linux lets you easily change the GUI shell
(also called the desktop environment) that you want to use. The two most common desktop environments for Linux
are GNOME and KDE; however, there are many other GUI shells available.

To access the CLI from within the GUI on a Linux operating system, the user can open a software program called a
terminal. Linux can also be configured only to run the CLI without the GUI; this is typically done on servers that
don't require a GUI, primarily to free up system resources.

1.3.1 Bash Shell


Not only does the Linux operating system provide multiple GUI shells, but also multiple CLI shells are available.
Normally, these shells are derived from one of two older UNIX shells: The Bourne Shell and the C Shell. In fact,
the Bash shell, a default CLI shell used in modern Linux operating systems, derives its name from the Bourne
Shell: Bourne Again SHell. In this course, you will focus upon learning how to use the CLI for Linux with the
Bash shell, arguably the most popular CLI in Linux.

Users interact with a system by executing commands which are interpreted by the shell and transformed into
actions by the kernel. These actions may or may not return information to the command line depending on the
command issued and its result. For example, when the ls command is typed into the console, it will return the
contents of whichever directory the user is currently in.

sysadmin@localhost:~$ ls
Desktop Documents Downloads Music Pictures Public Templates Videos

A command can be followed by options that modify how the command is executed, and arguments, that are
typically the files to be operated on:

command [options] [arguments]

Note

Some commands require options and arguments while others, like ls, can be used alone.

Commands entered are considered standard input, (stdin) whether they are typed by an operator, entered by a
script, or as the result of another command. Text returned to the console can be either standard output (stdout), or
standard error (stderr). This deceptively simple method of communicating with the Linux kernel is the basis for
almost every interaction a Linux administrator has with her systems. It can be confusing at first for users who have
only experienced GUI interfaces, but ultimately it gives the experienced operator far more power than any
graphical interface can.

This deceptively simple method of communicating with the Linux kernel is the basis for almost every interaction a
Linux administrator has with their systems. It can be confusing at first for users who have only experienced GUI
interfaces, but ultimately it gives the experienced operator far more power than any graphical interface can.
The Bash shell has numerous built-in commands and features that you will learn including:

 Aliases: Give a command a different or shorter name to make working with the shell more efficient.
 Re-Executing Commands: To save retyping long command lines.
 Wildcard Matching: Uses special characters like ?, *, and [] to select one or more files as a group for
processing.
 Input/Output Redirection: Uses special characters for redirecting input, < or <<, and output, >.
 Pipes: Used to connect one or more simple commands to perform more complex operations.
 Background Processing: Enables programs and commands to run in the background while the user
continues to interact with the shell to complete other tasks.

The shell that your user account uses by default is set at the time your user account was created. By default, many
Linux distributions use Bash for a new user's shell. Typically, a user learns one shell and sticks with that shell;
however, after you have learned the basics of Linux, you may want to explore the features of other shells.

Consider This

An administrator can use the usermod command to specify a different default shell after the account has been
created.

As a user, you can use the chsh command to change your default shell. Most of the time the default shell a system
offers will be adequate for basic tasks. Occasionally, an administrator will want to change the shell to have access
to more advanced features, or simply because they are more familiar with a different shell and the features it offers.
On systems that are near capacity, it may be advisable not to change shells as it could require additional resources
and slow processing for all users.

The location where the system stores the default shell for user accounts is the /etc/passwd file.

1.3.2 Accessing the Shell


How you access the command line shell depends on whether your system provides a GUI login or CLI login:

 GUI-based systems: If the system is configured to present a GUI, then you will need to find a software
application called a Terminal. In the GNOME desktop environment, the Terminal application can be started
by clicking the Applications menu, then the System Tools menu and Terminal icon.
 CLI-based systems: Many Linux systems, especially servers, are not configured to provide a GUI by
default, so they present a CLI instead. If the system is configured to present a CLI, then the system runs a
terminal application automatically after you log in.

In the early days of computing, terminal devices were large machines that allowed users to provide input through a
keyboard and displayed output by printing on paper. Over time, terminals evolved and their size shrank down into
something that looked similar to a desktop computer with a video display monitor for output and a keyboard for
input.

Ultimately, with the introduction of personal computers, terminals became software emulators of the actual
hardware. Whatever you type in the terminal is interpreted by your shell and translated into a form that can then be
executed by the kernel of the operating system.
If you are in a remote location, then pseudo-terminal connections can also be made across the network using
several techniques. Insecure connections could be made using protocols such as telnet and programs such as
rlogin, while secure connections can be established using programs like putty and protocols such as ssh.

1.4 Filesystems
In addition to the kernel and the shell, the other major component of any operating system is the filesystem. To the
user, a filesystem is a hierarchy of directories and files with the root / directory at the top of the directory tree. To
the operating system, a filesystem is a structure created on a disk partition consisting of tables defining the
locations of directories and files.

In this course, you will learn about the different Linux filesystems, filesystem benefits and how to create and
manage filesystems using commands.
NDG Introduction to Linux I - Chapter 2: Using the Shell

2.1 Command Line Interface


Most consumer operating systems are designed to shield the user from the “ins and outs” of the CLI. The Linux
community is different in that it positively celebrates the CLI for its power, speed, and ability to accomplish a vast
array of tasks with a single command line instruction.

When a user first encounters the CLI, they can find it challenging because it requires memorizing a dizzying
amount of commands and their options. However, once a user has learned the structure of how commands are used,
where the necessary files and directories are located, and how to navigate the hierarchy of a file system, they can
be immensely productive. This capability provides more precise control, greater speed, and the ability to automate
tasks more easily through scripting.

Furthermore, by learning the CLI, a user can easily be productive almost instantly on ANY flavor or distribution of
Linux, reducing the amount of time needed to familiarize themselves with a system because of variations in a GUI.

2.2 Commands
What is a command? The simplest answer is that a command is a software program that when executed on the
command line, performs an action on the computer.

When you consider a command using this definition, you are really considering what happens when you execute a
command. When you type in a command, a process is run by the operating system that can read input, manipulate
data, and produce output. From this perspective, a command runs a process on the operating system, which then
causes the computer to perform a job.

⁠However, there is another way of looking at what a command is: look at its source. The source is where the
command "comes from" and there are several different sources of commands within the shell of your CLI:

 Internal Commands: Also called built-in commands, these commands are built-in to the shell itself. A
good example is the cd (change directory) command as it is part of the Bash shell. When a user types the cd
command, the Bash shell is already executing and knows how to interpret that command, requiring no
additional programs to be started.
 External Commands: These commands are stored in files that are searched by the shell. If you type the ls
command, then the shell searches through a predetermined list of directories to try to find a file named ls
that it can execute. These commands can also be executed by typing the complete path to the command.
 Aliases: An alias can override a built-in command, function, or a command that is found in a file. Aliases
can be useful for creating new commands built from existing functions and commands.
 Functions: Functions can also be built using existing commands to either create new commands, override
commands built-in to the shell or commands stored in files. Aliases and functions are normally loaded from
the initialization files when the shell first starts, discussed later in this section.
2.2.1 External Commands
Commands that are stored in files can be in several forms that you should be aware of. Most commands are written
in the C programming language, which is initially stored in a human-readable text file. These text source files are
then compiled into computer-readable binary files, which are then distributed as the command files.

Users who are interested in seeing the source code of compiled, GPL licensed software can find it through the sites
where it originated. GPL licensed code also compels distributors of the compiled binaries, such as RedHat and
Debian, to make the source code available. Often it is found in the distributors’ repositories.

Note

It is possible to view available software packages, binary programs that can be installed directly at the command
line. Type the following command into the terminal to view the available source packages (source code that can be
modified before it’s compiled into binary programs) for the GNU Compiler Collection:

sysadmin@localhost:~$ apt-cache search gcc | grep source


gcc-4.8-source - Source of the GNU Compiler Collection
gcc-5-source - Source of the GNU Compiler Collection
gcc-6-source - Source of the GNU Compiler Collection
gcc-7-source - Source of the GNU Compiler Collection
gcc-8-source - Source of the GNU Compiler Collection
gcc-arm-none-eabi-source - GCC cross compiler for ARM Cortex-A/R/M processors (source)

The apt-cache command allows us to display information from the APT database cache. It is commonly used to
find information about programs you wish to install and the components required to make them work.

Although there are a tremendous number of free and open source programs available, quite often the binary code
you will need as a Linux administrator won’t exist for the particular distribution you are running. Since open
source licensing gives you access to the code for these programs, one of your tasks will be compiling, and
sometimes modifying that code into executable programs that can be installed on the systems you manage. The
Free Software Foundation (FSF) distributes the GNU Compiler Collection (GCC) to make this process easier. The
GCC provides a compiler system (the special programs used to convert source code into usable binary programs)
with front ends for many different programming languages. In fact, the FSF doesn’t limit these tools to just Linux.
There are versions of the GCC that run on Unix, Windows, MacOS, and many other systems including specific
microcontroller environments.

Linux package management will be covered in greater detail later in the course.

Note

Command files can also contain human-readable text in the form of script files. A script file is a collection of
commands that is typically executed at the command line.

The ability to create your own script files is a very powerful feature of the CLI. If you have a series of commands
that you regularly find yourself typing in order to accomplish some task, then you can easily create a Bash shell
script to perform these multiple commands by typing just one command: the name of your script file. You simply
need to place these commands into a file and make the file executable.
2.2.2 Aliases
An alias can be used to map longer commands to shorter key sequences. When the shell sees an alias being
executed, it substitutes the longer sequence before proceeding to interpret commands.

For example, the command ls -l is commonly aliased to l or ll. Because these smaller commands are easier to
type, it becomes faster to run the ls -l command line.

To determine what aliases are set on the current shell use the alias command:

sysadmin@localhost:~$ alias
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'

The aliases from the previous examples were created by initialization files. These files are designed to make the
process of creating aliases automatic.

New aliases can be created using the following format, where name is the name to be given the alias and command
is the command to be executed when the alias is run.

alias name=command

For example, the cal 2030 command displays the calendar for the year 2030. Suppose you end up running this
command often. Instead of executing the full command each time, you can create an alias called mycal and run the
alias, as demonstrated in the following graphic:
sysadmin@localhost:~$ alias mycal="cal 2019"
sysadmin@localhost:~$ mycal
2019
January February March
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 3 4 5 1 2 1 2
6 7 8 9 10 11 12 3 4 5 6 7 8 9 3 4 5 6 7 8 9
13 14 15 16 17 18 19 10 11 12 13 14 15 16 10 11 12 13 14 15 16
20 21 22 23 24 25 26 17 18 19 20 21 22 23 17 18 19 20 21 22 23
27 28 29 30 31 24 25 26 27 28 24 25 26 27 28 29 30
31

April May June


Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 3 4 5 6 1 2 3 4 1
7 8 9 10 11 12 13 5 6 7 8 9 10 11 2 3 4 5 6 7 8
14 15 16 17 18 19 20 12 13 14 15 16 17 18 9 10 11 12 13 14 15
21 22 23 24 25 26 27 19 20 21 22 23 24 25 16 17 18 19 20 21 22
28 29 30 26 27 28 29 30 31 23 24 25 26 27 28 29
30

October November December


Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 3 4 5 1 2 1 2 3 4 5 6 7
6 7 8 9 10 11 12 3 4 5 6 7 8 9 8 9 10 11 12 13 14
13 14 15 16 17 18 19 10 11 12 13 14 15 16 15 16 17 18 19 20 21
20 21 22 23 24 25 26 17 18 19 20 21 22 23 22 23 24 25 26 27 28
27 28 29 30 31 24 25 26 27 28 29 30 29 30 31

Aliases created this way only persist while the shell is open. Once the shell is closed, the new aliases are lost. Additionally,
each shell has its own aliases, so, aliases created in one shell won’t be available in a new shell that’s opened.

2.3 Basic Command Syntax


To execute a command, the first step is to type the name of the command. Click in the terminal on the right. Type
ls and hit Enter. The result should resemble the example below:

sysadmin@localhost:~$ ls
Desktop Documents Downloads Music Pictures Public Templates Videos

Note

By itself, the ls command lists files and directories contained in the current working directory. At this point, you
shouldn't worry too much about the output of the command, but instead, focus on understanding how to format and
execute commands.

The ls command will be covered in greater detail later in the course.

Many commands can be used by themselves with no further input. Some commands require additional input to run
correctly. This additional input comes in two forms: options and arguments. Commands typically follow a simple
pattern of syntax:
command [options…] [arguments…]

When typing a command that is to be executed, the first step is to type the name of the command. The name of the
command is often based on what the command does or what the developer who created the command thinks will
best describe the command's function.

For example, the ls command displays a listing of information about files. Associating the name of the command
with something mnemonic for what it does may help you to remember commands more easily.

Keep in mind that every part of the command is normally case-sensitive, so LS is incorrect and will fail, but ls is
correct and will succeed.

2.3.1 Specifying Arguments


command [options] [arguments]

An argument can be used to specify something for the command to act upon. Following a command, any desired
arguments are allowed or are required depending on the command. For example, the touch command is used to
create empty files or update the timestamp of existing files. It requires at least one argument to specify the file
name to act upon.

touch FILE...
sysadmin@localhost:~$ touch newfile

The ls command, on the other hand, allows for a path and/or file name to be specified as an argument, but it’s not
required.

ls [FILE]...

An example of a scenario where an argument is allowed but not required is the use of the ls command. If the ls
command is used without an argument, it will list the contents of the current directory:

sysadmin@localhost:~$ ls
Desktop Documents Downloads Music Pictures Public Templates Videos

If the ls command is given the name of a directory as an argument, it will list the contents of that directory. In the following
example, the /etc/ppp directory is used as an argument; the resulting output is a list of files contained in the /etc/ppp
directory:

sysadmin@localhost:~$ ls /etc/ppp
ip-down.d ip-up.d

The ls command also accepts multiple arguments. To list the contents of both the /etc/ppp and /etc/ssh directories,
pass them both as arguments:
sysadmin@localhost:~$ ls /etc/ppp /etc/ssh
/etc/ppp:
ip-down.d ip-up.d

/etc/ssh:
moduli ssh_host_ecdsa_key ssh_host_rsa_key
ssh_config ssh_host_ecdsa_key.pub ssh_host_rsa_key.pub
ssh_host_dsa_key ssh_host_ed25519_key ssh_import_id
ssh_host_dsa_key.pub ssh_host_ed25519_key.pub sshd_config

Some commands, like the cp command (copy file) and the mv command (move file), always require at least two
arguments: a source file and a destination file.

cp SOURCE... DESTINATION

In the example below, we will copy the public ssh rsa key called ssh_host_rsa_key.pub which resides in the
/etc/ssh directory, to the /home/sysadmin/Documents directory and verify that it is there:

sysadmin@localhost:~$ cp /etc/ssh/ssh_host_rsa_key.pub /home/sysadmin/Documents


sysadmin@localhost:~$ ls ~/Documents
School alpha.txt linux.txt profile.txt
Work animals.txt longfile.txt red.txt
adjectives.txt food.txt newhome.txt spelling.txt
alpha-first.txt hello.sh numbers.txt ssh_host_rsa_key.pub
alpha-second.txt hidden.txt os.csv words
alpha-third.txt letters.txt people.csv

Consider This

An ssh rsa key is a file that contains an authentication credential (similar to a password) used to verify the identity
of a machine that is being logged into using the ssh command. The ssh command allows users on a system to
connect to another machine across a network, log in, and then perform tasks on the remote machine.

The ssh command is covered in greater detail later in the NDG Introduction to Linux 2.
2.3.1.1 Quoting
Arguments that contain unusual characters like spaces or non-alphanumeric characters will usually need to be
quoted, either by enclosing them within double quotes or single quotes. Double quotes will prevent the shell from
interpreting some of these special characters; single quotes prevent the shell from interpreting any special
characters.

In most cases, single quotes are considered safer and should probably be used whenever you have an argument that
contains characters that aren't alphanumeric.

To understand the importance of quotes, consider the echo command. The echo command displays text to the
terminal and is used extensively in shell scripting.

echo [STRING]...

Consider the following scenario in which you want to list the contents of the current directory using the ls
command and then use the echo command to display the string hello world!! on the screen.

You might first try the echo command without any quotes, unfortunately without success:

sysadmin@localhost:~$ ls
sysadmin@localhost:~$ echo hello world!!
echo hello worldls
hello worldls

Using no quotes failed because the shell interprets the !! characters as special shell characters; in this case, they
mean "replace the !! with the last command that was executed". In this case, the last command was the ls
command, so ls replaced !! and then the echo command displayed hello worldls to the screen.

You may want to try the double quote " characters to see if they will block the interpretation (or expansion) of the
exclamation !! characters. The double quotes block the expansion of some special characters, but not all of them.
Unfortunately, double quotes do not block the expansion of the exclamation !! characters:

sysadmin@localhost:~$ ls
sysadmin@localhost:~$ echo "hello world!!"
echo "hello worldls"
hello worldls

Using double quotes preserves the literal value of all characters that they enclose except metacharacters such as the
$ dollar sign character, the ` backquote character, the \ backslash character and the ! exclamation point character.
These characters, called wild cards, are symbol characters that have special meaning to the shell. Wild card
characters are used for globbing and are interpreted by the shell itself before it attempts to run any command. Glob
characters are useful because they allow you to specify patterns that make it easier to match file names in the
command line. For example, the command ls e?? would list all files in that directory that start with an e and have
any two characters after it. However, because glob characters are interpreted differently by the shell, they need to
be enclosed appropriately to be interpreted literally.
Note

Globbing will be covered in greater detail later in the course.

If you enclose text within the ' single quote characters, then all characters have their literal meaning:

sysadmin@localhost:~$ ls
sysadmin@localhost:~$ echo 'hello world!!'
hello world!!

2.3.2 Options
command [options] [arguments]

Options can be used with commands to expand or modify the way a command behaves. If it is necessary to add
options, they can be specified after the command name. Short options are specified with a hyphen - followed by a
single character. Short options are how options were traditionally specified.

In the following example, the -l option is provided to the ls command, which results in a long display output:

sysadmin@localhost:~$ ls -l
total 0
drwxr-xr-x 1 sysadmin sysadmin 0 Sep 18 22:25 Desktop
drwxr-xr-x 1 sysadmin sysadmin 0 Sep 18 22:25 Documents
drwxr-xr-x 1 sysadmin sysadmin 0 Sep 18 22:25 Downloads
drwxr-xr-x 1 sysadmin sysadmin 0 Sep 18 22:25 Music
drwxr-xr-x 1 sysadmin sysadmin 0 Sep 18 22:25 Pictures
drwxr-xr-x 1 sysadmin sysadmin 0 Sep 18 22:25 Public
drwxr-xr-x 1 sysadmin sysadmin 0 Sep 18 22:25 Templates
drwxr-xr-x 1 sysadmin sysadmin 0 Sep 18 22:25 Videos

Often the character is chosen to be mnemonic for its purpose, like choosing the letter l for long or r for reverse. By
default, the ls command prints the results in alphabetical order, so adding the -r option prints the results in reverse
alphabetical order.

sysadmin@localhost:~$ ls -r
Videos Templates Public Pictures Music Downloads Documents Desktop

In most cases, options can be used in conjunction with other options. They can be given as separate options like -l
-r or combined like -lr. The combination of these two options would result in a long listing output in reverse
alphabetical order:

sysadmin@localhost:~$ ls -l -r
total 0
drwxr-xr-x 1 sysadmin sysadmin 0 Sep 18 22:25 Videos
drwxr-xr-x 1 sysadmin sysadmin 0 Sep 18 22:25 Templates
drwxr-xr-x 1 sysadmin sysadmin 0 Sep 18 22:25 Public
drwxr-xr-x 1 sysadmin sysadmin 0 Sep 18 22:25 Pictures
drwxr-xr-x 1 sysadmin sysadmin 0 Sep 18 22:25 Music
drwxr-xr-x 1 sysadmin sysadmin 0 Sep 18 22:25 Downloads
drwxr-xr-x 1 sysadmin sysadmin 0 Sep 18 22:25 Documents
drwxr-xr-x 1 sysadmin sysadmin 0 Sep 18 22:25 Desktop

Multiple single options can be either given as separate options like -a -l -r or combined like -alr. The output of
all of these examples would be the same:

ls -l -a -r
ls -rla
ls -a -lr

Generally, short options can be combined with other short options in any order. The exception to this is when an
option requires an argument.

For example, the -w option to the ls command specifies the width of the output desired and therefore requires an
argument. If combined with other options, the -w option can be specified last, followed by its argument and still be
valid, as in ls -rtw 40, which specifies an output width of 40 characters. Otherwise, the -w option cannot be
combined with other options and must be given separately.

sysadmin@localhost:~$ ls -lr -w 40
total 32
drwxr-xr-x 2 sysadmin sysadmin 4096 Feb 22 16:32 Videos
drwxr-xr-x 2 sysadmin sysadmin 4096 Feb 22 16:32 Templates
drwxr-xr-x 2 sysadmin sysadmin 4096 Feb 22 16:32 Public
drwxr-xr-x 2 sysadmin sysadmin 4096 Feb 22 16:32 Pictures
drwxr-xr-x 2 sysadmin sysadmin 4096 Feb 22 16:32 Music
drwxr-xr-x 2 sysadmin sysadmin 4096 Feb 22 16:32 Downloads
drwxr-xr-x 4 sysadmin sysadmin 4096 Feb 22 16:32 Documents
drwxr-xr-x 2 sysadmin sysadmin 4096 Feb 22 16:32 Desktop

If you are using multiple options that require arguments, don't combine them. For example, the -T option, which
specifies tab size, also requires an argument. In order to accommodate both arguments, each option is given
separately:

sysadmin@localhost:~$ ls -w 40 -T 12
Desktop Music Templates
Documents Pictures Videos
Downloads Public

Some commands support additional options that are longer than a single character. Long options for commands are
preceded by a double hyphen -- and the meaning of the option is typically the name of the option, like the --all
option, which lists all files, including hidden ones. For example:

sysadmin@localhost:~$ ls --all
. .bashrc .selected_editor Downloads Public
.. .cache Desktop Music Templates
.bash_logout .profile Documents Pictures Videos

For commands that support both long and short options, execute the command using the long and short options
concurrently:
sysadmin@localhost:~$ ls --all --reverse -t
.profile Templates Music Desktop ..
.bash_logout Public Downloads .selected_editor .cache
Videos Pictures Documents .bashrc .

Commands that support long options will often also support arguments that may be specified with or without an
equal symbol (the output of both commands is the same):

ls --sort time
ls --sort=time

sysadmin@localhost:~$ ls --sort=time
Desktop Documents Downloads Music Pictures Public Templates Videos

A special option exists, the lone double hyphen -- option, which can be used to indicate the end of all options for
the command. This can be useful in some circumstances where it is unclear whether some text that follows the
options should be interpreted as an additional option or as an argument to the command.

For example, if the touch command tries to create a file called --badname:

sysadmin@localhost:~$ touch --badname


touch: unrecognized option '--badname'
Try 'touch --help' for more information.

The command tries to interpret --badname as an option instead of an argument. However, if the lone double hyphen --
option is placed before the file name, indicating that there are no more options, then the file name can successfully be
interpreted as an argument:

sysadmin@localhost:~$ touch -- --badname


sysadmin@localhost:~$ ls
--badname Documents Music Public Videos
Desktop Downloads Pictures Templates

Consider This

The file name in the previous example is considered to be bad because putting hyphens in the beginning of file
names, while allowed, can cause problems when trying to access the file. For example, using the ls command
without any options to list the path of the --badname file above, will result in an error:

sysadmin@localhost:~$ ls --badname
ls: unrecognized option '--badname'
Try 'ls --help' for more information.

To remove the --badname file from the home directory, use the rm remove command:

sysadmin@localhost:~$ rm -- --badname
The rm command will be covered in greater detail later in the course.

A third type of option exists for a select few commands. While the options used in the AT&T version of UNIX
used a single hyphen and the GNU port of those commands used two hyphens, the Berkeley Software
Distribution (BSD) version of UNIX used options with no hyphen at all.

This no hyphen syntax is fairly rare in most Linux distributions. A couple of notable commands that support the
BSD UNIX style options are the ps and tar commands; both of these commands also support the single and
double hyphen style of options.

In the terminal below, there are two similar commands, the first command is executed with a traditional UNIX
style option (with single hyphens) and the second command is executed with a BSD style option (no hyphens).

sysadmin@localhost:~$ ps -u sysadmin
PID TTY TIME CMD
79 ? 00:00:00 bash
122 ? 00:00:00 ps
sysadmin@localhost:~$ ps u
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
sysadmin 79 0.0 0.0 18176 3428 ? S 20:23 0:00 -bash
sysadmin 120 0.0 0.0 15568 2040 ? R+ 21:26 0:00 ps u

2.4 Scripts
One exception to the basic command syntax used is the exec command, which takes another command to execute
as an argument. What is special about the commands that are executed with exec is that they replace the currently
running shell.

A common use of the exec command is in what is known as wrapper scripts. If the purpose of a script is to simply
configure and launch another program, then it is known as a wrapper script.

A wrapper script often uses the following as the last line of the script to execute another program.

exec program

A script written this way avoids having a shell continue to run while the program that it launched is running, the
result is that this technique saves resources (like RAM).

Although redirection of input and output to a script are discussed in another section, it should also be mentioned
that the exec command can be used to cause redirection for one or more statements in a script.
2.5 Displaying System Information
The uname command displays system information. This command will output Linux by default when it is executed
without any options.

sysadmin@localhost:~$ uname
Linux

The uname command is useful for several reasons, including when you need to determine the name of the computer
as well as the current version of the kernel that is being used.

To display additional information about the system, you can use one of the many options available for the uname
command. For example, to display all the information about the system, use the -a option with the uname
command:

sysadmin@localhost:~$ uname -a
Linux localhost 4.4.0-72-generic #93~14.04.1-Ubuntu SMP Fri Mar 31 15:05:15 UTC
2017 x86_64 x86_64 x86_64 GNU/Linux

To display information about what kernel version the system is running, use the -r option:

sysadmin@localhost:~$ uname -r
4.4.0-72-generic

The options for the uname command are summarized below:

Short Option Long Option Prints


-a --all All information
-s --kernel-name Kernel name
-n --node-name Network node name
-r --kernel-release Kernel release
-v --kernel-version Kernel version
-m --machine Machine hardware name
-p --processor Processor type or unknown
-i --hardware-platform Hardware platform or unknown
-o --operating-system Operating system
--help Help information
--version Version information

2.6 Current Directory


One of the simplest commands available is the pwd command, which is an acronym for print working directory.
When executed without any options, the pwd command will display the name of the directory where the user is
currently located in the file system. When a user logs into a system, they are normally placed in their home
directory where files they create and control reside. As you navigate around the file system it is often helpful to
know what directory you’re in.

sysadmin@localhost:~$ pwd
/home/sysadmin

Notice our virtual machines employ a prompt that displays the current working directory, emphasized with the
color blue. In the first prompt above, the blue tilde ~ character is equivalent to /home/sysadmin, representing the
user's home directory:

sysadmin@localhost:~$

After changing directories, the new location can also be confirmed in the new prompt by using the pwd command,
and is again shown in blue:

sysadmin@localhost:~$ cd Documents/
sysadmin@localhost:~/Documents$ pwd
/home/sysadmin/Documents

To get back to the home directory after changing to a new location, use the cd change directory command without
any arguments:

sysadmin@localhost:~/Documents$ cd
sysadmin@localhost:~$

2.7 Command Information


The type command displays information about a command type. For example, if you entered type ls at the
command prompt, it will return that the ls command is actually an alias for the ls --color=auto command:

sysadmin@localhost:~$ type ls
ls is aliased to `ls --color=auto'

Using the -a option with the type command will return all locations of the files that contain a command; also called an
executable file:

sysadmin@localhost:~$ type -a ls
ls is aliased to `ls --color=auto'
ls is /bin/ls

In the output above, the /bin/ls file path is the file location of the ls command.

This command is helpful for getting information about commands and where they reside on the system. For
internal commands, like the pwd command, the type command will identify them as shell builtins

sysadmin@localhost:~$ type pwd


pwd is a shell builtin

For external commands like the ip command, the type command will return the location of the command, in this case, the
/sbin directory:
sysadmin@localhost:~$ type ip
ip is /sbin/ip

Consider This

The /bin directory contains executable programs needed for booting a system, commonly used commands, and
other programs needed for basic system functionality.

The /sbin directory also contains executable programs; mainly commands and tools designed for system
administration.

If a command does not behave as expected or if a command is not accessible, that should be, it can be beneficial to
know where the shell is finding the command.

The which command searches for the location of a command in the system by searching the PATH variable.

sysadmin@localhost:~$ which ls
/bin/ls

Note

The PATH variable contains a list of directories that are used to search for commands entered by the user.

The PATH variable will be covered in greater detail later in the course.

2.8 Command Completion


A useful tool of the Bash shell is the ability to complete commands and their arguments automatically. Like many
command line shells, Bash offers command line completion, where you type a few characters of a command (or its
file name argument) and then press the Tab key. The Bash shell will complete the command (or its file name
argument) automatically for you. For example, if you type ech and press Tab, then the shell will automatically
complete the command echo for you.

There will be times when you type a character or two and press the Tab key, only to discover that Bash does not
automatically complete the command. This will happen when you haven't typed enough characters to match only
one command. However, pressing the Tab key a second time in this situation will display the possible completions
(possible commands) available.

A good example of this would be if you typed ca and pressed Tab; then nothing would be displayed. If you
pressed Tab a second time, then the possible ways to complete a command starting with ca would be shown

sysadmin@localhost:~$ ca
cal capsh cat cautious-launcher
calendar captoinfo catchsegv
caller case catman
sysadmin@localhost:~$ ca
Another possibility may occur when you have typed too little to match a single command name uniquely. If there
are more possible matches to what you've typed than can easily be displayed, then the system will use a pager to
display the output, which will allow you to scroll through the possible matches.

For example, if you just type c and press the Tab key twice, the system will provide you with many matches that
you can scroll through:

c_rehash cksum
cal clear
calendar clear_console
caller cmp
capsh codepage
captoinfo col
case colcrt
cat colrm
catchsegv column
catman comm
cautious-launcher command
cd compgen
cfdisk complete
chage compopt
chardet3 compose
chardetect3 continue
chattr coproc
chcon corelist
chcpu cp
chfn cpan
chgpasswd cpan5.26-x86_64-linux-gnu
chgrp cpgr
chmem cpio
--More--

You may not wish to scroll through all these options; in that case, press Q to exit the pager. In a situation like this,
you should probably continue to type more characters to achieve a more refined match.

A common mistake when typing commands is to misspell the command name. Not only will you type commands
faster, but you will type more accurately if you use command completion. Using the Tab key to complete the
command automatically helps to ensure that the command is typed correctly.

Note that completion also works for arguments to commands when the arguments are file or directory names
2.9 Getting Help
As previously mentioned, UNIX was the operating system from which the foundation of Linux was built. The
developers of UNIX created help documents called man pages (short for manual page).

⁠ 

Referring to the man page for a command will provide you with the basic idea behind the purpose of the command,
as well as details regarding the options of the command and a description of its features.

2.9.1 Viewing Man Pages


To view a man page for a command, execute the man command in a terminal window.

man command

For example, the following graphic shows the partial man page for the cal command:

sysadmin@localhost:~$ man cal

CAL(1) BSD General Commands Manual CAL(1)

NAME
cal, ncal -- displays a calendar and the date of Easter

SYNOPSIS
cal [-3hjy] [-A number] [-B number] [[month] year]
cal [-3hj] [-A number] [-B number] -m month [year]
ncal [-3bhjJpwySM] [-A number] [-B number] [-s country_code] [[month]
year]
ncal [-3bhJeoSM] [-A number] [-B number] [year]
ncal [-CN] [-H yyyy-mm-dd] [-d yyyy-mm]

DESCRIPTION
The cal utility displays a simple calendar in traditional format and ncal
offers an alternative layout, more options and the date of Easter. The
new format is a little cramped but it makes a year fit on a 25x80 termi-
nal. If arguments are not specified, the current month is displayed.

The options are as follows:

-h Turns off highlighting of today.

Consider This

It is possible to print man pages from the command line. If you wanted to send a man page to a default printer from
a local machine, you would execute the following command:

man -t command | lp

The command above will not function in our virtual environment.


2.9.2 Controlling the Man Page Display
The man command uses a pager to display documents. Typically, this pager is the less command, but on some
distributions, it may be the more command. Both are very similar in how they perform and will be discussed in
more detail in a later chapter.

To view the various movement commands that are available, use the H key or Shift+H while viewing a man page.
This will display a help page.

Note

If you are working on a Linux distribution that uses the more command as a pager, your output will be different
from the partial example shown here.

Pagers will be covered in greater detail later in the course

SUMMARY OF LESS COMMANDS

Commands marked with * may be preceded by a number, N.


Notes in parentheses indicate the behavior if N is given.
A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K.

h H Display this help.


q :q Q :Q ZZ Exit.
---------------------------------------------------------------------------

MOVING

e ^E j ^N CR * Forward one line (or N lines).


y ^Y k ^K ^P * Backward one line (or N lines).
f ^F ^V SPACE * Forward one window (or N lines).
b ^B ESC-v * Backward one window (or N lines).
z * Forward one window (and set window to N).
w * Backward one window (and set window to N).
ESC-SPACE * Forward one window, but don't stop at end-of-file.
d ^D * Forward one half-window (and set half-window to N).
u ^U * Backward one half-window (and set half-window to N).

ESC-) RightArrow *Left one half screen width (or N positions).


ESC-( LeftArrow * Right one half screen width (or N positions).
F Forward forever; like "tail -f".
r ^R ^L Repaint screen.
R Repaint screen, discarding buffered input.
---------------------------------------------------
Default "window" is the screen height.
Default "half-window" is half of the screen height.
---------------------------------------------------------------------------

To exit the SUMMARY OF LESS COMMANDS, type Q.


If your distribution uses the less command, you might be a bit overwhelmed with the large number of
"commands" that are available. The following table provides a summary of the more useful commands:

Command Function
Return (or Enter) Go down one line
Space Go down one page
/term Search for term
n Find next search item
1G Go to the beginning of the page
G Go to the end of the page
h Display help
q Quit man page

2.9.3 Sections Within Man Pages


Each man page is broken into sections. Each section is designed to provide specific information about a command.
While there are common sections that you will see in most man pages, some developers also create sections that
you will only see in a specific man page.

The following table describes some of the more common sections that you will find in man pages:

NAME

Provides the name of the command and a very brief description.

NAME
ls - list directory contents

SYNOPSIS

A brief summary of the command or function's interface. A summary of how the command line syntax of the
program looks.

SYNOPSIS
ls [OPTION]... [FILE]...

DESCRIPTION

Provides a more detailed description of the command.

DESCRIPTION
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is speci-
fied.
OPTIONS

Lists the options for the command as well as a description of how they are used. Often this information is found in
the DESCRIPTION section and not in a separate OPTIONS section.

-a, --all
do not ignore entries starting with .

-A, --almost-all
do not list implied . and ..

--author
with -l, print the author of each file

-b, --escape
print C-style escapes for nongraphic characters

--block-size=SIZE
scale sizes by SIZE before printing them; e.g., '--block-size=M'
prints sizes in units of 1,048,576 bytes; see SIZE format below

FILES

Lists the files that are associated with the command as well as a description of how they are used. These files may
be used to configure the command's more advanced features. Often this information is found in the DESCRIPTION
section and not in a separate FILES section.

AUTHOR

Provides the name of the person who created the man page and (sometimes) how to contact the person.

AUTHOR
Written by Richard M. Stallman and David MacKenzie.

REPORTING BUGS

Provides details on how to report problems with the command

REPORTING BUGS
GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
Report ls translation bugs to <http://translationproject.org/team/>
COPYRIGHT

Provides basic copyright information.

COPYRIGHT
Copyright (C) 2017 Free Software Foundation, Inc. License GPLv3+: GNU
GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

SEE ALSO

Provides you with an idea of where you can find additional information. This often includes other commands that
are related to this command

SEE ALSO
Full documentation at: <http://www.gnu.org/software/coreutils/ls>
or available locally via: info '(coreutils) ls invocation'

2.9.4 Man Pages Synopsis


The SYNOPSIS section of a man page can be difficult to understand, but it is a valuable resource since it provides a
concise example of how to use the command. For example, consider an example SYNOPSIS for the cal command:

SYNOPSIS
cal [-3hjy] [-A number] [-B number] [[month] year]

The square brackets [ ] are used to indicate that this feature is not required to run the command. For example, [-
3hjy] means you can use the options -3, -h, -j, -y, but none of these options are required for the cal command to
function properly.

The second set of square brackets [-A number] allows you to ⁠specify the number of months to be added to the end
of the display.

The third set of square brackets in the [-B number] allows you to specify the number of months to be added to the
beginning of the display.

The fourth set of square brackets in the [[month] year]demonstrates another feature; it means that you can specify a
year by itself, but if you specify a month you must also specify a year.

Another component of the SYNOPSIS that might cause some confusion can be seen in the SYNOPSIS of the date
command:

SYNOPSIS
date [OPTION]... [+FORMAT]
date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]
In this SYNOPSIS there are two syntaxes for the date command. The first one is used to display the date on the
system while the second is used to set the date.

The ellipses ... following [OPTION], indicate that [OPTION] may be repeated.

Additionally, the [-u|--utc|--universal] notation means that you can either use the -u option or the --utc
option, or the --universal option. Typically, this means that all three options really do the same thing, but
sometimes this format (use of the | character) is used to indicate that the options can't be used in combination, like
a logical or.

2.9.5 Searching Within a Man Page


In order to search a man page for a term, type the / character followed by the term and hit the Enter key. The
program will search from the current location down towards the bottom of the page to try to locate and highlight
the term.

If the term is not found, or you have reached the end of the matches, then the program will report Pattern not found
(press Return). If a match is found and you want to move to the next match of the term, press N. To return to a
previous match of the term, press Shift+N.

Note

If you haven't already, notice here that pager commands are viewed on the final line of the screen.

2.9.6 Man Page Sections


Until now, we have been displaying man pages for commands. However, sometimes configuration files also have
man pages. Configuration files (sometimes called system files) contain information that is used to store information
about the operating system or services.

Additionally, there are several different types of commands (user commands, system commands, and
administration commands) as well as other features that require documentation, such as libraries and kernel
components.

As a result, there are thousands of man pages on a typical Linux distribution. To organize all of these man pages,
the pages are categorized by sections, much like each individual man page is broken into sections.
By default, there are nine sections of man pages:

 Executable programs or shell commands


 System calls (functions provided by the kernel)
 Library calls (functions within program libraries)
 Special files (usually found in /dev)
 File formats and conventions, e.g. /etc/passwd
 Games
 Miscellaneous (including macro packages and conventions), e.g. man(7), groff(7)
 System administration commands (usually only for root)
 Kernel routines [non-standard]

When you use the man command, it searches each of these sections in order until it finds the first match. For
example, if you execute the command man cal, the first section (Executable programs or shell commands) is
searched for a man page called cal. If not found, then the second section is searched. If no man page is found after
searching all sections, you will receive an error message:

sysadmin@localhost:~$ man zed


No manual entry for zed

Consider This

Typically, there are many more sections than the standard nine. Custom software designers make man pages, using
non-standard section names, for example "3p".

2.9.6.1 Determining Which Section


To determine which section a specific man page belongs to, look at the numeric value on the first line of the output
of the man page. For example, if you execute the command man cal, you will see that the cal command belongs
to the first section of man pages:

sysadmin@localhost:~$ man cal

CAL(1) BSD General Commands Manual CAL(1)


2.9.6.2 Specifying a Section
In some cases, you will need to specify the section in order to display the correct man page. This is necessary
because sometimes there will be man pages with the same name in different sections.

For example, there is a command called passwd that allows you to change your password. There is also a file
called passwd that stores account information. Both the command and the file have a man page.

The passwd command is a user command, so the following command will display the man page for the passwd
command, located in the first section, by default:

sysadmin@localhost:~$ man passwd

PASSWD(1) User Commands PASSWD(1)

NAME
passwd - change user password

To specify a different section, provide the number of the section as the first argument of the man command. For example,
the command man 5 passwd will look for the passwd man page in section 5 only:

PASSWD(5) File Formats and Conversions PASSWD(5)

NAME
passwd - the password file

2.9.6.3 Searching by Name


Sometimes it isn't clear which section a man page is stored in. In cases like this, you can search for a man page by
name.

The -f option to the man command will display man pages that match, or partially match, a specific name and
provide a brief description of each man page:

sysadmin@localhost:~$ man -f passwd


passwd (1ssl) - compute password hashes
passwd (1) - change user password
passwd (5) - the password file

Note that on most Linux distributions, the whatis command does the same thing as man -f. On those distributions,
both will produce the same output.

sysadmin@localhost:~$ whatis passwd


passwd (1ssl) - compute password hashes
passwd (1) - change user password
passwd (5) - the password file
2.9.6.4 Searching by Keyword
Unfortunately, you won't always remember the exact name of the man page that you want to view. In these cases,
you can search for man pages that match a keyword by using the -k option to the man command.

For example, what if you knew you wanted a man page that displays how to change your password, but you didn't
remember the exact name? You could run the command man -k password

sysadmin@localhost:~$ man -k password


chage (1) - change user password expiry information
chgpasswd (8) - update group passwords in batch mode
chpasswd (8) - update passwords in batch mode
cpgr (8) - copy with locking the given file to the password or gr...
cppw (8) - copy with locking the given file to the password or gr...

Warning

When you use this option, you may end up with a large amount of output. The preceding command, for example,
provided over 60 results.

Recall that there are thousands of man pages, so when you search for a keyword, be as specific as possible. Using a
generic word, such as "the" could result in hundreds or even thousands of results.

Note that on most Linux distributions, the apropos command does the same thing as man -k. On those
distributions, both will produce the same output.

Consider This

Want to learn more about man pages? Execute the following command:

sysadmin@localhost:~$ man man

Sumber : https://content.netdevgroup.com/contents/lpic1-s1/294KjJnWHt/
Lab 2: Using the Shell
2.1 Introduction
In this lab, you will interact with the shell and gain an understanding of how basic commands are executed. You
will also learn how to seek help on various commands and topics.

Most Linux commands follow a simple pattern of syntax:

command [options…] [arguments…]

We will begin with simple commands and then go on to execute commands with options and arguments.

2.1.1 Step 1
You will begin by running three commands: pwd, ls, and uname. These commands, in their simplest forms, are
executed without any options or arguments.

At the shell prompt, type the pwd command and press the Enter key. The pwd command displays the directory
where the user is currently located in the file system:

sysadmin@localhost:~$ pwd
/home/sysadmin
sysadmin@localhost:~$

The working directory is the directory that your terminal window or shell is currently "in". This is also called the
current directory. This is an important consideration when you are running commands, since they may behave
differently based on the directory you are currently in.

The output of the pwd command (/home/sysadmin in this example) is called a path. The first slash represents the
root directory, the top level of the directory structure; home is a directory under the root directory, and sysadmin is
a directory under the home directory.

2.1.2 Step 2
Execute the ls command at the prompt and press Enter; this command will list the files and directories that are in
the current directory:

ls

sysadmin@localhost:~$ ls
Desktop Downloads Pictures Templates Documents Music Public Videos
sysadmin@localhost:~$
Warning: Linux commands are case sensitive. Running the ls command is not the same as LS or Ls.

Try executing LS at the prompt and notice that it will report an error:

LS
sysadmin@localhost:~$ LS
Command 'LS' not found, but can be installed with:
sudo apt install sl
sysadmin@localhost:~$

2.1.3 Step 3
The uname command displays information about the current system. Execute the following uname command and
review the output:

uname
sysadmin@localhost:~$ uname
Linux
sysadmin@localhost:~$

2.1.4 Step 4
There are two types of options for Linux commands:

a. Short options are specified with a hyphen - followed by a single character.


b. Long options for commands are preceded by a double hyphen -- and the option is typically a "full name".

The ls command can be executed using various options. Execute the following ls command with the –a option.
You will notice that with the –a option specified, the result now includes hidden files that begin with a dot .
character:

ls -a

sysadmin@localhost:~$ ls -a
. .bashrc .selected_editor Downloads Public
.. .cache Desktop Music Templates
.bash_logout .profile Documents Pictures Videos
sysadmin@localhost:~$

File names displayed in different colors denote different file types. For example, blue denotes directories and white denotes
plain files

sysadmin@localhost:~$ ls --all
. .bashrc .selected_editor Downloads Public
.. .cache Desktop Music Templates
.bash_logout .profile Documents Pictures Videos
sysadmin@localhost:~$
Warning: If you don't include two hyphens and instead use the option -all, your output will be different because you will
really be executing the ls -a -l command.

2.1.6 Step 6
Execute the ls command with the –l option; this will show the listing in long format:

ls -l

sysadmin@localhost:~$ ls -l
total 32
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Desktop
drwxr-xr-x 4 sysadmin sysadmin 4096 Mar 29 17:36 Documents
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Downloads
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Music
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Pictures
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Public
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Templates
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Videos
sysadmin@localhost:~$

2.1.7 Step 7
The –r option for the ls command produces the listing in reverse sorting order. Compare it with the output from
the ls command executed earlier.

ls -r
sysadmin@localhost:~$ ls -r
Videos Templates Public Pictures Music Downloads Documents Desktop
sysadmin@localhost:~$

2.1.8 Step 8
It is typically possible to combine more than one option in any order. Execute the following ls command with all
three options you have previously used:

ls -alr
sysadmin@localhost:~$ ls -alr
total 60
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Videos
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Templates
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Public
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Pictures
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Music
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Downloads
drwxr-xr-x 4 sysadmin sysadmin 4096 Mar 29 17:36 Documents
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Desktop
-rw-r--r-- 1 sysadmin sysadmin 74 Mar 29 17:36 .selected_editor
-rw-r--r-- 1 sysadmin sysadmin 807 Apr 4 2018 .profile
drwx------ 2 sysadmin sysadmin 4096 Apr 2 15:27 .cache
-rw-r--r-- 1 sysadmin sysadmin 3768 Mar 29 17:36 .bashrc
-rw-r--r-- 1 sysadmin sysadmin 220 Apr 4 2018 .bash_logout
drwxr-xr-x 1 root root 4096 Mar 29 17:36 ..
drwxr-xr-x 1 sysadmin sysadmin 4096 Apr 2 15:27 .
sysadmin@localhost:~$

This ls command output has the combined effect of all the options specified:

 The -a option includes files starting with a period . character.


 The -l option provides the long listing format.
 The -r option sorts the result in reverse order.

Warning: Not all options can be combined. Some options are conflicting; for example, an option to the ls
command that sorts files by name would conflict with an option that sorts files by size. Later in this lab, you will
see how to consult documentation to determine which options will conflict.

2.1.9 Step 9
Just to confirm that it has the same combined effect, specify all of the options separately. You will note that it
produces the same result:

ls -a -l -r

sysadmin@localhost:~$ ls -a -l -r
total 60
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Videos
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Templates
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Public
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Pictures
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Music
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Downloads
drwxr-xr-x 4 sysadmin sysadmin 4096 Mar 29 17:36 Documents
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Desktop
-rw-r--r-- 1 sysadmin sysadmin 74 Mar 29 17:36 .selected_editor
-rw-r--r-- 1 sysadmin sysadmin 807 Apr 4 2018 .profile
drwx------ 2 sysadmin sysadmin 4096 Apr 2 15:27 .cache
-rw-r--r-- 1 sysadmin sysadmin 3768 Mar 29 17:36 .bashrc
-rw-r--r-- 1 sysadmin sysadmin 220 Apr 4 2018 .bash_logout
drwxr-xr-x 1 root root 4096 Mar 29 17:36 ..
drwxr-xr-x 1 sysadmin sysadmin 4096 Apr 2 15:27 .
sysadmin@localhost:~$

2.1.10 Step 10
Earlier, without any options specified, the uname command had produced the output Linux. Now, execute the
uname command with various options and notice the additional information it can display:

uname –a
uname –s
uname –n
uname –m
uname –p
uname –i
uname -o

sysadmin@localhost:~$ uname -a
Linux localhost 4.4.0-141-generic #167~14.04.1-Ubuntu SMP Mon Dec 10 13:20:24 UTC 2018
x86_64 x86_64 x86_64 GNU/Linux
sysadmin@localhost:~$ uname -s
Linux
sysadmin@localhost:~$ uname -n
localhost
sysadmin@localhost:~$ uname -m
x86_64
sysadmin@localhost:~$ uname -p
x86_64
sysadmin@localhost:~$ uname -i
x86_64
sysadmin@localhost:~$ uname -o
GNU/Linux
sysadmin@localhost:~$

Note that the uname command provides various system information, including system name (-n) and processor type (-p).

2.1.11 Step 11
After the command and its options, many commands will accept one or more arguments. Commands that use
arguments may require multiple values. The -w option, when specified with the ls command, can be used to
specify the width of the screen (normally this is determined by the actual terminal window size):

ls –rw 40

sysadmin@localhost:~$ ls -rw 40
Videos Picture Documents
Templates Music Desktop
Public Downloads
sysadmin@localhost:~$
2.1.12 Step 12
Since the -w option requires an argument, it must be specified at the end of the options. Combining options where
the -w option is not at the end will not work. Execute the following command and notice the error that is reported:

ls –wr 40

sysadmin@localhost:~$ ls -wr 40
ls: invalid line width: 'r'
sysadmin@localhost:~$

2.1.13 Step 13
It is not possible to combine multiple options that require arguments. In such a case, they have to appear separately.
Execute the following to see a demonstration:

ls –w 40 –I "T*"

sysadmin@localhost:~$ ls -w 40 -I "T*"
Desktop Downloads Pictures Videos
Documents Music Public
sysadmin@localhost:~$

The ignore -I option will cause the ls command to not display specific files that match a pattern. The pattern "T*" means
any file or directory that begins with a capital T. In this case, the Templates directory was not displayed.

2.1.14 Step 14
It is possible to use both short and long options in the same command line. Execute the ls command using both
long and short options as shown below:

ls --all –rl
sysadmin@localhost:~$ ls --all -rl
total 60
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Videos
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Templates
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Public
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Pictures
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Music
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Downloads
drwxr-xr-x 4 sysadmin sysadmin 4096 Mar 29 17:36 Documents
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 29 17:36 Desktop
-rw-r--r-- 1 sysadmin sysadmin 74 Mar 29 17:36 .selected_editor
-rw-r--r-- 1 sysadmin sysadmin 807 Apr 4 2018 .profile
drwx------ 2 sysadmin sysadmin 4096 Apr 2 15:27 .cache
-rw-r--r-- 1 sysadmin sysadmin 3768 Mar 29 17:36 .bashrc
-rw-r--r-- 1 sysadmin sysadmin 220 Apr 4 2018 .bash_logout
drwxr-xr-x 1 root root 4096 Mar 29 17:36 ..
drwxr-xr-x 1 sysadmin sysadmin 4096 Apr 2 15:27 .
sysadmin@localhost:~$

2.1.15 Step 15
Similarly, it is possible to run commands with long options and with arguments. For example, execute the
following to display files with the ls command without having the file names color-coded by file type:

ls --color=never
sysadmin@localhost:~$ ls --color=never
Desktop Documents Downloads Music Pictures Public Templates Videos
sysadmin@localhost:~$

2.1.16 Step 16
A lone double hyphen indicates the end of all the options for the command. Without this double hyphen, the
following sequence of commands would not work since --badname would be considered an option to these
commands rather than a file name:

touch –d “1970-01-01 12:00:00” -- --badname


ls –-full-time -- --badname
rm -- --badname

sysadmin@localhost:~$ touch -d "1970-01-01 12:00:00" -- --badname


sysadmin@localhost:~$ ls --full-time -- --badname
-rw-rw-r-- 1 sysadmin sysadmin 0 1970-01-01 12:00:00.000000000 +0000 --badname
sysadmin@localhost:~$ rm -- --badname
sysadmin@localhost:~$

The touch command creates a file with a specific timestamp. The ls command displays this file with its timestamp. The rm
command deletes the file. Without the -- characters before the --badname file name, these commands would consider --
badname to be an option to the commands.

2.1.17 Step 17
Some commands make use of arguments that don't require any options. For example, execute the following touch
command with a file name. This will create a file. Then execute the ls command immediately after to confirm that
it has created the file:

touch lpicfile.txt
ls

sysadmin@localhost:~$ touch lpicfile.txt


sysadmin@localhost:~$ ls
Desktop Downloads Pictures Templates lpicfile.txt
Documents Music Public Videos
sysadmin@localhost:~$
2.1.18 Step 18
Similarly, you can execute the following rm command with the same file name as an argument to remove that file:

rm lpicfile.txt
ls

sysadmin@localhost:~$ rm lpicfile.txt
sysadmin@localhost:~$ ls
Desktop Documents Downloads Music Pictures Public Templates Videos
sysadmin@localhost:~$$

2.1.19 Step 19
Some commands, like the cp command, require at least two arguments. The cp command requires the source file to
copy and the destination file (where to copy the file to). For example, execute the following to copy the hosts file
from the /etc directory into the current directory with a new name of myhosts:

cp /etc/hosts myhosts
ls

2.1.20 Step 20
Arguments that contain spaces or non-alphanumeric characters need to be enclosed within single quotes ' or
double quotes ". The use of single quotes is safer because it prevents the shell from interpreting any special
characters. For example, without quotes, the shell will interpret a double exclamation point !! as repeat the last
command executed.

Note: Special characters such as the exclamation point ! character, the question mark ? character, the asterisk *
character, and more will be covered in greater detail later in the course.

Use the echo command to illustrate the effects of different quotes on special characters:

ls
echo something new!!

sysadmin@localhost:~$ ls
Desktop Downloads Pictures Templates myhosts
Documents Music Public Videos
sysadmin@localhost:~$ echo something new!!
echo something newls
something newls
The shell interprets the double exclamation point !! as the previously executed ls command and then the echo
command returns the string something newls. This time, try executing the echo command with double quotes " :

ls
echo "something new!!"

sysadmin@localhost:~$ ls
Desktop Downloads Pictures Templates myhosts
Documents Music Public Videos
sysadmin@localhost:~$ echo "something new!!"
something newls

Slightly better, but the ls command is still appended to the end of the string something new. Now use single quotes
' to let the shell know that everything inside should be interpreted literally:

ls
echo 'something new!!'

sysadmin@localhost:~$ ls
Desktop Downloads Pictures Templates myhosts
Documents Music Public Videos
sysadmin@localhost:~$ echo 'something new!!'
something new!!

This time the echo command worked properly, displaying only the data contained within single quotes

2.1.21 Step 21
Aliases serve as a nickname for another command or series of commands. As you can see by the commands that
you have executed so far, commands in the Linux command shell require a fair amount of memorizing and typing.
Aliases can help save such repetitive effort. New aliases can be created using the following format, where name is
the name to be given the alias and command is the command to be executed when the alias is run.

alias name=command

Instead of typing the command ls –alr each time, you can create an alias called l as shown below. Single quotes
' are used to ensure that all the characters retain their literal meaning:

alias l='ls -ar'


ls –ar
l
sysadmin@localhost:~$ alias l='ls -ar'
sysadmin@localhost:~$ ls -ar
myhosts Public Downloads .selected_editor .bashrc .
Videos Pictures Documents .profile .bash_logout
Templates Music Desktop .cache ..
sysadmin@localhost:~$ l
myhosts Public Downloads .selected_editor .bashrc .
Videos Pictures Documents .profile .bash_logout
Templates Music Desktop .cache ..
sysadmin@localhost:~$

Consider This

Later, you can remove entries from your list of aliases by using the unalias command:

unalias l
l

sysadmin@localhost:~$ unalias l
sysadmin@localhost:~$ l
l: command not found
sysadmin@localhost:~$

2.1.22 Step 22
The Bash shell provides a feature designed to avoid typing mistakes and save typing effort; this feature is called
command completion. Command completion allows you to type a few characters of a command (or its file name
argument) and then press the Tab key. The Bash shell will complete the command (or its file name argument)
automatically for you.

For example, first type ec:

ec
sysadmin@localhost:~$ ec

Next, press the Tab key, and the shell will automatically complete the command echo for you (it even places a
space after the command so you can immediately start typing the option or argument):

sysadmin@localhost:~$ echo_

2.1.23 Step 23
When the characters that are typed are insufficient to match a single command, all the possible choices are
displayed if you press the Tab key twice:

ca
sysadmin@localhost:~$ ca
cal capsh cat cautious-launcher
calendar captoinfo catchsegv
caller case catman
sysadmin@localhost:~$ ca

Finish this command by pressing the letter l, followed by the Enter key:
l

sysadmin@localhost:~$ cal
April 2020
Su Mo Tu We Th Fr Sa
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30

sysadmin@localhost:~$

2.1.24 Step 24
The type command is used to determine what a file is and/or where it is located. Use the type command to get
information about the pwd command.

type pwd

sysadmin@localhost:~$ type pwd


pwd is a shell builtin

The pwd command is identified as a shell builtin; a command that is part of the shell rather than a separate program.
Let's find out more about the man command that’s used for viewing manual pages.

type man

sysadmin@localhost:~$ type man


man is /usr/bin/man

The man command is identified as a program located in /usr/bin


2.2 Getting Help
Manual pages are one of the best resources to get help on a Linux system. Referring to the man page for a
command will provide you with the basic idea behind the purpose of the command, as well as details regarding the
options of the command and a description of its features.

2.2.1 Step 1
To access man pages of the ls command, execute the following command:

man ls

LS(1) User Commands LS(1)

NAME
ls - list directory contents
SYNOPSIS
ls [OPTION]... [FILE]...
DESCRIPTION
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is speci
-fied.
Mandatory arguments to long options are mandatory for short
options too.

-a, --all
do not ignore entries starting with .

-A, --almost-all
do not list implied . and ..

--author
Manual page ls(1) line 1 (press h for help or q to quit)

2.2.2 Step 2
To view the various movement commands that are available, type the H key or Shift+h while viewing a man page

SUMMARY OF LESS COMMANDS

Commands marked with * may be preceded by a number, N.


Notes in parentheses indicate the behavior if N is given.
A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K.

h H Display this help.


q :q Q :Q ZZ Exit.
---------------------------------------------------------------------------
MOVING

e ^E j ^N CR * Forward one line (or N lines).


y ^Y k ^K ^P * Backward one line (or N lines).
f ^F ^V SPACE * Forward one window (or N lines).
b ^B ESC-v * Backward one window (or N lines).
z * Forward one window (and set window to N).
w * Backward one window (and set window to N).
ESC-SPACE * Forward one window, but don't stop at end-of-file.
d ^D * Forward one half-window (and set half-window to N).
u ^U * Backward one half-window (and set half-window to N).
ESC-) RightArrow * Right one half screen w

2.2.3 Step 3
Press the Spacebar to read through the help section. When you are ready to go back to the man page for the ls
command, press the Q key:

LS(1) User Commands LS(1)

NAME
ls - list directory contents
SYNOPSIS
ls [OPTION]... [FILE]...
DESCRIPTION
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is speci
-fied.
Mandatory arguments to long options are mandatory for short
options too.

-a, --all
do not ignore entries starting with .

-A, --almost-all
do not list implied . and ..

--author
Manual page ls(1) line 1 (press h for help or q to quit)
2.2.4 Step 4
Take a few moments to explore a few of the movement commands that are available when displaying a man page:

Command Function
Return (or Enter) Go down one line
Space Go down one page
/term Search for term
n Find next search item
1G Go to the beginning
G Go to the end
h Display help
q Quit man page

2.2.5 Step 5
When you are finished exploring the man page, exit the ls man page by typing the Q key:

q
sysadmin@localhost:~$ man ls
sysadmin@localhost:~$

2.2.6 Step 6
A command may be included in more than one section of man pages. To display a specific section for the passwd
command, execute the following:

man 5 passwd

sysadmin@localhost:~$ man 5 passwd


PASSWD(5) File Formats and Conversions PASSWD(5)

NAME
passwd - the password file

DESCRIPTION
/etc/passwd contains one line for each user account, with seven fields
delimited by colons (":"). These fields are:

o login name

o optional encrypted password

o numerical user ID

o numerical group ID

o user name or comment field

o user home directory

o optional user command interpreter


Manual page passwd(5) line 1 (press h for help or q to quit)

Consider This

By default, there are nine sections of man pages:

1. Executable programs or shell commands


2. System calls (functions provided by the kernel)
3. Library calls (functions within program libraries)
4. Special files (usually found in /dev)
5. File formats and conventions, e.g., /etc/passwd
6. Games
7. Miscellaneous (including macro packages and conventions), e.g., man(7), groff(7)
8. System administration commands (usually only for root)
9. Kernel routines [non-standard]

2.2.7 Step 7
When you are finished exploring the man page, exit the man page by typing the Q key:

2.2.8 Step 8
If you do not know the exact man page you are looking for, you can search for man pages that match a keyword by
using the -k option to the man command. For example, execute the following:

man –k passwd

sysadmin@localhost:~$ man -k passwd


chgpasswd (8) - update group passwords in batch mode
chpasswd (8) - update passwords in batch mode
gpasswd (1) - administer /etc/group and /etc/gshadow
openssl-passwd (1ssl) - compute password hashes
pam_localuser (8) - require users to be listed in /etc/passwd
passwd (1) - change user password
passwd (1ssl) - compute password hashes
passwd (5) - the password file
update-passwd (8) - safely update /etc/passwd, /etc/shadow and /etc/group
sysadmin@localhost:~$

Note: When you use the -k option, both the man page names and descriptions are searched.
2.2.9 Step 9
To search only for the man page name, use the -f option:

man –f passwd

sysadmin@localhost:~$ man -f passwd


passwd (1ssl) - compute password hashes
passwd (1) - change user password
passwd (5) - the password file
sysadmin@localhost:~$

2.2.10 Step 10
Alternatively, you can try the whatis command, which produces the same result as the man -f command:

whatis passwd

sysadmin@localhost:~$ whatis passwd


passwd (1ssl) - compute password hashes
passwd (1) - change user password
passwd (5) - the password file
sysadmin@localhost:~$

Consider This

Want to learn more about man pages? Execute the command man man:

sysadmin@localhost:~$ man man

Sumber : https://content.netdevgroup.com/labs/lpic1-s1/EfrmyJmPoR/
NDG Introduction to Linux I - Chapter 3: Configuring the
Shell

3.1 Introduction
One key component of the Bash shell is shell variables. These variables are critical because they store vital system
information and modify the behavior of the Bash shell, as well as many commands. This chapter will discuss in
detail what shell variables are and how they can be used to configure the shell.

You will learn how the PATH variable affects how commands are executed and how other variables affect your
ability to use the history of your commands. You will also see how to use initialization files to make shell variables
persistent, so they will be created each time you log into the system.

Additionally, this chapter will cover how to use the command history and the files that are used to store and
configure the command history.

3.2 Shell Variables


A variable is a name or identifier that can be assigned a value. The shell and other commands read the values of
these variables, which can result in altered behavior depending on the contents (value) of the variable.

Variables typically hold a single value, like 0 or bob. Some may contain multiple values separated by spaces like
Joe Brown or by other characters, such as colons; /usr/bin:/usr/sbin:/bin:/usr/bin:/home/joe/bin.

You assign a value to a variable by typing the name of the variable immediately followed by the equal sign =
character and then the value. For example:

name="Bob Smith"

Variable names should start with a letter (alpha character) or underscore and contain only letters, numbers and the
underscore character. It is important to remember that variable names are case sensitive; a and A are different
variables. Just as with arguments to commands, single or double quotes should be used when special characters are
included in the value assigned to the variable to prevent shell expansion.

Valid Variable Assignments Invalid Variable Assignments


a=1 1=a
_1=a a-1=3
LONG_VARIABLE='OK' LONG-VARIABLE='WRONG'
Name='Jose Romero' 'user name'=anything

The Bash shell and many commands make extensive use of variables. One of the main uses of variables is to
provide a means to configure various preferences for each user. The Bash shell and commands can behave in
different ways, based on the value of variables. For the shell, variables can affect what the prompt displays, the
directories the shell will search for commands to execute and much more.
3.2.1 Local and Environment Variables
A local variable is only available to the shell in which it was created. An environment variable is available to the
shell in which it was created, and it is passed into all other commands/programs started by the shell.

To set the value of a variable, use the following assignment expression. If the variable already exists, the value of
the variable is modified. If the variable name does not already exist, the shell creates a new local variable and sets
the value:

variable=value

In the example below, a local variable is created, and the echo command is used to display its value:

sysadmin@localhost:~$ name="judy"
sysadmin@localhost:~$ echo $name
judy

By convention, lowercase characters are used to create local variable names, and uppercase characters are used
when naming an environment variable. For example, a local variable might be called test while an environment
variable might be called TEST. While this is a convention that most people follow, it is not a rule. An environment
variable can be created directly by using the export command.

export variable=value

In the example below, an environment variable is created with the export command:

sysadmin@localhost:~$ export JOB=engineer

Recall that the echo command is used to display output in the terminal. To display the value of the variable, use a
dollar sign $ character followed by the variable name as an argument to the echo command:

sysadmin@localhost:~$ echo $JOB


engineer

We can see the difference between local and environment variables by opening a new shell with the bash
command

sysadmin@localhost:~$ bash
To run a command as administrator (user "root"), use "sudo" command.
See "man sudo_root" for details.
sysadmin@localhost:~$ echo $name
sysadmin@localhost:~$ echo $JOB
engineer

Notice that the local variable name is empty, while the environment variable JOB returns the value engineer. Also notice
that if you return to the first shell by using the exit command, both variables are still available in the original shell:

sysadmin@localhost:~$ exit
exit
sysadmin@localhost:~$ echo $name
judy
sysadmin@localhost:~$ echo $JOB
engineer
The local variable name is not available in the new shell because by default, when a variable is assigned in the
Bash shell, it is initially set as a local variable. When you exit the original shell, only the environment variables
will be available. There are several ways that a local variable can be made into an environment variable.

First, an existing local variable can be exported with the export command.

export variable

In the example below, the local variable name is exported to environment (with the standard convention of all
caps):

sysadmin@localhost:~$ NAME=judy
sysadmin@localhost:~$ export NAME
sysadmin@localhost:~$ echo $NAME
judy

Second, a new variable can be exported and assigned a value with a single command as demonstrated below with
the variable DEPARTMENT:

sysadmin@localhost:~$ export DEPARTMENT=science


sysadmin@localhost:~$ echo $DEPARTMENT
science

Third, the declare or typeset command can be used with the export -x option to declare a variable to be an
environment variable. These commands are synonymous and work the same way:

sysadmin@localhost:~$ declare -x EDUCATION=masters

sysadmin@localhost:~$ echo $EDUCATION


masters
sysadmin@localhost:~$ typeset -x EDUCATION=masters
sysadmin@localhost:~$ echo $EDUCATION
masters

The env command is used to run commands in a modified environment. It can also be used to temporarily create or
change environment variables that are only passed to a single command execution by using the following syntax:

env [NAME=VALUE] [COMMAND]

For example, servers are often set to Coordinated Universal Time (UTC), which is good for maintaining consistent
time on servers across the planet, but can be frustrating for practical use to simply tell the time:
sysadmin@localhost:~$ date
Sun Mar 10 22:47:44 UTC 2020

To temporarily set the time zone variable, use the env command. The following will run the date command with
the temporary variable assignment:

sysadmin@localhost:~$ env TZ=EST date


Sun Mar 10 17:48:16 EST 2020

The TZ variable is set only in the environment of the current shell, and only for the duration of the command. The
rest of the system will not be affected by this variable. In fact, running the date command again will verify that the
TZ variable has reverted to UTC.

sysadmin@localhost:~$ date
Sun Mar 10 22:49:46 UTC 2020

3.2.2 Displaying Variables


There are several ways to display the values of variables. The set command by itself will display all variables
(local and environment) Here, we will pipe the output to the tail command so we can see some of the variables
that were set in the previous section:

sysadmin@localhost:~$ set | tail


DEPARTMENT=science
SHELL=/bin/bash
SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
SHLVL=1
TERM=xterm
UID=1001
USER=sysadmin
VISUAL=vi
_=set
name=judy

Note

The example above utilizes a command line pipe, represented by the | character. The pipe character can be used to
send the output of one command to another.

The command line pipes will be covered in greater detail later in the course.

Note

The tail command is used to display only the last few lines of a file, (or, when used with a pipe, the output of a
previous command). By default, the tail command displays ten lines of a file provided as an argument.
The tail command will be covered in greater detail later in the course.

To display only environment variables, you can use several commands that provide nearly the same output:

env
declare -x
typeset -x
export -p

sysadmin@localhost:~$ env | tail


NAME=judy
MAIL=/var/mail/sysadmin
SHELL=/bin/bash
TERM=xterm
SHLVL=1
EDUCATION=masters
LOGNAME=sysadmin
PATH=/home/sysadmin/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:
/bin:/usr/games:/usr/local/games
LESSOPEN=| /usr/bin/lesspipe %s
_=/usr/bin/env

To display the value of a specific variable, use the echo command with the name of the variable prefixed by the $ (dollar
sign). For example, to display the value of the PATH variable, you would execute echo $PATH:

sysadmin@localhost:~$ echo $PATH


/home/sysadmin/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/
usr/local/games

Consider This

Variables can also be enclosed in the curly brace {} characters in order to delimit them from surrounding text.
While the echo ${PATH} command would produce the same result as the echo $PATH command, the curly braces
set the variable apart visually, making it easier to see in scripts in some contexts.

3.2.3 Unsetting Variables


If you create a variable and then no longer want that variable to be defined, use the unset command to delete it:

unset VARIABLE
sysadmin@localhost:~$ example=12
sysadmin@localhost:~$ echo $example
12
sysadmin@localhost:~$ unset example
sysadmin@localhost:~$ echo $example
Warning

Do not unset critical system variables like the PATH variable, as this may lead to a malfunctioning environment.
3.2.4 PATH Variable
The PATH variable is one of the most critical environment variables for the shell, so it is important to understand the
effect it has on how commands will be executed.

⁠ 

The PATH variable contains a list of directories that are used to search for commands entered by the user. When the
user types a command and then presses the Enter key, the PATH directories are searched for an executable file that
matches the command name. Processing works through the list of directories from left to right; the first executable
file that matches what is typed is the command the shell will try to execute.

Note

Before searching the PATH variable for the command, the shell will first determine if the command is an alias or
function, which may result in the PATH variable not being utilized when that specific command is executed.

Additionally, if the command happens to be built-in to the shell, the PATH variable will not be utilized.

Using the echo command to display the current $PATH will return all the directories that files can be executed from.
The following example displays a typical PATH variable, with directory names separated from each other by a colon
: character:

sysadmin@localhost:~$ echo $PATH


/home/sysadmin/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/
usr/local/games

The following table illustrates the purpose of some of the directories displayed in the output of the previous
command:

Directory Contents
/home/sysadmin/bin
A directory for the current user sysadmin to place programs. Typically used by users who
create their own scripts.
/usr/local/sbin
Normally empty, but may have administrative commands that have been compiled from
local sources.
/usr/local/bin Normally empty, but may have commands that have been compiled from local sources.
/usr/sbin Contains the majority of the administrative command files.
/usr/bin Contains the majority of the commands that are available for regular users to execute.
/sbin Contains the essential administrative commands.
/bin
Contains the most fundamental commands that are essential for the operating system to
function.

To execute commands that are not contained in the directories that are listed in the PATH variable, several options
exist:

 The command may be executed by typing the absolute path to the command.
 The command may be executed with a relative path to the command.
 The PATH variable can be set to include the directory where the command is located.
 The command can be copied to a directory that is listed in the PATH variable.

To demonstrate absolute paths and relative paths an executable script named my.sh is created in the home
directory. Next, that script file is given “execute permissions” (permissions are covered in a later chapter):

sysadmin@localhost:~$ echo 'echo Hello World!' > my.sh


sysadmin@localhost:~$ chmod u+x my.sh

An absolute path specifies the location of a file or directory from the top-level directory through all of the
subdirectories to the file or directory. Absolute paths always start with the / character representing the root
directory. For example, /usr/bin/ls is an absolute path. It means the ls file, which is in the bin directory, which
is in the usr directory, which is in the / (root) directory. A file can be executed using an absolute path like so:

sysadmin@localhost:~$ /home/sysadmin/my.sh
Hello World!

A relative path specifies the location of a file or directory relative to the current directory. For example, in the
/home/sysadmin directory, a relative path of test/newfile would actually refer to the
/home/sysadmin/test/newfile file. Relative paths never start with the / character.

Note

Visualizing the directory structure using paths can be confusing at first, but it is a necessary skill for effectively
navigating the filesystem.

Absolute paths and relative paths are covered in greater detail in the NDG Linux Essentials course.

Using a relative path to execute a file in the current directory requires the use of the . character, which symbolizes
the current directory:

sysadmin@localhost:~$ ./my.sh
Hello World!

Sometimes a user wants their home directory added to the PATH variable in order to run scripts and programs
without using ./ in front of the file name. They might be tempted to modify the PATH variable like so:

sysadmin@localhost:~$ echo $PATH


/home/sysadmin/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/
usr/local/games
sysadmin@localhost:~$ pwd
/home/sysadmin
sysadmin@localhost:~$ PATH=/home/sysadmin

Unfortunately, modifying a variable this way overwrites the contents. Therefore, everything that was previously
contained in the PATH variable will be lost.

sysadmin@localhost:~$ echo $PATH


/home/sysadmin
Programs listed outside of the /home/sysadmin directory will now only be accessible by using their full path
name. For example, assuming that the home directory has not yet been added to the PATH variable, the uname -a
command would behave as expected:

sysadmin@localhost:~$ uname -a
Linux localhost 3.15.6+ #2 SMP Wed Jul 23 01:26:02 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

After assigning the home directory to the PATH variable, the uname -a command will need its full path name to execute
successfully:

sysadmin@localhost:~$ PATH=/home/sysadmin
sysadmin@localhost:~$ uname -a
-bash: uname: command not found
sysadmin@localhost:~$ /bin/uname -a
Linux localhost 3.15.6+ #2 SMP Wed Jul 23 01:26:02 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

Important

If you changed the PATH variable like we did in the previous example and want to reset it, simply use the exit
command to logout:

sysadmin@localhost:~$ exit

Once logged back in, the PATH variable will be reset to its original value.

It is possible to add a new directory to the PATH variable without overwriting its previous contents. Import the
current value of the $PATH variable into the newly defined PATH variable by using it on both sides of the assignment
statement:

sysadmin@localhost:~$ PATH=$PATH

Finish it with the value of the additional home directory path:

sysadmin@localhost:~$ PATH=$PATH:/home/sysadmin
sysadmin@localhost:~$ echo $PATH
/home/sysadmin/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/
usr/local/games:/home/sysadmin

Now, scripts located in the /home/sysadmin directory can execute without using a path:

sysadmin@localhost:~$ my.sh
Hello World!
Warning

In general, it is a bad idea to modify the $PATH variable. If it were to change, administrators would view it as
suspicious activity. Malicious forces want to gain elevated privileges and access to sensitive information residing
on Linux servers. One way to do this is to write a script which shares the name of a system command, then change
the PATH variable to include the administrator’s home directory. When the administrator types in the command, it
actually runs the malicious script!

3.3 Initialization Files


When a user opens a new shell, either during login or when they run a terminal that starts a shell, the shell is
customized by files called initialization (or configuration) files. These initialization files set the value of variables,
create aliases and functions, and execute other commands that are useful in starting the shell.

There are two types of initialization files: global initialization files that affect all users on the system and local
initialization files that are specific to an individual user.

The global configuration files are located in the /etc directory. Local configuration files are stored in the user's
home directory.

BASH Initialization Files

Each shell uses different initialization files. Additionally, most shells execute different initialization files when the
shell is started via the login process (called a login shell) versus when a shell is started by a terminal (called a non-
login shell or an interactive shell).

The following diagram illustrates the different files that are started with a typical login shell versus an interactive
shell:
Note

The tilde ~ character represents the user's home directory.

Note

File names preceded by a period . character indicates hidden files. You can view these files in your home directory
by using the ls command with the all -a option.

sysadmin@localhost:~$ ls -a
. .bashrc .selected_editor Downloads Public
.. .cache Desktop Music Templates
.bash_logout .profile Documents Pictures Videos

When Bash is started as a login shell, the /etc/profile file is executed first. This file typically executes all files
ending in .sh that are found in the /etc/profile.d directory.
The next file that is executed is usually ~/.bash_profile (but some users may use ~/.bash_login or
~/.profile file). The ~/.bash_profile file typically also executes the ~/.bashrc file which in turn executes the
/etc/bashrc file.

Consider This

Since the ~/.bash_profile file is under the control of the user, the execution of the ~/.bashrc and /etc/bashrc
files are also controllable by the user.

When Bash is started as an interactive shell, it executes the ~/.bashrc file, which may also execute the
/etc/bashrc file, if it exists. Again, since the ~/.bashrc file is owned by the user who is logging in, the user can
prevent execution of the /etc/bashrc file.

With so many initialization files, a common question at this point is "what file am I supposed to use?" The
following chart illustrates the purpose of each of these files, providing examples of what commands you might
place in each file:

File Purpose
This file can only be modified by the administrator and will be executed by every user
/etc/profile who logs in. Administrators use this file to create key environment variables, display
messages to users as they log in, and set key system values.
Each user has their own .bash_profile file in their home directory. The purpose of
~/.bash_profile
~/.bash_login
this file is the same as the /etc/profile file, but having this file allows a user to
~/.profile customize the shell to their own tastes. This file is typically used to create customized
environment variables.
Each user has their own .bashrc file in their home directory. The purpose of this file is
~/.bashrc to generate items that need to be created for each shell, such as local variables and
aliases.
This file may affect every user on the system. Only the administrator can modify this
/etc/bashrc file. Like the .bashrc file, the purpose of this file is to generate items that need to be
created for each shell, such as local variables and aliases.

3.3.1 Modifying Initialization Files


The way a user's shell operates can be changed by modifying that user's initialization files. Modifying global
configuration requires administrative access to the system as the files under the /etc directory can only be
modified by an administrator. A user can only modify the initialization files in their home directory.

The best practice is to create a backup before modifying configuration files as insurance against errors; a backup
can always be restored if something should go wrong. The following example references CentOS, a community-
supported Linux distribution based on source code from Red Hat Enterprise Linux.

In some distributions, the default ~/.bash_profile file contains the following two lines which customize the
PATH environment variable:

PATH=$PATH:$HOME/bin
export PATH
The first line sets the PATH variable to the existing value of the PATH variable with the addition of the bin
subdirectory of the user's home directory. The $HOME variable refers to the user's home directory. For example, if
the user logging in is joe, then $HOME/bin is /home/joe/bin.

The second line converts the local PATH variable into an environment variable.

The default ~/.bashrc file executes /etc/bashrc using a statement like:

⁠ 
./etc/bashrc

The period . character used to source a file in order to execute it. The period . character also does have a synonym
command, the source command, but the use of the period . character is more common than using the source
command.

Sourcing can be an effective way to test changes made to initialization files, enabling you to correct any errors
without having to log out and log in again. If you update the ~/.bash_profile to alter the PATH variable, you
could verify that your changes are correct by executing the following:

.~/.bash_profile
echo $PATH

Warning

Our virtual environment is not persistent, therefore, any changes made to the configuration files will not be saved if
the VM is reset.

3.3.2 BASH Exit Scripts


Just as Bash executes one or more files upon starting up, it also may execute one or more files upon exiting. As
Bash exits, it will execute the ~/.bash_logout and /etc/bash_logout files, if they exist. Typically, these files
are used for "cleaning up" tactics as the user exits the shell. For example, the default ~/.bash_logout executes the
clear command to remove any text present in the terminal screen.

⁠ 

Consider This

When a new user is created, the files from the /etc/skel directory are automatically copied into the new user's
home directory. As an administrator, you can modify the files in the/etc/skel directory to provide custom
features to new users.
3.4 Command History
In a sense, the ~/.bash_history file could also be considered to be an initialization file, since Bash also reads this
file as it starts up. By default, this file contains a history of the commands that a user has executed within the Bash
shell. When a user exits the Bash shell, it writes out the recent history to this file.

There are several ways that this command history is advantageous to the user:

 You can use the Up ↑ and Down ↓ Arrow Keys to review your history and select a previous command to
execute again.
 You can select a previous command and modify it before executing it.
 You can do a reverse search through history to find a previous command to select, edit, and execute it. To
start the search, press Ctrl+R and then begin typing a portion of a previous command.
 You execute a command again, based upon a number that is associated with the command.

3.4.1 Executing Previous Commands


The Bash shell will allow a user to use the Up ↑ Arrow Key to view previous commands. With each press of the
up arrow, the shell displays one more command back in the history list.

If the user goes back too far, the Down ↓ Arrow Key can be used to return to a more recent command. Once the
correct command is displayed, the Enter key can be pressed to execute it.

The Left ← and Right → Arrow Keys can also be used to position the cursor within the command. The
Backspace and Delete keys are used to remove text, and additional characters can be typed into the command line
to modify it before pressing the Enter key to execute it.

There are more keys that can be used for editing a command on the command line. The following table summarizes
some helpful editing keys:

Action Key Alternate Key Combination


Previous history item ↑ Ctrl+P
Next history item ↓ Ctrl+N
Reverse history search Ctrl+R
Beginning of line Home Ctrl+A
End of line End Ctrl+E
Delete current character Delete Ctrl+D
Delete to the left of the cursor Backspace Ctrl+X
Move cursor left ← Ctrl+B
Move cursor right → Ctrl+F
3.4.2 Changing Editing Keys
The keys that are available for editing a command are determined by the settings of a library called Readline. The
keys are typically set to match the key assignments found within the emacs text editor (a popular Linux editor) by
default.

To bind the keys to match the key assignments found with another popular text editor, the vi editor. The shell can
be configured with the set -o vi command. To set the key bindings back to the emacs text editor, use the set -o
emacs command.

Note

If you don't know how to use the vi editor yet, you may want to stick with the emacs keys as the vi editor has a
bigger learning curve.

The vi editor will be covered in greater detail later in the course.

To automatically configure the edit history options at login, edit the ~/.inputrc file. If this file doesn't exist, the
/etc/inputrc file is used instead. Key bindings are set differently in configuration files than on the command
line; for example, to enable the vi key binding mode for an individual, add the following lines to the ~/.inputrc
file:


set editing-mode vi
set keymap vi

If the situation is reversed, perhaps due to the above two lines being added to the /etc/inputrc file, a user can
enable the emacs mode by adding the following lines to the ~/.inputrc file:

set editing-mode emacs


set keymap emacs

3.4.3 Using the history Command


The history command can be used to re-execute previously executed commands. When used with no arguments,
the history command provides a list of previously executed commands:

sysadmin@localhost:~$ history
1 ls
2 cd test
3 cat alpha.txt
4 ls -l
5 cd ..
6 ls
7 history

Note that each command is assigned a number that a user can use to re-execute the command.

The history command has numerous options; the most common of these options are listed below:

⁠ 
Option Purpose
Option Purpose
-c Clear the list
-r Read the history file and replace the current history
-w Write the current history list to the history file

As the history list commonly contains five hundred or more commands, it is often helpful to filter the list. The
history command accepts a number as an argument to indicate how many commands to list. For example,
executing the following command will only show the last three commands from your history.

sysadmin@localhost:~$ history 3
5 cd ..
6 ls
7 history

Note

The grep command is very useful for filtering the output of commands that produce copious output. For example,
to view all of the commands in your history that contain the ls command, search for the ls pattern using the
following command:

sysadmin@localhost:~$ history | grep "ls"


1 ls
4 ls -l
6 ls
9 history | grep "ls"

The grep command will be covered in greater detail later in the course.

3.4.4 Configuring the history Command


When you close the shell program, it takes commands in the history list and stores them in the ~/.bash_history
file, also called the history file. By default, five hundred commands will be stored in the history file. The
HISTFILESIZE variable will determine how many commands to write to this file.

If a user wants to store the history commands in a file that is different from ~/.bash_history, then the user can
specify an absolute path to the different file as the value for the HISTFILE local variable:

HISTFILE=/path/to/file

The HISTSIZE variable will determine how many commands to keep in memory for each Bash shell. If the size of
HISTSIZE is greater than the size of HISTFILESIZE, then only the most recent number of commands specified by
HISTFILESIZE will be written to the history file when the Bash shell exits.

Although it is not normally set to anything by default, you may want to take advantage of setting a value for the
HISTCONTROL variable in an initialization file like the ~/.bash_profile file. The HISTCONTROL variable could be
set to any of the following features:

HISTCONTROL=ignoredups

Prevents duplicate commands that are executed consecutively.


HISTCONTROL=ignorespace

Any command that begins with a space will not be stored. This provides the user with an easy way to execute a
command that won't go into the history list.

HISTCONTROL=ignoreboth

Consecutive duplicates and any commands that begin with a space will not be stored.

HISTCONTROL=erasedups

Commands that are identical to another command in your history will not be stored. (The previous entry of the
command will be deleted from the history list.)

HISTCONTROL=ignorespace:erasedups

Includes the benefit of erasedups with the advantage of ignorespace.

Another variable that will affect what gets stored in the history of commands is the HISTIGNORE variable. Most
users do not want the history list cluttered with basic commands like the ls, cd, exit, and history commands.
The HISTIGNORE variable can be used to tell Bash not to store certain commands in the history list.

To have commands not included in the history list, include an assignment like the following in the
~/.bash_profile file:

HISTIGNORE='ls*:cd*:history*:exit'

Note

The * character is used to indicate anything else after the command. So, ls* would match any ls command, such
as ls -l or ls /etc.

Globbing will be covered in greater detail later in the course.

3.4.5 Executing Previous Commands


The ! exclamation mark is a special character to the Bash shell to indicate the execution of a command within the
history list. There are many ways to use the ! exclamation character to re-execute commands; for example,
executing two exclamation characters will repeat the previous command:

sysadmin@localhost:~$ ls
Desktop Documents Downloads Music Pictures Public Templates Videos
sysadmin@localhost:~$ !!
ls
Desktop Documents Downloads Music Pictures Public Templates Videos
The following table provides some examples of using the exclamation ! character:


History Command Meaning
!! Repeat the last command
!-4 Execute the command that was run four commands ago
!555 Execute command number 555
!ec Execute the last command that started with ec
!?joe Execute the last command that contained joe

Another way to use the history list is to take advantage of the fact that the last argument of every command is
stored. Often a user will type a command to refer to a file, perhaps to display some information about that file.
Subsequently, the user may want to type another command to do something else with the same file. Instead of
having to type the path again, a user can use a couple of keyboard shortcuts to recall that file path from the
previous command line.

By pressing either Esc+. (Escape+Period) or Alt+. (Alt+Period), the shell will bring back the last argument of the
previous command. Repeatedly pressing one of these key combinations will recall, in reverse order, the last
argument of each previous command.
NDG Introduction to Linux I - Lab 3: Configuring the
Shell

One key component of the Bash shell is shell variables. These variables are critical because they store vital system
information and modify the behavior of the Bash shell, as well as many commands. In this lab, you will learn how to
configure shell features such as variables and command history. Understanding these shell features will make it much easier
for you to work in the command line environment.

3.1 Step 1
A local variable is only available to the shell in which it was created. To set the value of a variable, use the
following assignment expression:

variable=value

Create and display a local variable by executing the following commands:

name="bob"
echo $name

sysadmin@localhost:~$ name="bob"
sysadmin@localhost:~$ echo $name
bob

3.2 Step 2
An environment variable is available to the shell in which it was created, and it is passed into all other
commands/programs started by the shell. An environment variable can be created directly by using the export
command:

export variable=value

Create and display an environment variable by executing the following commands:

export AGE=25
echo $AGE

sysadmin@localhost:~$ export AGE=25


sysadmin@localhost:~$ echo $AGE
25
3.3 Step 3
To display the value of the variable, use a dollar sign $ character followed by the variable name as an argument to
the echo command. Recall that the echo command is used to display output in the terminal.

Open another shell and view the contents of the two variables that were created:

bash
echo $name
echo $AGE

sysadmin@localhost:~$ bash
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
sysadmin@localhost:~$ echo $name
sysadmin@localhost:~$ echo $AGE
25

Notice in the output of the commands above that the $name variable didn't exist in the new shell because local variables
are not passed into new processes. However, the $AGE variable did exist in the new shell, since environment variables are
passed into new processes.

3.4 Step 4
The set command by itself will display all variables (local and environment). To display variables in the original
shell, exit the current shell and use the set command with a pager, along with the less command, in a command
pipeline by using the pipe | character:

exit
set | less

sysadmin@localhost:~$ exit
sysadmin@localhost:~$ set | less
AGE=25
BASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote
:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:s
ourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_COMPLETION_VERSINFO=([0]="2" [1]="8")
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="4" [1]="4" [2]="19" [3]="1" [4]="release" [5]="x86_64-pc-lin
ux-gnu")
BASH_VERSION='4.4.19(1)-release'
COLUMNS=80
DIRSTACK=()
EDITOR=vi
EUID=1001
GROUPS=()
HISTCONTROL=ignoreboth
HISTFILE=/home/sysadmin/.bash_history
HISTFILESIZE=2000
:

To exit the less command and return to the prompt, press Q.

3.5 Step 5
The set command used in the previous step displays all variables, both local and environment. To only display
environment variables, execute the env command:

env
sysadmin@localhost:~$ env

LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or
=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*
.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01
;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;
31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=0
1;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.wa
r=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31
:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;
35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*
.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01
;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.
mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;
35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli
=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.e
mf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36
:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=0
0;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:

LESSCLOSE=/usr/bin/lesspipe %s %s
AGE=25
HUSHLOGIN=FALSE
USER=sysadmin
PWD=/home/sysadmin
HOME=/home/sysadmin
MAIL=/var/mail/sysadmin
SHELL=/bin/bash
TERM=xterm
SHLVL=1
LOGNAME=sysadmin
PATH=/home/sysadmin/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/ga
mes:/usr/local/games
LESSOPEN=| /usr/bin/lesspipe %s
_=/usr/bin/env
sysadmin@localhost:~$
Note

The following commands will also display only environment variables and will provide similar output to the env
command:

declare -x
typeset -x
export -p

3.6 Step 6
If it is no longer necessary for a variable to be defined, the unset command can be used to delete it:

unset VARIABLE

Execute the following commands to unset these variables and then verify that they are no longer set:

unset name
unset AGE
echo $name
echo $AGE

sysadmin@localhost:~$ unset name


sysadmin@localhost:~$ unset AGE
sysadmin@localhost:~$ echo $name
sysadmin@localhost:~$ echo $AGE

Important

Do not unset critical system variables like the PATH variable, as this may lead to a malfunctioning environment.

3.7 Step 7
The PATH variable contains a list of directories that are used to search for commands entered by the user. When the
user types a command and then presses the Enter key, the PATH directories are searched for an executable file that
matches the command name.

Display the value of the PATH variable by executing the following command:

echo $PATH
sysadmin@localhost:~$ echo $PATH
/home/sysadmin/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/
usr/local/games
The following table illustrates the purpose of some of the directories displayed in the output of the previous
command:

Directory Contents
/home/sysadmin/bin
A directory for the current sysadmin user to place programs. Typically used by users who
create their own scripts.
/usr/local/sbin
Normally empty, but may have administrative commands that have been compiled from
local sources.
/usr/local/bin Normally empty, but may have commands that have been compiled from local sources.
/usr/sbin Contains the majority of the administrative command files.
/usr/bin Contains the majority of the commands that are available for regular users to execute.
/sbin Contains the essential administrative commands.
/bin
Contains the most fundamental commands that are essential for the operating system to
function.

Note

Recall that when you execute a command without specifying a complete path name, the shell uses the value of the
PATH variable to determine where the command is stored.

3.8 Step 8
Using the which command, you can determine where a command resides in the PATH. Execute the following to
determine where the ls command resides:

which ls

sysadmin@localhost:~$ which ls
/bin/ls

3.9 Step 9
If the command doesn't reside in a directory that is specified in the PATH variable, no output is displayed:

which zzz

sysadmin@localhost:~$ which zzz


sysadmin@localhost:~$

Consider This

You can also use the type command, which more clearly indicates that the command is not located in the PATH:

type zzz
sysadmin@localhost:~$ type zzz
-bash: type: zzz: not found

3.10 Step 10
Recall that when the user types a command and then presses the Enter key, the PATH directories are searched for
an executable file that matches the command name. However, it is possible to execute commands that are not
contained in the directories that are listed in the PATH variable using the following options:

 The command may be executed by typing the absolute path to the command.
 The command may be executed with a relative path to the command.
 The PATH variable can be set to include the directory where the command is located.
 The command can be copied to a directory that is listed in the PATH variable.

There are two types of paths commonly used when invoking a command or locating a file in the Linux filesystem:
absolute paths and relative paths.

An absolute path specifies the location of a file or directory from the top-level directory through all of the
subdirectories to the file or directory. Absolute paths always start with the / character representing the root
directory. A relative path specifies the location of a file or directory relative to the current directory.

Note

If a command or file seems to be missing, often the reason is that it is not located within directories in the PATH
variable, and the user is trying to access it with a relative path. While specifying an absolute path should remedy
the problem, it can be cumbersome, especially when a file is located several layers deep into a directory structure.

A relative path is used for files that are within the directory structure you are currently located in. For example,
users normally log in to their home directories, so changing to the Documents directory (located under the user’s
home directory) using the relative path is as simple as typing the following command:

cd Documents

sysadmin@localhost:~$ cd Documents
sysadmin@localhost:~/Documents$

If, however, you were in the /etc directory and you want to change to the Documents directory, just typing the
command below from the /etc directory will return an error, because the Documents directory is not located
within the /etc directory:

cd /etc
cd Documents

sysadmin@localhost:~/Documents$ cd /etc
sysadmin@localhost:/etc$ cd Documents
-bash: cd: Documents: No such file or directory

Instead, you would need to use the absolute path by typing the following command:

cd /home/sysadmin/Documents
sysadmin@localhost:/etc$ cd /home/sysadmin/Documents
sysadmin@localhost:~/Documents$

3.11 Step 11
In this step, you will set the PATH variable to include a directory where a command would be located. Make a
directory and then add it to the PATH variable by executing the following commands:

mkdir mybin
PATH=$PATH:/home/sysadmin/mybin

sysadmin@localhost:~/Documents$ cd
sysadmin@localhost:~$ mkdir mybin
sysadmin@localhost:~$ PATH=$PATH:/home/sysadmin/mybin

Verify that the PATH now includes the /home/sysadmin/mybin directory using the echo command:

echo $PATH

sysadmin@localhost:~$ echo $PATH


/home/sysadmin/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/
usr/local/games:/home/sysadmin/mybin

Notice in the output above that the /home/sysadmin/mybin directory is appended to the PATH variable:

/home/sysadmin/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/
usr/local/games:/home/sysadmin/mybin

3.12 Step 12
In the following steps, you will copy a command (executable program) to a directory that is listed in the PATH
variable. Create a simple Bash shell program in your current directory by executing the following commands:

echo "echo hello" > hello.sh


chmod a+x hello.sh

sysadmin@localhost:~$ echo "echo hello" > hello.sh


sysadmin@localhost:~$ chmod a+x hello.sh

Note

The second command in the example above gives the hello.sh script file execute permissions, which allows for a
file to be run as a process.

Permissions will be covered in greater detail in a later chapter.


3.13 Step 13
Execute the following command to verify that the hello.sh program works correctly:

/home/sysadmin/hello.sh

sysadmin@localhost:~$ /home/sysadmin/hello.sh
hello

3.14 Step 14
Note that you can't just execute hello.sh, you must include the path to the command. Execute the following to
verify:

hello.sh

sysadmin@localhost:~$ hello.sh
hello.sh: command not found

3.15 Step 15
However, if you place this script in the /home/sysadmin/mybin directory, which is included in the PATH variable,
you can execute the command without specifying the full path. Use the mv command to move the hello.sh file to
the /home/sysadmin/mybin directory, which is located in the PATH and then execute the hello.sh file alone to
verify:

mv hello.sh /home/sysadmin/mybin
hello.sh

sysadmin@localhost:~$ mv hello.sh /home/sysadmin/mybin


sysadmin@localhost:~$ hello.sh
hello

Note

You could also verify this by executing the following command:

which hello.sh

sysadmin@localhost:~$ which hello.sh


/home/sysadmin/mybin/hello.sh
3.16 Step 16
When a user opens a new shell, either during login or when they run a terminal that starts a shell, the shell is
customized by files called initialization (or configuration) files. These initialization files set the value of variables,
create aliases and functions, and execute other commands that are useful in starting the shell.

Each shell uses different initialization files. Additionally, most shells execute different initialization files when the
shell is started via the login process (called a login shell) versus when a shell is started by a terminal (called a non-
login shell or an interactive shell).

When Bash is started as an interactive shell, it executes the ~/.bashrc file.

Use the less pager command to view your account's .bashrc file to see what customizations are set by this file:

less .bashrc

sysadmin@localhost:~$ less .bashrc


# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# If not running interactively, don't do anything


case $- in
*i*) ;;
*) return;;
esac

# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth

# append to the history file, don't overwrite it


shopt -s histappend

# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)


HISTSIZE=1000

To exit the less command and return to the prompt, press Q.

3.17 Step 17
Adding custom paths to the PATH environment variable provides users with a means to customize their shell. For
example, if you wanted to create a custom shell script that could run from a directory other than where it was
located, you could add the path to it by modifying the PATH environment variable. The grep command can be used
to specifically see any changes made to the PATH variable in the .bashrc file:

grep PATH .bashrc

sysadmin@localhost:~$ grep PATH .bashrc


PATH="$HOME/bin:$PATH"
Note

The grep command provides the ability to filter text and will only display lines that contain the argument passed to
the command, in this case, PATH.

The grep command will be covered in greater detail later in the course.

3.18 Step 18
If you wanted to add more to the PATH variable, you could either edit the .bashrc file directly with a text editor
(such as vi, nano, or others covered in a later chapter) or execute the following commands:

echo 'PATH=$PATH:/home/sysadmin/mybin' >> .bashrc


tail .bashrc

sysadmin@localhost:~$ echo 'PATH=$PATH:/home/sysadmin/mybin' >> .bashrc


sysadmin@localhost:~$ tail .bashrc
# add user bin to path
PATH="$HOME/bin:$PATH"

# set editor and visual envs to vim


EDITOR=vi
VISUAL=vi

# change to home dir


cd ~
PATH=$PATH:/home/sysadmin/mybin

n the example above, the >> characters are used to redirect the output of the echo command and append it to the
bottom of the .bashrc file. The tail command displays the last ten lines of the .bashrc file so you can verify the
file was successfully edited.

Note

Redirection and the tail command will be covered in greater detail later in the course.

3.19 Step 19
The ~/.bash_history file could also be considered to be an initialization file since Bash also reads this file as it
starts up. By default, this file contains a history of the commands that a user has executed within the Bash shell.

The command history will allow a user to use the Up ↑ Arrow Key to view previous commands. With each press
of the up arrow, the shell displays one more command back in the history list.

If the user goes back too far, the Down ↓ Arrow Key can be used to return to a more recent command. Once the
correct command is displayed, the Enter key can be pressed to execute it.
The Left ← and Right → Arrow Keys can also be used to position the cursor within the command. The
Backspace and Delete keys are used to remove text, and additional characters can be typed into the command line
to modify it before pressing the Enter key to execute it. The following steps will demonstrate how to use the
command history.

Execute the following command, which will result in an error message:

cp /etc/host .

sysadmin@localhost:~$ cp /etc/host .
cp: cannot stat '/etc/host': No such file or directory

3.20 Step 20
The file name should be hosts, not host. To fix this, press the Up Arrow ↑ Key one time, use your Left Arrow
← Keys to move over to the space after host, type an s, and then press the Enter key:

Up Arrow Key
Left Arrow Key
Left Arrow Key
s
Enter Key
sysadmin@localhost:~$ cp /etc/hosts .

3.21 Step 21
Execute the history command to view previously executed commands:

history

sysadmin@localhost:~$ history
1 bash
2 name="bob"
3 echo $name
4 export AGE=25
5 echo $AGE
6 bash
7 set
8 bash
9 env
10 unset name
11 unset AGE
12 echo $name
13 echo $AGE
14 echo $PATH
15 which ls
16 which zzz
17 type zzz
18 mkdir mybin
19 PATH=$PATH:/home/sysadmin/mybin
20 echo "echo hello" > hello.sh
21 chmod a+x hello.sh
22 /home/sysadmin/hello.sh
23 hello.sh
24 mv hello.sh /home/sysadmin/mybin
25 hello.sh
26 which hello.sh
27 more .bashrc
28 grep PATH .bashrc
29 echo 'PATH=$PATH:/home/sysadmin/mybin' >> .bashrc
30 tail .bashrc
31 cp /etc/host .
32 cp /etc/hosts .
33 history

3.22 Step 22
The ! exclamation mark is a special character to the Bash shell to indicate the execution of a command within the
history list. There are many ways to use the ! exclamation character to re-execute commands; for example,
executing two exclamation characters will repeat the previous command.

Execute the history command again by executing the command history shortcut !!:

!!

sysadmin@localhost:~$ !!
1 bash
2 name="bob"
3 echo $name
4 export AGE=25
5 echo $AGE
6 bash
7 set
8 bash
9 env
10 unset name
11 unset AGE
12 echo $name
13 echo $AGE
14 echo $PATH
15 which ls
16 which zzz
17 type zzz
18 mkdir mybin
19 PATH=$PATH:/home/sysadmin/mybin
20 echo "echo hello" > hello.sh
21 chmod a+x hello.sh
22 /home/sysadmin/hello.sh
23 hello.sh
24 mv hello.sh /home/sysadmin/mybin
25 hello.sh
26 which hello.sh
27 more .bashrc
28 grep PATH .bashrc
29 echo 'PATH=$PATH:/home/sysadmin/mybin' >> .bashrc
30 tail .bashrc
31 cp /etc/host .
32 cp /etc/hosts .
33 history
3.23 Step 23
Execute the previous tail command by typing an exclamation ! character followed by the number before the tail
command in the history list. For example, given the previous output, you would execute the following:

The number in the command history in our virtual environment may be different from the example.
!15

sysadmin@localhost:~$ !15
which ls
/bin/ls

3.24 Step 24
Execute the following commands to have the history feature ignore duplicate commands:

HISTCONTROL=ignoredups
ls
ls
history | tail

sysadmin@localhost:~$ HISTCONTROL=ignoredups
sysadmin@localhost:~$ ls
Desktop Downloads Pictures Templates hosts
Documents Music Public Videos mybin
sysadmin@localhost:~$ ls
Desktop Downloads Pictures Templates hosts
Documents Music Public Videos mybin
sysadmin@localhost:~$ history | tail
37 history
38 bash
39 env
40 history
41 echo $AGE
42 history
43 which ls
44 HISTCONTROL=ignoredups
45 ls
46 history | tail

Notice that only one of the ls commands was recorded. The history | tail command line takes the output of the
history command and only displays the last ten lines of that output.
3.25 Step 25
To prevent the history feature from recording commands that begin with a space character, execute the following
commands. (Note that the cal command used in the example below has a space in front of it.):

HISTCONTROL=ignorespace
date
cal
history | tail

sysadmin@localhost:~$ HISTCONTROL=ignorespace
sysadmin@localhost:~$ date
Tue Apr 9 15:26:35 UTC 2019
sysadmin@localhost:~$ cal
April 2019
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6
7 8 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

sysadmin@localhost:~$ history | tail


40 history
41 echo $AGE
42 history
43 which ls
44 HISTCONTROL=ignoredups
45 ls
46 history | tail
47 HISTCONTROL=ignorespace
48 date
49 history | tail

3.26 Step 26
To clear the history list, use the -c option with the history command:

history -c

sysadmin@localhost:~$ history -c
sysadmin@localhost:~$ history
1 history

Sumber : https://content.netdevgroup.com/labs/lpic1-s1/g75k2uFDxF/
NDG Introduction to Linux I - Chapter 4: File Globbing

File globbing might sound like an unusual term, but the concept of globbing is probably a familiar one. Like a
joker in a deck of cards, which you might be able to use as any card (a wildcard), glob characters are special
characters that can be used to match file or path names.

For the details of how globbing works, you can view the man page on glob in section 7 of the manual pages by
executing:

sysadmin@localhost:~$ man 7 glob

From that manual page:

 A string is a wildcard pattern if it contains one of the characters '?', '*', or '['. Globbing is the operation
that expands a wildcard pattern into the list of path names matching the pattern.

The shell is what performs the expansion of the wildcards; therefore, the use of globbing is not limited to a
particular command. Globbing is especially useful for file management since it can be used to match the path
names to files that you want to manage.

4.2 Asterisk * Character


The asterisk* wildcard can be used to match any string, including the empty string.

sysadmin@localhost:~$ echo *
Desktop Documents Downloads Music Pictures Public Templates Videos

In the screen capture above, the echo command is used to see which files a glob pattern will match. In this case, it
displays the name of every file in the user's current directory.

Consider This

An empty string is a string that has nothing in it. It is commonly referred to as "".

In order to limit the * wildcard, so that it matches fewer file names, it can be combined with other characters. For
example, the D* pattern will only match file names that start with a D character:

sysadmin@localhost:~$ echo D*
Desktop Documents Downloads

The * character can appear anywhere in the pattern; it can even appear multiple times. It is possible to find a file
that not only starts with a D, but also contains the letter n, by using the D*n* pattern:

sysadmin@localhost:~$ echo D*n*


Documents Downloads
4.3 Question Mark ? Character
The question mark ? character in a string will match exactly one character. For example, to see all of the files in
the /usr/bin directory that only have one character in the file name, use the /usr/bin/? pattern:

sysadmin@localhost:~$ cd /usr/bin
sysadmin@localhost:/usr/bin$ echo /usr/bin/?
/usr/bin/[ /usr/bin/w

By adding more question mark ? characters, it is possible to match additional characters. In order to see which files
had two or three characters as their file names, execute the following two echo commands:

sysadmin@localhost:/usr/bin$ echo ??
⁠ du ex hd id nl od pg pr sg tr ul vi wc xz
sysadmin@localhost:/usr/bin$ echo ???
a2p apt awk cal cmp col cut dig env eqn fmt gpg lcf ldd man pdb pic ptx rcp rev
rsh s2p scp see seq ssh sum tac tbl tee tic toe top tty ucf who xxd yes zip

The incorporation of other characters to patterns using the question mark ? character, including other wildcard
characters, allow for more specific searches. For example, the w?? pattern will match files that started with the
letter w, and are exactly three characters long:

sysadmin@localhost:/usr/bin$ echo w??


who

While the w??* pattern will match files that started with the letter w, but are at least three characters long:

sysadmin@localhost:/usr/bin$ echo w??*


w.procps wall watch wget whatis whereis which who whoami write

4.4 Brackets [ ] Characters


By using the square bracket [ ] characters, a set of characters can be enclosed that will be used to match exactly
one character. You can think of the square brackets as being like a question mark ? wildcard, but limited to the
characters that are listed inside of the square brackets.

For example, using a pattern like [abcd]?? will match file names that start with an a, b, c, or d character and
that are three characters long. Alternatively, letters that are consecutive can also be expressed as a range like the
[a-d]?? pattern:

sysadmin@localhost:/usr/bin$ echo [a-d]??


a2p apt awk cal cmp col cut dig

Consider This

When the hyphen - character is used with square brackets, it is referred to as a range. For example: the [a-z]
pattern would match any single character that is within the range of characters from a to z.
This range is defined by the ASCII text table. Simply use a lower value character from the ASCII table as the first
character and a higher value character as the second.

To see the numeric value assigned to each character in the ASCII text table, either do a simple search for "ASCII
text table" on the internet or view the table with the ascii command:

sysadmin@localhost:~$ ascii

The touch command in the following example is used to create the files that will be matched. Single quotes were
used when specifying the file name to create with the touch command because within single quotes, globbing
characters lose their special meaning to the shell.

sysadmin@localhost:/usr/bin$ cd ~/Documents
sysadmin@localhost:~/Documents$ touch '*' '**' '***' '?' '??' '???' '[][][]'
sysadmin@localhost:~/Documents$ ls
'*' School alpha-third.txt letters.txt people.csv
'**' Work alpha.txt linux.txt profile.txt
'***' '[][][]' animals.txt longfile.txt red.txt
'?' adjectives.txt food.txt newhome.txt spelling.txt
'??' alpha-first.txt hello.sh numbers.txt words
'???' alpha-second.txt hidden.txt os.csv

When placed inside the square brackets, the wildcard characters lose their wildcard meaning and only match
themselves. So, a pattern like [*]* would match a file name that begins with an * character. A pattern of [?]*
would match a file name that begins with a ? character.

sysadmin@localhost:~/Documents$ echo [*]*


* ** ***
sysadmin@localhost:~/Documents$ echo [?]*
? ?? ???

Even using square brackets inside of the square brackets will match a square bracket, so [[]]* would match a file
name that starts with the square brackets:

sysadmin@localhost:~/Documents$ echo [[]]*


[][][]

Warning

Normally, you want to avoid using special characters like *, ?, [ and ] within file names because these
characters, when used in a file name on the command line, can end up matching other file names unintentionally.

⁠ 

Just as with the other wildcard characters, the square brackets can appear multiple times in a pattern. For example,
to match a file in the /usr/bin directory that contains at least two digits in the file name, use the /etc/*[0-9][0-
9]* pattern:

sysadmin@localhost:~/Documents$ cd /usr/bin
sysadmin@localhost:/usr/bin$ echo *[0-9][0-9]*
base64 i386 linux32 linux64 perl5.18.2 pstree.x11 sha224sum sha256sum sha384sum sha512sum
x86_64
The square brackets also support negating the set of characters (also called complementation). If the first character
inside of the square brackets is either an exclamation ! character or a caret ^ character, then that first character has
a special meaning of not the following characters, meaning match a single character that is not within the set of
characters that follows it.

In other words, the [!a-v]* pattern would match a file name that does not begin with a letter a through v:

sysadmin@localhost:/usr/bin$ echo [!a-v]*


2to3 2to3-2.7 2to3-3.4 [ w w.procps wall watch wc wget whatis whereis which who
whoami write x86_64 xargs xauth xgettext xsubpp xxd xz xzcat xzcmp xzdiff xzegrep xzfgrep
xzgrep xzless xzmore yes zdump zip zipcloak zipdetails zipgrep zipinfo zipnote zipsplit
zsoelim

Sumber : https://1579225036.netacad.com/courses/1009461/modules/items/66957930
NDG Introduction to Linux I - Lab 4: File Globbing

4.0 Introduction
In this task, you will explore the usage of glob characters, which are wildcards used to match files or path names.

Globbing expands the given wildcard pattern into a list of path names matching the pattern. This function is
performed by the shell and is extremely useful for file operations. It can be used with the grep and echo commands
as well as various file commands such as ls, cp, mv, and rm.

File globbing allows you to expand or restrict your search by modifying the wildcard pattern.

4.1 Step 1
To display the names of all files in your current working directory, execute the echo command with the asterisk *
character as the argument:

echo *

sysadmin@localhost:~$ echo *
Desktop Documents Downloads Music Pictures Public Templates Videos

The echo command can be used to see which files a glob pattern will match. The asterisk * character is a wildcard
pattern that is used for matching any string, including an empty string.

In the output above, all the files in your current working directory are displayed.

4.2 Step 2
To view all files and directories with names starting with the letter D, execute the following command:

echo D*

sysadmin@localhost:~$ echo D*
Desktop Documents Downloads
4.3 Step 3
The asterisk * character can be used at any position within the pattern. To list all files and directories with names
starting with the letter D and containing the letter n, execute the following command:

echo D*n*

sysadmin@localhost:~$ echo D*n*


Documents Downloads
sysadmin@localhost:~$ echo D*N*
D*N*

Important

In Linux, file names are case sensitive. So, the output of D*n* will be different from that of D*N*. Also, the shell
will not match files starting with a period . character when it matches an asterisk * character, as these are special
files called hidden files.

4.4 Step 4
To list all the files in the /usr/bin directory with names beginning with pyd, execute the following command:

echo /usr/bin/pyd*

sysadmin@localhost:~$ echo /usr/bin/pyd*


/usr/bin/pydoc3 /usr/bin/pydoc3.6

4.5 Step 5
The question mark ? character can be used for matching exactly one character. To view all files with names
consisting of exactly two characters in the /usr/bin directory, execute the following command:

echo /usr/bin/??

sysadmin@localhost:~$ echo /usr/bin/??


/usr/bin/du /usr/bin/ex /usr/bin/hd /usr/bin/id /usr/bin/mc /usr/bin/nl /usr/bin/od
/usr/bin/pr /usr/bin/sg /usr/bin/tr /usr/bin/ua /usr/bin/ul /usr/bin/vi /usr/bin/wc
/usr/bin/xz
4.6 Step 6
The asterisk * character matches zero or more characters, whereas the question mark ? character matches exactly
one character. To search for all files with names beginning with D and having at least one more character, execute
the following command:

echo D?*

sysadmin@localhost:~$$ echo D?*


Desktop Documents Downloads

4.7 Step 7
To search for a specific set of characters, use the square brackets [] notation. For example, to view all the files and
directories with names starting with the letters P, M, or T, followed by zero or more characters, execute the
following command:

echo [PMT]*

sysadmin@localhost:~$ echo [PMT]*


Music Pictures Public Templates

4.8 Step 8
The square brackets [] are used to specify supported ASCII characters. To specify a range of possible characters
from 3 to 6, execute the following command:

echo /etc/rc[3-6]*

sysadmin@localhost:~$ echo /etc/rc[3-6]*


/etc/rc3.d /etc/rc4.d /etc/rc5.d /etc/rc6.d

4.9 Step 9
To view all file names with the initial character in the range from A to D and containing at least three letters total,
execute the following command:

echo [A-D]??*

sysadmin@localhost:~$ echo [A-D]??*


Desktop Documents Downloads
4.10 Step 10
To view all files with names beginning with M, having a character from p to u in the 2nd position and followed by
exactly 3 more characters, execute the following command:

echo M[p-u]???

sysadmin@localhost:~$ echo M[p-u]???


Music

4.11 Step 11
The wildcard characters can have multiple occurrences within a pattern. To list all file names starting with the
letter p, containing the letter t and ending with the numbers in the range [2-6], execute the following command:

echo /usr/bin/p*t*[2-6]

sysadmin@localhost:~$ echo /usr/bin/p*t*[2-6]


/usr/bin/pygettext3 /usr/bin/pygettext3.6 /usr/bin/python3 /usr/bin/python3.6

Note

The square brackets notation [] also supports the negation operator. The characters ! or ^ are used for negation; if
either of these characters is placed at the first position within the square bracket, then the pattern is evaluated as to
match any character except the listed characters.

4.12 Step 12
If the first character inside of the square brackets is either an exclamation ! character or a caret ^ character, then
that first character has a special meaning of not the following characters.

To view the file names that begin with rc in the /etc directory, excluding those containing the numbers 3-6,
execute the following command:

echo /etc/rc[^3-6]*

sysadmin@localhost:~$ echo /etc/rc[^3-6]*


/etc/rc0.d /etc/rc1.d /etc/rc2.d /etc/rcS.d

Alternatively, you can use the exclamation point ! character to match the pattern from the previous step:

echo /etc/rc[!3-6]*
sysadmin@localhost:~$ echo /etc/rc[!3-6]*
/etc/rc0.d /etc/rc1.d /etc/rc2.d /etc/rcS.d

4.13 Step 13
To view all files with names beginning with rc in the /etc directory except for those that include the number 1,
execute the following command:

echo /etc/rc[!1]*

sysadmin@localhost:~$ echo /etc/rc[!1]*


/etc/rc0.d /etc/rc2.d /etc/rc3.d /etc/rc4.d /etc/rc5.d /etc/rc6.d /etc/rcS.d

Note

The wildcard characters lose their special meaning inside the [] notation and are treated as regular characters. For
example, if you specify [*]*, it will try to match with a file name starting with the asterisk * character. Typically
file names don't include wildcard characters, so this feature is rarely needed.

https://content.netdevgroup.com/labs/lpic1-s1/SzrYdqSxui/
Chapter 5: File Manipulation

Everything is considered a file in Linux. Therefore, file management is an important topic. Not only are your
documents considered files, but hardware devices such as hard drives and memory are considered files as well.
Even directories are considered files since they are special files that are used to contain other files.

The essential commands needed for file management are often named by short abbreviations of their functions.
You can use the ls command to list files, the cp command to copy files, the mv command to move or rename
files, and the rm command to remove files.

For working with directories, use the mkdir command to make directories, the rmdir command to remove
directories (if they are empty), and the rm command to recursively delete directories containing files.

Note

While permissions will be covered in greater detail later in the course, they can have an impact on file management
commands.

Permissions determine the level of access that a user has on a file. When a user runs a program and the program
accesses a file, then the permissions are checked to determine if the user has the correct access rights to the file.

There are three types of permissions: read, write, and execute. Each has a different meaning depending on whether
they are applied to a file or a directory.

Read:

 On a file, this allows processes to read the contents of the file, meaning the contents can be viewed and
copied.
 On a directory, file names in the directory can be listed, but other details are not available.

Write:

 A file can be written to by the process, so changes to a file can be saved. Note that the write permission
usually requires the read permission on the file to work correctly with most applications.
 On a directory, files can be added to or removed from the directory. Note that the write permission requires
the execute permission on the directory to work correctly.

Execute:

 A file can be executed or run as a process.


 On a directory, the user can use the cd command to "get into" the directory and use the directory in a
pathname to access files and, potentially, subdirectories under this directory.

Typically, there are two places where you should always have the write and execute permissions on the directory:
your home directory (for permanent files) and the /tmp directory (for temporary files).

Permissions will be covered in greater detail later in the course.


5.2 Listing Files
While technically not a file management command, the ability to list files using the ls command is critical to file
management. By default, the ls command will list the files in the current directory:

sysadmin@localhost:~$ ls
Desktop Documents Downloads Music Pictures Public Templates Videos

For arguments, the ls command will accept an arbitrary number of different path names to attempt to list:

ls [OPTION]... [FILE]...

Note the use of the period . character in the following example. When used where a directory is expected, it
represents the current directory.

sysadmin@localhost:~$ ls . Documents /usr/local


.:
Desktop Documents Downloads Music Pictures Public Templates Videos

/usr/local:
bin etc games include lib man sbin share src

Documents:
School alpha-third.txt hidden.txt numbers.txt spelling.tx
Work alpha.txt letters.txt os.csv words
adjectives.txt animals.txt linux.txt people.csv
alpha-first.txt food.txt longfile.txt profile.txt
alpha-second.txt hello.sh newhome.txt red.txt

However, when the period . character is used at the beginning of a file or directory name, it makes the file hidden
by default. These hidden files are not normally displayed when using the ls command, though many can be
commonly found in user home directories. Hidden files and directories are typically used for individual specific
data or settings. Using the -a option will display all files, including hidden files:

sysadmin@localhost:~$ ls -a
. .bashrc .selected_editor Downloads Public
.. .cache Desktop Music Templates
.bash_logout .profile Documents Pictures Videos

The -A option to the ls command will display almost all files of a directory. The current directory file . and the
parent directory file .. are omitted.

sysadmin@localhost:~$ ls -A
.bash_logout .profile Documents Pictures Videos
.bashrc .selected_editor Downloads Public
.cache Desktop Music Templates

The -d option to the ls command is also important. When listing a directory, the ls command normally will show
the contents of that directory, but when the -d option is added, then it will display the directory itself:

sysadmin@localhost:~$ ls -ld /var/log


drwxrwxr-x 1 root syslog 4096 Mar 8 02:11 /var/log

Listing the contents of a directory using the ls command only requires the read permission on the directory.
Command File Type Permission

ls Directory Read

Long Listing

To learn the details about a file, such as the type of file, permissions, ownership, or the timestamp, perform a long
listing, using the -l option to the ls command. Because it provides a variety of output, the /var/log directory is
listed as an example below:

sysadmin@localhost:~$ ls -l /var/log/
total 900
-rw-r--r-- 1 root root 15322 Feb 22 16:32 alternatives.log
drwxr-xr-x 1 root root 4096 Jul 19 2018 apt
-rw-r----- 1 syslog adm 560 Mar 8 02:17 auth.log
-rw-r--r-- 1 root root 35330 May 26 2018 bootstrap.log
-rw-rw---- 1 root utmp 0 May 26 2018 btmp
-rw-r----- 1 syslog adm 293 Mar 8 02:17 cron.log
-rw-r--r-- 1 root adm 85083 Feb 22 16:32 dmesg
-rw-r--r-- 1 root root 351960 Jul 19 2018 dpkg.log
-rw-r--r-- 1 root root 32064 Feb 22 16:32 faillog
drwxr-xr-x 2 root root 4096 Jul 19 2018 journal
-rw-rw-r-- 1 root utmp 292584 Mar 8 02:11 lastlog
-rw-r----- 1 syslog adm 14289 Mar 8 02:17 syslog
-rw------- 1 root root 64128 Feb 22 16:32 tallylog
-rw-rw-r-- 1 root utmp. 384 Mar 8 02:11 wtmp

Viewing the above output as fields that are separated by spaces, they indicate:

File Type

-rw-r--r-- 1 root root 15322 Feb 22 16:32 alternatives.log


drwxr-xr-x 1 root root 4096 Jul 19 2018 apt

The first character of each line indicates the type of file. The file types are:

Symbol File Type Description

d directory A file used to store other files.

- regular file Includes readable files, images files, binary files, and compressed files.

l symbolic link Points to another file.

s socket Allows for communication between processes.

p pipe Allows for communication between processes.

b block file Used to communicate with hardware.

c character file Used to communicate with hardware.


Note that alternatives.log is a regular file -, while the apt is a directory d.

Permissions

drwxr-xr-x 1 root root 4096 Jul 19 2018 journal

The next nine characters demonstrate the permissions of the file. Permissions indicate how certain users can access
a file.

The permissions are read r, write w, and execute x. Breaking this down a bit:

User Owner Group Owner Other

Read Write Execute Read Write Execute Read Write Execute

r w - r - - r - -
Permissions will be covered in greater detail later in the course.

Hard Link Count

-rw-r----- 1 syslog adm 560 Mar 8 02:17 auth.log

⁠ There is only one directory name that links to this file.

Links will be covered in greater detail later in the course.

User Owner

-rw-r----- 1 syslog adm 293 Mar 8 02:17 cron.log

The syslog user owns this file. Every time a file is created, the ownership is automatically assigned to the user
who created it. This is important because the owner has the rights to set permissions on a file.

File ownership will be covered in greater detail later in the course.

Group Owner

-rw-rw-r-- 1 root utmp 292584 Mar 8 02:11 lastlog

This indicates which group owns this file. This is important because any member of this group has a set of
permissions on the file. Although root created this file, any member of the utmp group has read and write access to
it (as indicated by the group permissions).

File ownership will be covered in greater detail later in the course.

File Size

-rw-r----- 1 syslog adm 14289 Mar 8 2018 syslog

This displays the size of the file in bytes.

Timestamp
-rw-rw---- 1 root utmp 0 May 26 2018 btmp
-rw-r--r-- 1 root adm 85083 Feb 22 16:32 dmesg

This indicates the time that the file's contents were last modified. This time would be listed as just the date and year
if the file was last modified more than six months from the current date. Otherwise, the month, day, and time is
displayed. Using the ls command with the --full-time option will display timestamps in full detail.

File Name

-rw-r--r-- 1 root root 35330 May 26 2018 bootstrap.log

The final field contains the name of the file or directory. In the case of symbolic links, the link name will be shown
along with an arrow and the path name of the file that is linked is shown.

lrwxrwxrwx. 1 root root 22 Nov 6 2012 /etc/grub.conf -> ../boot/grub/grub.conf


Links will be covered in greater detail later in the course.

While listing the contents of a directory using the ls command only requires the read permission on the directory,
viewing file details with the -l option also requires the execute permission on the directory.

Command File Type Permission

ls -l Directory Read, Execute

Sorting

The output of the ls command is sorted alphabetically by file name. It can sort by other methods as well:

Option Function

-S Sorts files by size

-t Sorts by timestamp

-r Reverses any type of sort

With both time and size sorts, add the -l option or the --full-time option, to be able to view those details:

sysadmin@localhost:~$ ls -t --full-time
total 32
drwxr-xr-x 2 sysadmin sysadmin 4096 2019-02-22 16:32:34.000000000 +0000 Desktop
drwxr-xr-x 4 sysadmin sysadmin 4096 2019-02-22 16:32:34.000000000 +0000 Documents
drwxr-xr-x 2 sysadmin sysadmin 4096 2019-02-22 16:32:34.000000000 +0000 Downloads
drwxr-xr-x 2 sysadmin sysadmin 4096 2019-02-22 16:32:34.000000000 +0000 Music
drwxr-xr-x 2 sysadmin sysadmin 4096 2019-02-22 16:32:34.000000000 +0000 Pictures
drwxr-xr-x 2 sysadmin sysadmin 4096 2019-02-22 16:32:34.000000000 +0000 Public
drwxr-xr-x 2 sysadmin sysadmin 4096 2019-02-22 16:32:34.000000000 +0000 Templates
drwxr-xr-x 2 sysadmin sysadmin 4096 2019-02-22 16:32:34.000000000 +0000 Videos

Recursion

When managing files, it is important to understand what the term recursive option means. When the recursive
option is used with file management commands, it means to apply that command to not only the specified
directory, but also to all subdirectories and all of the files within all subdirectories. To perform a recursive listing
with the ls command, add the -R option.

sysadmin@localhost:~$ ls -lR /var/log


/var/log:
total 900

-rw-r--r-- 1 root root 15322 Feb 22 16:32 alternatives.log


drwxr-xr-x 1 root root 4096 Jul 19 2018 apt
-rw-r----- 1 syslog adm 560 Mar 8 02:17 auth.log
-rw-r--r-- 1 root root 35330 May 26 2018 bootstrap.log
-rw-rw---- 1 root utmp 0 May 26 2018 btmp
-rw-r----- 1 syslog adm 293 Mar 8 02:17 cron.log
-rw-r--r-- 1 root adm 85083 Feb 22 16:32 dmesg
-rw-r--r-- 1 root root 351960 Jul 19 2018 dpkg.log
-rw-r--r-- 1 root root 32064 Feb 22 16:32 faillog
drwxr-xr-x 2 root root 4096 Jul 19 2018 journal
-rw-rw-r-- 1 root utmp 292584 Mar 8 02:11 lastlog
-rw-r----- 1 syslog adm 14289 Mar 8 02:17 syslog
-rw------- 1 root root 64128 Feb 22 16:32 tallylog
-rw-rw-r-- 1 root utmp. 384 Mar 8 02:11 wtmp

/var/log/apt:
total 144
-rw-r--r-- 1 root root 13232 Jul 19 2018 eipp.log.xz
-rw-r--r-- 1 root root 18509 Jul 19 2018 history.log
-rw-r----- 1 root adm 108711 Jul 19 2018 term.log

/var/log/journal:
total 0

Warning

Use the recursive option carefully because its impact can be huge! With the ls command, using the -R option can
result in a large amount of output in your terminal. For the other file management commands, the recursive option
can impact a large number of files and a large amount of disk space.

Consider This

Some commands use the -r option for recursion while others use the -R option. The -R option is used for recursive
with the ls command because the -r option is used for reversing how the files are sorted.

5.3 Viewing File Types


⁠When viewing a binary file in a CLI, the terminal may become corrupted and unable to display the output of other
subsequent commands correctly. To avoid viewing binary files, use the file command. The file command "looks
at" the contents of a file to report what kind of file it is; it does this by matching the content to known types stored
in a magic file.

Many commands that you will use in Linux expect that the file name provided as an argument is a text file (rather
than some sort of binary file). As a result, it is a good idea to use the file command before attempting to access a
file to make sure that it does contain text. For example, the Documents/newhome.txt file is in ASCII English text
format and can be viewed without any problem:

sysadmin@localhost:~$ file Documents/newhome.txt


Documents/newhome.txt: ASCII text

In the next example, the file /bin/ls is an Executable Link Format (ELF); this file shouldn't be displayed with the
cat command. While the cat command is able to output the contents of binary files, the terminal application may
not handle displaying the content of binary files correctly.

sysadmin@localhost:~$ file /bin/ls


/bin/ls: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically lin
ked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]
=9567f9a28e66f4d7ec4baf31cfbf68d0410f0ae6, stripped

Note

The cat command used to display the content of text files.

This command will be covered in greater detail later in the course.

Important

If you use a command that is expecting a text file argument, you may get strange results if you provide a non-text
file. Your terminal may become disrupted by attempting to output binary content; as a result, the terminal may not
be able to function properly anymore.

The result will be strange characters being displayed in the terminal. If this occurs, use the exit or logout
commands to leave the terminal you were using and then reconnect or log in again. It may also be possible to
execute the reset command. If this does not solve the problem, closing the terminal and opening a new one will
solve the problem.

5.4 Creating and Modifying Files


The touch command performs two functions. It can create an empty file or update the modification timestamp on
an existing file.

touch [OPTION]... FILE...

If the argument provided is an existing file, then the touch command will update the file's timestamp:

sysadmin@localhost:~$ ls -l Documents/red.txt
-rw-r--r-- 1 sysadmin sysadmin 51 Feb 22 16:32 Documents/red.txt
sysadmin@localhost:~$ touch Documents/red.txt
sysadmin@localhost:~$ ls -l Documents/red.txt
-rw-r--r-- 1 sysadmin sysadmin 51 Mar 8 02:59 Documents/red.txt

If the argument is a file that does not exist, a new file is created with the current time for the timestamp. The
contents of this new file will be empty:

sysadmin@localhost:~$ touch newfile


sysadmin@localhost:~$ ls
Desktop Downloads Pictures Templates newfile
Documents Music Public Videos
sysadmin@localhost:~$ ls -l newfile
-rw-rw-r-- 1 sysadmin sysadmin 0 Mar 8 03:00 newfile
Each file has three timestamps:

 The last time the file's contents were modified. This is the timestamp provided by the ls -l command by
default. The touch command modified this timestamp by default.
 The last time the file was accessed. To modify this timestamp, use the -a option with the touch command.
 The last time the file attributes were modified. These file attributes, which include permissions and file
ownership, are also called the file's metadata. To modify this timestamp, use the -c option with the touch
command.

The touch command will normally update the specified time to the current time, but the -t option with a
timestamp value can be used instead.

sysadmin@localhost:~$ touch -t 201912251200 newfile


sysadmin@localhost:~$ ls -l newfile
-rw-rw-r-- 1 sysadmin sysadmin 0 Dec 25 2019 newfile

In the above command, the date/time syntax for the touch command is CCYYMMDDHHMM (optionally add SS for the
seconds). The table below breaks down the date/time structure used in the example above in greater detail:

Syntax Example Meaning


CC 20 The century
YY 19 The year
MM 12 The month
DD 25 The day
HH 12 The hour
MM 00 The minutes

Because the example above uses the precise time of 12:00 AM, we don’t need to put 00 in the seconds (SS) field.

In order to view all three timestamps that are kept for a file, use the stat command with the path to the file as an
argument:

sysadmin@localhost:~$ stat Documents/alpha.txt


File: Documents/alpha.txt
Size: 390 Blocks: 8 IO Block: 4096 regular file
Device: 802h/2050d Inode: 5898795 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1001/sysadmin) Gid: ( 1001/sysadmin)
Access: 2019-02-22 16:32:34.000000000 +0000
Modify: 2019-02-22 16:32:34.000000000 +0000
Change: 2019-02-22 16:37:01.149507126 +0000
Birth: -

To create a file with the touch command, you must have the write and execute permission on the parent directory.
If the file already exists, modifying it with the touch command only requires the write permission on the file itself.

Command File Type Permission


touch NEW_FILE Parent Directory Write, Execute
touch EXISTING_FILE File Write
5.5 Copying Files
Creating copies of files can be useful for numerous reasons:

 If a copy of a file is created before changes are made, then it is possible to revert back to the original.
 It can be used to transfer a file to removable media devices.
 A copy of an existing document can be made; in this way, it is possible to take advantage of the existing
layout and content to get started more quickly than from scratch.

The cp command is used to copy files. It takes at least two arguments: the first argument is the path to the file to be
copied and the second argument is the path to where the copy will be placed. The files to be copied are sometimes
referred to as the source, and the location where the copies are placed is called the destination.

cp [OPTION]... SOURCE DESTINATION

Recall that the tilde ~ character represents your home directory; it is commonly used as a source or destination. To
view the current contents of the home directory, use the ls command:

sysadmin@localhost:~$ ls
Desktop Documents Downloads Music Pictures Public Templates Videos

To demonstrate how the cp command works, the /etc/services file can be copied to the home directory using
the following command:

sysadmin@localhost:~$ cp /etc/services ~

The result of executing the previous command would create a copy of the contents of the /etc/services file in
your home directory. The new file in your home directory would also be named services. The success of the cp
command can be verified using the ls command:

sysadmin@localhost:~$ ls
Desktop Downloads Pictures Templates newfile
Documents Music Public Videos services

To copy a file and rename the file in one step you can execute a command like:

sysadmin@localhost:~$ cp /etc/services ~/ports

The previous command would copy the contents of the /etc/services file into a new file named ports in your
home directory:

sysadmin@localhost:~$ ls
Desktop Downloads Pictures Templates newfile services
Documents Music Public Videos ports

To copy multiple files into a directory, additional file names to copy can be included as long as the last argument is
a destination directory:

cp [OPTION]... SOURCE... DIRECTORY

Although they may only represent one argument, a wildcard pattern can be expanded to match multiple path
names. The following command copies all files in the Documents directory that start with an n to the home
directory; as a result, newhome.txt and numbers.txt are copied.
sysadmin@localhost:~$ cp Documents/n* ~
sysadmin@localhost:~$ ls
Desktop Downloads Pictures Templates newfile numbers.txt services
Documents Music Public Videos newhome.txt ports

An issue that frequently comes up when using wildcard patterns with the cp command is that sometimes they
match the names of directories as well as regular files. If an attempt is made to copy a directory, the cp command
will print an error message.

Using the -v option makes the cp command print verbose output, so you can always tell what copies succeed as
well as those that fail. In the following wildcard example, we've marked in red the lines which indicate that the
directories were matched, but not copied.

sysadmin@localhost:~$ cp -v /etc/b* ~
'/etc/bash.bashrc' -> '/home/sysadmin/bash.bashrc'
cp: -r not specified; omitting directory '/etc/bind'
'/etc/bindresvport.blacklist' -> '/home/sysadmin/bindresvport.blacklist'
cp: -r not specified; omitting directory '/etc/binfmt.d'

In order to copy a directory, its contents must be copied as well, including all files within the directories and all of
its subdirectories. This can be done by using the -r or -R recursive options.

sysadmin@localhost:~$ cp -R -v /etc/perl ~
'/etc/perl' -> '/home/sysadmin/perl'
'/etc/perl/CPAN' -> '/home/sysadmin/perl/CPAN'
'/etc/perl/Net' -> '/home/sysadmin/perl/Net'
'/etc/perl/Net/libnet.cfg' -> '/home/sysadmin/perl/Net/libnet.cfg'

Copying a file using the cp command requires the execute permission to access the directory where the file is
located and the read permission for the file you are trying to copy.

You will also need to have the write and execute permissions on the directory where you want to put the copied
file.

Command File Type Permission


cp Source Directory Execute
cp Source File Read
cp Destination Directory Write, Execute

Consider This

The archive -a option of the cp command copies the contents of the file and also attempts to maintain the original
timestamps and file ownership. For regular users, only original timestamps can be maintained, since regular users
can't create files owned by other users. If the root user uses the -a option, then the cp command will create a new
file owned by the original file owner and also use the original file's timestamps.

The -a option also implies that recursion will be done. Therefore, it can also be used to copy a directory.

5.6 Moving Files and Directories


The mv command is used to move a file from one path name in the filesystem to another. When you move a file, it's
like creating a copy of the original file with a new path name and then deleting the original file.

mv [OPTION]... SOURCE DESTINATION

If you move a file from one directory to another, and you don't specify a new name for the file, then it will retain
its original name. For example, the following will move the ~/Documents/red.txt file into the home directory
and the resulting file name will be red.txt:

sysadmin@localhost:~$ cd Documents
sysadmin@localhost:~/Documents$ mv red.txt ~
sysadmin@localhost:~/Documents$ ls ~
Desktop Downloads Pictures Templates red.txt
Documents Music Public Videos

Like the cp command, the mv command will allow you to specify multiple files to move, as long as the final
argument provided to the command is a directory.

mv [OPTION]... SOURCE... DIRECTORY

For example:

sysadmin@localhost:~/Documents$ mv animals.txt food.txt alpha.txt /tmp


sysadmin@localhost:~/Documents$ ls /tmp
alpha.txt animals.txt food.txt

There is no need for a recursive option with the mv command. When a directory is moved, everything it contains is
automatically moved as well.

Moving a file within the same directory is an effective way to rename it. For example, in the following command,
the people.csv file is moved from the current directory to the current directory and given a new name of
founders.csv. In other words, people.csv is renamed founders.csv:

sysadmin@localhost:~/Documents$ mv people.csv founders.csv

Use the mv command to move a directory from one location to another. Just like moving files, the original directory
will be deleted from its previous location. In the following example, the mv command is used to move the
Engineering directory from the School directory to the Work directory:

sysadmin@localhost:~/Documents$ cd
sysadmin@localhost:~$ ls Documents/School
Art Engineering Math
sysadmin@localhost:~$ mv Documents/School/Engineering Documents/Work
sysadmin@localhost:~$ ls Documents/Work
Engineering

Moving a file using the mv command requires the write and execute permissions on both the origin and destination
directories.

Command File Type Permission


mv Source Directory Write, Execute
mv Destination Directory Write, Execute
5.7 Deleting Files
The rm command is used to remove files and directories.

rm [OPTION]... [FILE]...

Warning

It is important to keep in mind that deleted files and directories do not go into a "trash can" as with desktop-
oriented operating systems. When a file is deleted with the rm command, it is permanently gone.

Without any options, the rm command is typically used to remove regular files:

sysadmin@localhost:~$ cd Documents
sysadmin@localhost:~/Documents$ rm alpha.txt
sysadmin@localhost:~/Documents$ ls alpha.txt
ls: cannot access alpha.txt: No such file or directory

Extra care should be applied when using wildcards to specify which files to remove, as the extent to which the
pattern might match files may be beyond what was anticipated. To avoid accidentally deleting files when using
globbing characters, use the -i option. This option makes the rm command confirm interactively every file that you
delete:

sysadmin@localhost:~/Documents$ rm -i a*
rm: remove regular file 'adjectives.txt'? y
rm: remove regular file 'alpha-first.txt'? y
rm: remove regular file 'alpha-first.txt.original'? y
rm: remove regular file 'alpha-second.txt'? y
rm: remove regular file 'alpha-third.txt'? y
rm: remove regular file 'animals.txt'? Y
sysadmin@localhost:~/Documents$ cd
sysadmin@localhost:~$

Some distributions make the -i option a default option by making an alias for the rm command.

Deleting a file with the rm command requires the write and execute permissions on its parent directory. Regular
users typically only have this type of permission in their home directory and its subdirectories.

Command File Type Permission


rm Parent Directory Write, Execute

Consider This

The /tmp and /var/tmp directories do have the special permission called sticky bit set on them so that files in these
directories can only be deleted by the user that owns them (with the exception of the root user who can delete any
file in any directory). So, this means if you copy a file to the /tmp directory, then other users of the system will not
be able to delete your file.

5.8 Creating Directories


The mkdir command allows you to create (make) a directory. Creating directories is an essential file management
skill, since you will want to maintain some functional organization with your files and not have them all placed in a
single directory.

mkdir [OPTION]... DIRECTORY...

Typically, you have a handful of directories in your home directory by default. Exactly what directories you have
will vary due to the distribution of Linux, what software has been installed on your system, and actions that may
have been taken by the administrator.

For example, upon successful graphical login on a default installation of Ubuntu, the following directories have
already been created automatically in the user's home directory:

sysadmin@localhost:~$ ls
Desktop Documents Downloads Music Pictures Public Templates Videos

The bin directory is a common directory for users to create in their home directory. It is a useful directory to place
scripts that the user has created. In the following example, the user creates a bin directory within their home
directory:

sysadmin@localhost:~$ mkdir bin


sysadmin@localhost:~$ ls
Desktop Downloads Pictures Templates bin
Documents Music Public Videos

The mkdir command can accept a list of space-separated path names for new directories to create:

sysadmin@localhost:~$ mkdir one two three


sysadmin@localhost:~$ ls
Desktop Downloads Pictures Templates bin two
Documents Music Public Videos one three

Directories are often described in terms of their relationship to each other. If one directory contains another
directory, then it is referred to as the parent directory. The subdirectory is referred to as a child directory. In the
following example, /home is the parent directory and /sysadmin is the child directory:

sysadmin@localhost:~$ pwd
/home/sysadmin

When creating a child directory, its parent directory must first exist. If an administrator attempted to create a
directory named blue inside of the non-existent /home/sysadmin/red directory, there would be an error:

sysadmin@localhost:~$ mkdir /home/sysadmin/red/blue


mkdir: cannot create directory '/home/sysadmin/red/blue': No such file or directory

By adding the -p option, the mkdir command automatically creates the parent directories for any child directories
about to be created. This is especially useful for making deep path names:

sysadmin@localhost:~$ mkdir -p /home/sysadmin/red/blue/yellow/green


sysadmin@localhost:~$ ls -R red
red:
blue

red/blue:
yellow

red/blue/yellow:
green

red/blue/yellow/green:

To create a directory with the mkdir command, you must have the write and execute permission on the parent of
the proposed directory. For example, to create the /etc/test directory requires the write and execute permissions
in the /etc directory.

Command File Type Permission


mkdir Parent Directory Write, Execute

5.9 Removing Directories


The rmdir command is used to remove empty directories:

rmdir [OPTION]... DIRECTORY...


sysadmin@localhost:~$ rmdir bin

Using the -p option with the rmdir command will remove directory paths, but only if all of the directories contain
other empty directories.

sysadmin@localhost:~$ rmdir red


rmdir: failed to remove 'red': Directory not empty
sysadmin@localhost:~$ rmdir -p red/blue/yellow/green

Otherwise, if a directory contains anything except other directories, you'll need to use the rm command with a
recursive option. The rm command alone will ignore directories that it's asked to remove; to delete a directory, use
either the -r or -R recursive options. Just be careful as this will delete all files and all subdirectories:

sysadmin@localhost:~$ mkdir test


sysadmin@localhost:~$ touch test/file1.txt
sysadmin@localhost:~$ rmdir test
rmdir: failed to remove 'test': Directory not empty
sysadmin@localhost:~$ rm test
rm: cannot remove 'test': Is a directory
sysadmin@localhost:~$ rm -r test
sysadmin@localhost:~$
⁠ 

To delete a directory with the rmdir command, you must have the write and execute permission on the parent
directory. For example, to remove the /etc/test directory requires the write and execute permissions in the /etc
directory.

Command File Type Permission


rmdir Parent Directory Write, Execute
Key Term

cp
Command used to copy files and directories. cp will copy a SOURCE to a DEST, or multiple SOURCES to
a DIRECTORY.
Section 5.5
file
Command used to determine the type of file. file tests each argument in an attempt to classify it. There are
three sets of tests, preformed in this order: filesystem test, magic tests, and language tests.
Section 5.3
ls
Command that will list information about files. The current directory is listed by default.
| Section 5.2
mkdir
Command used to create directories, if they do not already exist.
Section 5.8
rm
Command used to remove files or directories. By default the rm command will not remove directories.
Section 5.7
rmdir
Command that is used to remove empty directories in the filesystem.
Section 5.9
touch
Command used to change the file timestamps. touch will allow a user to update the access and modification
times of each FILE to the current time.
Section 5.4
Lab 5: File Manipulation

5.0 Introduction
In this task, you will learn the commands required for managing files and directories. For Linux, everything is
considered a file, including regular files, directories, hardware devices, and sockets. The file management
commands such as ls, cp, mv, and rm are used very frequently. Similarly, to work with directories, the mkdir and
rmdir commands are used.

5.1 Step 1
The ls command is used to list files. The ls command will accept an arbitrary number of different path names to
attempt to list as arguments:

ls [OPTION]... [FILE]...

Used alone without any options, the ls command will list the files in the current directory. To list all the files in
your current working directory, execute the following command:

ls
sysadmin@localhost:~$ ls
Desktop Documents Downloads Music Pictures Public Templates Videos

5.2 Step 2
To view all the files in the current working directory, including hidden files, execute the following command:

ls -a
sysadmin@localhost:~$ ls -a
. .bashrc .selected_editor Documents Pictures Videos
.. .cache .sudo_as_admin_successful Downloads Public
.bash_logout .profile Desktop Music Templates

In the output above, the files with a period . character at the beginning, such as .bashrc and .bash_logout, are
hidden files.

5.3 Step 3
To learn the details about a file, such as the type of file, permissions, ownership, or the timestamp, perform a long
listing, using the -l option to the ls command. To display a detailed listing of the files in the /usr/lib/openssh
directory, execute the following command:

ls –l /usr/lib/openssh
sysadmin@localhost:~$ ls -l /usr/lib/openssh
total 888
-rwxr-xr-x 1 root root 700 Jan 25 2018 agent-launch
-rwxr-xr-x 1 root root 105608 Mar 4 12:17 sftp-server
-rwsr-xr-x 1 root root 436552 Mar 4 12:17 ssh-keysign
-rwxr-xr-x 1 root root 354400 Mar 4 12:17 ssh-pkcs11-helper
-rwxr-xr-x 1 root root 239 Jan 16 2018 ssh-session-cleanup

In the output above:

The first field is used to indicate the file type along with its permissions.

-rwxr-xr-x 1 root root 105608 Mar 4 12:17 sftp-server

The second field contains the number of files that are hard linked.

-rwxr-xr-x 1 root root 105608 Mar 4 12:17 sftp-server

The third and fourth fields indicate the user owner and group owner of the file.

-rwxr-xr-x 1 root root 105608 Mar 4 12:17 sftp-server

The fifth field indicates the file size in bytes.

-rwxr-xr-x 1 root root 105608 Mar 4 12:17 sftp-server

The sixth field indicates the timestamp when the file was last modified.

-rwxr-xr-x 1 root root 105608 Mar 4 12:17 sftp-server

The last field is the name of the file or directory.

-rwxr-xr-x 1 root root 105608 Mar 4 12:17 sftp-server

The output of the ls –l command is sorted alphabetically by the file name. There are other options for sorting
such as -S to sort files by size and -t to sort by modification timestamp

5.4 Step 4
To display a listing of all files in the /etc/ssh directory, sorted by file size, execute the ls command with the -l
and -S options:

ls –lS /etc/ssh
sysadmin@localhost:~$ ls -lS /etc/ssh
total 580
-rw-r--r-- 1 root root 553122 Mar 4 12:17 moduli
-rw-r--r-- 1 root root 3264 Mar 4 12:17 sshd_config
-rw------- 1 root root 1675 Mar 29 17:36 ssh_host_rsa_key
-rw-r--r-- 1 root root 1580 Mar 4 12:17 ssh_config
-rw------- 1 root root 411 Mar 29 17:36 ssh_host_ed25519_key
-rw-r--r-- 1 root root 399 Mar 29 17:36 ssh_host_rsa_key.pub
-rw-r--r-- 1 root root 338 Mar 29 17:36 ssh_import_id
-rw------- 1 root root 227 Mar 29 17:36 ssh_host_ecdsa_key
-rw-r--r-- 1 root root 179 Mar 29 17:36 ssh_host_ecdsa_key.pub
-rw-r--r-- 1 root root 99 Mar 29 17:36 ssh_host_ed25519_k
5.5 Step 5
To reverse the results of any listing option, use the -r option to the ls command. To reverse the sorting based on
file size for the /etc/ssh directory, execute the following command:

ls –lSr /etc/ssh
sysadmin@localhost:~$ ls -lSr /etc/ssh
total 580
-rw-r--r-- 1 root root 99 Mar 29 17:36 ssh_host_ed25519_key.pub
-rw-r--r-- 1 root root 179 Mar 29 17:36 ssh_host_ecdsa_key.pub
-rw------- 1 root root 227 Mar 29 17:36 ssh_host_ecdsa_key
-rw-r--r-- 1 root root 338 Mar 29 17:36 ssh_import_id
-rw-r--r-- 1 root root 399 Mar 29 17:36 ssh_host_rsa_key.pub
-rw------- 1 root root 411 Mar 29 17:36 ssh_host_ed25519_key
-rw-r--r-- 1 root root 1580 Mar 4 12:17 ssh_config
-rw------- 1 root root 1675 Mar 29 17:36 ssh_host_rsa_key
-rw-r--r-- 1 root root 3264 Mar 4 12:17 sshd_config
-rw-r--r-- 1 root root 553122 Mar 4 12:17 moduli

5.6 Step 6
The -R option is used with the ls command for a recursive listing of directories. It will display the listing of the
specified directories, as well as all other subdirectories within that directory. To display the recursive listing of all
files and directories in the /usr/lib/systemd directory, execute the following command:

ls –R /usr/lib/systemd
sysadmin@localhost:~$ ls -R /usr/lib/systemd
/usr/lib/systemd:
boot tests user-environment-generators user-preset
catalog user user-generators

/usr/lib/systemd/boot:
efi

/usr/lib/systemd/boot/efi:
linuxx64.efi.stub systemd-bootx64.efi

/usr/lib/systemd/catalog:
systemd.be.catalog systemd.de.catalog systemd.pt_BR.catalog
systemd.be@latin.catalog systemd.fr.catalog systemd.ru.catalog
systemd.bg.catalog systemd.it.catalog systemd.zh_CN.catalog
systemd.catalog systemd.pl.catalog systemd.zh_TW.catalog

/usr/lib/systemd/tests:
testdata
...
Some output has been omitted in the example above.
5.7 Step 7
To display only the directory, not the contents of the directory, use the ls command with the -d option. To list only
the /usr/lib directory, execute the following command:

ls –d /usr/lib
sysadmin@localhost:~$ ls -d /usr/lib
/usr/lib

5.8 Step 8
The wildcard characters, such as the ones used for file globbing, can be used with the ls command. For example,
execute the following command to list all the files and directories in the /etc directory starting with the letter l:

ls /etc/l*
sysadmin@localhost:~$ ls /etc/l*
/etc/ld.so.cache /etc/libaudit.conf /etc/localtime /etc/lsb-release
/etc/ld.so.conf /etc/locale.alias /etc/login.defs /etc/ltrace.conf
/etc/legal /etc/locale.gen /etc/logrotate.conf

/etc/ld.so.conf.d:
libc.conf x86_64-linux-gnu.conf

/etc/logcheck:
ignore.d.server

/etc/logrotate.d:
alternatives apt dpkg rsyslog ufw

In the output of the command above, the l* pattern matched all files that start with the letter l. Notice the
highlighted output above shows that not only was the ld.so.conf.d directory listed, but so were the contents of
this directory.

5.9 Step 9
To avoid listing the contents of directories that match (as shown in the previous step), execute the ls command
with the -d option:

ls -d /etc/l*
sysadmin@localhost:~$ ls -d /etc/l*
/etc/ld.so.cache /etc/libaudit.conf /etc/logcheck /etc/lsb-release
/etc/ld.so.conf /etc/locale.alias /etc/login.defs /etc/ltrace.conf
/etc/ld.so.conf.d /etc/locale.gen /etc/logrotate.conf
/etc/legal /etc/localtime /etc/logrotate.d
5.10 Step 10
The file command can be used to check the contents of a file to report what kind of file it is. To verify the file
type of the /etc/hosts file, execute the following command:

file /etc/hosts
sysadmin@localhost:~$ file /etc/hosts
/etc/hosts: ASCII text

Consider This

Many commands expect input files to be of a specific format, such as text. The file command is used to verify the
file type prior to running these other commands.

5.11 Step 11
To verify the file type of the /usr/bin/sudo file, execute the following command:

file /usr/bin/sudo
sysadmin@localhost:~$ file /usr/bin/sudo
/usr/bin/sudo: setuid ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically
linked, interpreter /lib64/l, for GNU/Linux 3.2.0,
BuildID[sha1]=103d78e3fba072f46aa467b5cf28b0649c08c9d3, stripped

The output of the previous command indicates that /usr/bin/sudo is an Executable Link Format (ELF), not a text
file.

5.12 Step 12
The touch command is used to create an empty file as well as update the timestamp of an existing file.

touch [OPTION]... FILE...

If the file specified as a parameter does not exist, then the touch command creates a new file. To create a new file
called testfile and verify its timestamp, execute the following commands:

touch testfile
ls –l testfile
sysadmin@localhost:~$ touch testfile
sysadmin@localhost:~$ ls -l testfile
-rw-rw-r-- 1 sysadmin sysadmin 0 May 17 14:43 testfile
5.13 Step 13
If an existing file is specified, then the touch command will update the file's timestamp with the current
timestamp. Execute the touch command and then the ls command on the newly created testfile file to update
and verify the timestamp:

touch testfile
ls –l testfile
sysadmin@localhost:~$ touch testfile
sysadmin@localhost:~$ ls -l testfile
-rw-rw-r-- 1 sysadmin sysadmin 0 May 17 14:45 testfile

5.14 Step 14
To set the timestamp to a value other than the current time, use the -t option to the touch command. For example,
execute the following commands:

touch –t 201902151435 testfile


ls –l testfile
sysadmin@localhost:~$ touch -t 201902151435 testfile
sysadmin@localhost:~$ ls -l testfile
-rw-rw-r-- 1 sysadmin sysadmin 0 Feb 15 14:35 testfile

5.15 Step 15
The touch command modifies the modification timestamp by default. There is also an access timestamp and a
change timestamp.

The stat command provides detailed information about the different timestamps associated with a file, such as the
last time the file's contents were modified, the last time the file was accessed and the last time the file attributes
were modified.

To view the different timestamps associated with the testfile file, execute the following command:

stat testfile
sysadmin@localhost:~$ stat testfile
File: testfile
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 802h/2050d Inode: 158336372 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1001/sysadmin) Gid: ( 1001/sysadmin
Access: 2019-02-15 14:35:00.000000000 +0000
Modify: 2019-02-15 14:35:00.000000000 +0000
Change: 2019-05-17 14:47:37.666082226 +0000
Birth: -
5.16 Step 16
The cp command is used to copy files. It takes at least two arguments: the first argument is the path to the file to be
copied and the second argument is the path to where the copy will be placed:

cp [OPTION]... SOURCE DESTINATION

To copy the /etc/hosts file to your home directory, execute the following command:

cp /etc/hosts ~
ls –l hosts
sysadmin@localhost:~$ cp /etc/hosts ~
sysadmin@localhost:~$ ls -l hosts
-rw-r--r-- 1 sysadmin sysadmin 172 May 17 14:49 hosts

5.17 Step 17
To copy the /etc/hosts file to your home directory and rename it as myhosts, execute the following command:

cp /etc/hosts ~/myhosts
ls –l *hosts
sysadmin@localhost:~$ cp /etc/hosts ~/myhosts
sysadmin@localhost:~$ ls -l *hosts
-rw-r--r-- 1 sysadmin sysadmin 172 May 17 14:49 hosts
-rw-r--r-- 1 sysadmin sysadmin 172 May 17 14:50 myhosts

5.18 Step 18
To view and copy the contents of the /usr/share/misc directory to the current user's home directory, execute the
following commands:

ls -ld /usr/share/misc/* ~
cp /usr/share/misc/* ~
sysadmin@localhost:~$ ls -ld /usr/share/misc/* ~
drwxr-xr-x 1 sysadmin sysadmin 4096 May 17 14:50 /home/sysadmin
lrwxrwxrwx 1 root root 13 Mar 13 16:43 /usr/share/misc/magic -> ../
file/magic
lrwxrwxrwx 1 root root 24 Mar 13 16:43 /usr/share/misc/magic.mgc ->
../../lib/file/magic.mgc
-rw-r--r-- 1 root root 1126913 Feb 10 18:25 /usr/share/misc/pci.ids
lrwxrwxrwx 1 root root 25 Apr 21 2017 /usr/share/misc/usb.ids -> /
var/lib/usbutils/usb.ids
sysadmin@localhost:~$ cp /usr/share/misc/* ~
cp: -r not specified; omitting directory '/usr/share/misc/magic'
5.19 Step 19
The cp command skips subdirectories within the source directory and displays the error omitting directory, as
shown in the output of the previous command. To include the contents of subdirectories within the source
directory, the recursive -r option must be specified. To copy the contents of the /usr/share/misc directory,
including subdirectories, to your home directory, execute the following commands:

ls
cp –r /usr/share/misc/* ~
ls
sysadmin@localhost:~$ ls
Desktop Downloads Pictures Templates hosts myhosts testfile
Documents Music Public Videos magic.mgc pci.ids usb.ids
sysadmin@localhost:~$ cp -r /usr/share/misc/* ~
sysadmin@localhost:~$ ls
Desktop Downloads Pictures Templates hosts magic.mgc pci.ids usb.ids
Documents Music Public Videos magic myhosts

5.20 Step 20
To copy the contents of a directory to your home directory while maintaining the original timestamps, the -a
option must be specified with the cp command. To view the original timestamp of the magic file contained in the
subdirectory /usr/share/misc, execute the following command:

ls -l /usr/share/misc/magic
sysadmin@localhost:~$ ls -l /usr/share/misc/magic
lrwxrwxrwx 1 root root 13 Mar 13 16:43 /usr/share/misc/magic -> ../file/magic

To copy the /usr/share/misc directory maintaining the original timestamps, execute the following command:

cp –a /usr/share/misc/* ~
sysadmin@localhost:~$ cp -a /usr/share/misc/* ~

To verify that the timestamp of the magic file copied into your home directory matches the original, execute the
following command:

ls -l magic
sysadmin@localhost:~$ ls -l magic
lrwxrwxrwx 1 sysadmin sysadmin 13 Mar 13 16:43 magic -> ../file/magic

Note

The -a option is especially effective when used by the root user because it maintains the original owner of the file
in the copied version. When a regular user uses the -a option, then the timestamp is preserved, but the new file is
owned by the user who copied the file.
5.21 Step 21
The mv command is used to move a file from one path name in the filesystem to another.

mv [OPTION]... SOURCE DESTINATION

To move the testfile file from the current directory to the ~/Public directory, execute the following command:

mv testfile ~/Public
ls -ltr ~/Public
sysadmin@localhost:~$ mv testfile ~/Public
sysadmin@localhost:~$ ls -ltr ~/Public
total 0
-rw-rw-r-- 1 sysadmin sysadmin 0 Feb 15 14:35 testfile

5.22 Step 22
To move the ~/Public/testfile file to the current directory and rename it as mytestfile, execute the following
command:

mv ~/Public/testfile ~/mytestfile
ls -lt
sysadmin@localhost:~$ mv ~/Public/testfile ~/mytestfile
sysadmin@localhost:~$ ls -ltr
total 1144
lrwxrwxrwx 1 sysadmin sysadmin 25 Apr 21 2017 usb.ids -> /var/lib/usbutils
/usb.ids
-rw-r--r-- 1 sysadmin sysadmin 1126913 Feb 10 18:25 pci.ids
-rw-rw-r-- 1 sysadmin sysadmin 0 Feb 15 14:35 mytestfile
lrwxrwxrwx 1 sysadmin sysadmin 24 Mar 13 16:43 magic.mgc -> ../../lib/file/
magic.mgc
lrwxrwxrwx 1 sysadmin sysadmin 13 Mar 13 16:43 magic -> ../file/magic
drwxr-xr-x 2 sysadmin sysadmin 4096 Apr 24 16:24 Videos
drwxr-xr-x 2 sysadmin sysadmin 4096 Apr 24 16:24 Templates
drwxr-xr-x 2 sysadmin sysadmin 4096 Apr 24 16:24 Pictures
drwxr-xr-x 2 sysadmin sysadmin 4096 Apr 24 16:24 Music
drwxr-xr-x 2 sysadmin sysadmin 4096 Apr 24 16:24 Downloads
drwxr-xr-x 4 sysadmin sysadmin 4096 Apr 24 16:24 Documents
drwxr-xr-x 2 sysadmin sysadmin 4096 Apr 24 16:24 Desktop
-rw-r--r-- 1 sysadmin sysadmin 172 May 17 14:49 hosts
-rw-r--r-- 1 sysadmin sysadmin 172 May 17 14:50 myhosts
drwxr-xr-x 1 sysadmin sysadmin 4096 May 17 15:13 Public
5.23 Step 23
The rm command is used to remove files and directories.

rm [OPTION]... [FILE]...

To delete the file mytestfile from the current directory and verify the deletion, execute the following commands:

rm mytestfile
ls –l mytestfile
sysadmin@localhost:~$ rm mytestfile
sysadmin@localhost:~$ ls -l mytestfile
ls: cannot access 'mytestfile': No such file or directory

Important

The rm command is used to remove files and directories permanently. Linux does not have the concept of a "soft
delete" where you can retrieve the contents again from a "trash can", so you should be careful when deleting files.
By default, rm will only delete files; use the -r or -R options in order to delete directories also.

5.24 Step 24
The mkdir command allows you to create (make) a directory.

mkdir [OPTION]... DIRECTORY...

To create a directory named testdir in the current directory and verify the new directory exists, execute the
following commands:

mkdir testdir
ls –d testdir/
sysadmin@localhost:~$ mkdir testdir
sysadmin@localhost:~$ ls -d testdir/
testdir/

5.25 Step 25
To create multiple directories in the current directory and verify they are created, execute the following commands:

mkdir dir1 dir2 dir3 dir4 dir5


ls –d dir?
sysadmin@localhost:~$ mkdir dir1 dir2 dir3 dir4 dir5
sysadmin@localhost:~$ ls -d dir?
dir1 dir2 dir3 dir4 dir5

Note

Recall that the question mark ? character in a string will match exactly one character.
5.26 Step 26
To create a nested structure of directories, the -p option is used with the mkdir command. To create the inner
directory which is inside the outer directory, execute the following commands:

mkdir –p outer/inner
ls –R outer
sysadmin@localhost:~$ mkdir -p outer/inner
sysadmin@localhost:~$ ls -R outer
outer:
inner

outer/inner:

5.27 Step 27
The rmdir command is used to remove empty directories:

rmdir [OPTION]... DIRECTORY...

To remove the empty testdir directory, execute the following commands:

rmdir testdir
ls –d testdir
sysadmin@localhost:~$ rmdir testdir
sysadmin@localhost:~$ ls -d testdir
ls: cannot access testdir: No such file or directory

5.28 Step 28
To remove the outer directory along with the inner subdirectory, execute the following command:

rmdir –p outer/inner/
ls –R outer/
sysadmin@localhost:~$ rmdir -p outer/inner/

To verify the outer directory and the inner subdirectory no longer exist, use the following command:

ls –R outer/
sysadmin@localhost:~$ ls -R outer/
ls: cannot access outer/: No such file or directory

5.29 Step 29
The rmdir command is used to remove empty directories. If a directory contains any files, it can be deleted using
the rm –r command.
Create a directory called newtestdir and a file within the directory called newtestfile using the following
commands:

mkdir newtestdir
touch newtestdir/newtestfile
sysadmin@localhost:~$ mkdir newtestdir
sysadmin@localhost:~$ touch newtestdir/newtestfile

Attempt to remove the newtestdir directory by executing the rmdir and rm commands without options:

rmdir newtestdir
rm newtestdir
sysadmin@localhost:~$ rmdir newtestdir
rmdir: failed to remove 'newtestdir': Directory not empty
sysadmin@localhost:~$ rm newtestdir
rm: cannot remove 'newtestdir': Is a directory

To remove the newtestdir directory, execute the following command:

rm -r newtestdir
sysadmin@localhost:~$ rm -r newtestdir
sysadmin@localhost:~$ ls -ld newtestdir
ls: cannot access 'newtestdir': No such file or directory
Chapter 6: Finding Files
6.1 Introduction
In Linux, everything is considered a file. Files are used to store data such as text, graphics, and programs.
Directories are a type of file used to store other files. This chapter will cover how to find files, which requires
knowledge about the Linux directory structure, typically called a filesystem and the filesystem standards supported
by the Linux Foundation; the Filesystem Hierarchy Standard (FHS). You will also learn about how to find files
and commands within the Linux filesystem from the command line.

6.2 Filesystem Hierarchy Standard


The open source licensing of many Linux components makes it possible for anyone to create their own distribution.
Most people start with a well-known distribution, make modifications, and release a fork of the original.

Consider This

An illustration containing many more of the distributions and their origins can be found at
http://futurist.se/gldt/wp-content/uploads/12.02/gldt1202.svg.

Since there are so many Linux distributions, it would be expected that numerous people would change the names
of the files and folders, eventually making the distributions incompatible. This makes a basic agreement necessary
concerning the naming and location of important system files and directories.
The Filesystem Hierarchy Standard (FHS) is an agreement to standardize the names and locations of directories
and their content for use within most Linux filesystems. It helps to know what directories to expect to find, and
what files one should expect to find in them. More importantly, it allows programmers to write programs that will
be able to work across a wide variety of systems that conform to this standard.

During the development of the first series of this standard from 1994 to 1995, it was known as the Filesystem
Standard (FSSTND). When the second series was started in 1997, it was renamed to the Filesystem Hierarchy
Standard (FHS). The final 2.3 version of this second series of this FHS standard was published in 2004 at
http://refspecs.linuxfoundation.org/fhs.shtml. In 2011, a draft version of the third series of this standard was
published at http://www.linuxbase.org/betaspecs/fhs/fhs.html.

The Linux file structure is best visualized as an upside-down tree, with directories and files branching out from the
top-level root / directory. While the actual standard details many more directories than listed below, the image and
table highlight some of the most important ones to know.

Directory Purpose
/ The root of the primary filesystem hierarchy.
/bin Contains essential user binary executables.
/boot Contains the kernel and bootloader files.
/dev Populated with files representing attached devices.
/etc Configuration files specific to the host.
/home Common location for user home directories.
/lib Essential libraries to support /bin and /sbin executables.
/mnt Essential libraries to support /bin and /sbin executables.
/opt Optional third-party add-on software.
Directory Purpose
/root Home directory for the root user.
/sbin Contains system or administrative binary executables.
srv May contain data provided by system services.
/tmp Location for creating temporary files.
/usr The root of the secondary filesystem hierarchy.
/usr/bin Non-vital system or administrative executables.
/usr/include Header files for compiling C-based software.
/usr/lib Shared libraries to support /usr/bin and /usr/sbin.
/usr/local The root of the third filesystem hierarchy for local software.
/usr/sbin Non-vital system or administrative executables.
/usr/share Location for architecturally-independent data files.
/usr/share/dict Word lists.
/usr/share/doc Documentation for software packages.
/usr/share/info Information pages for software packages.
/usr/share/locale Locale information.
/usr/share/man Location for man pages.
/usr/share/nls Native language support files.

Vendors of Linux distributions have continued to make some changes, even though a new version of the standard
has not been published in over ten years. Two notable new additions include the /run directory and the /sys
directory. The /run directory is being considered for use in the forthcoming FHS versions to contain volatile data
that changes at runtime. Previously, this data was supposed to be stored under the /var/run directory, but due to
the unavailability of this directory at boot time, this data can become scattered in other places, such as hidden files
in the /dev directory.

The /sys directory in some traditional UNIX systems was used to hold files related to the kernel. In modern Linux
systems, the /sys directory is used to mount the sysfs pseudo-filesystem. This filesystem is used to export
information about kernel objects and their relationships to each other. The kernel objects are represented by
directories, and the files that they contain are named for the attributes of those objects. The contents of the files
represent the value for that attribute. Symbolic links are used to represent relationships between objects.

Another notable change that some Linux distributions are making is the conversion of the /bin, /sbin and /lib
directories into symbolic links which point to /usr/bin, /usr/sbin and /usr/lib, respectively. All user
executables are now in the /usr/bin directory, administrator executables are now in the /usr/sbin directory, and
the libraries to support all these executables are now in the /usr/lib directory.

Note

A symbolic link, also called a soft link, is simply a file that points to another file.

Links will be covered in greater detail later in the course.

The merger of the /bin, /sbin and /lib directories into the /usr/bin, /usr/sbin and /usr/lib directories has
been somewhat controversial. Many administrators are comfortable with the long-standing subdivisions of these
files into different directories.
Because the way that UNIX booted, the /bin, /sbin and /lib directories had to be part of the root filesystem as
they contain critical boot executables. Some developers now argue that the reason for having them split is no
longer valid. In early versions of UNIX, the developers had two filesystems of about 1.5 MiB each on two separate
disks for the root filesystem and the /usr filesystem. As the root filesystem started to become full, the developers
decided to move some of the executable files that were in the /bin and /sbin directories that were not essential to
booting the system into the corresponding directories /usr/bin and /usr/sbin (in the separate /usr filesystem).

The FHS standard categorizes each system directory in a couple of ways for security purposes:

Shareable / Unshareable

 Shareable files can be stored on one host and used on others. For instance, /var/www is often used as the
root directory of a web server, which shares files with other hosts. Another example is the user home
directories.
 Unshareable files should not be shared between hosts. These include process states in the /var/run
directory and the /boot directory.

Variable / Static

 Static files generally do not change, including library files and documentation pages. An example is the info
pages located at /usr/share/info.
 Variable files normally change during the execution of programs. The /var/run directory contains files
that are both variable and unshareable.

The table below summarizes the main distinctions between file types:

Shareable Unshareable
/usr /etc
Static
/opt /boot
/var/mail /var/run
Variable
/var/spool/news /var/lock

6.3 Finding Files and Commands


Most operating systems allow users to search for specific files in the filesystem. A GUI typically provides a search
tool that makes it possible to find files and applications. However, there are a few commands available for
searching files and commands from the CLI. Both the locate and find commands are useful for searching for a
file within the filesystem. While both commands perform similar tasks, each does so by using a different technique,
with its own distinct advantages and disadvantages.

6.3.1 locate Command


Of the two main search commands, the locate command can be described as fast, but always potentially out-of-
date. Its speed comes from the fact that the locate command searches a database that contains the location of the
files on the filesystem, but that database needs to be updated to be accurate.
locate [OPTION]... PATTERN...

In its simplest form, the locate command accepts a search string as an argument. For example, to find a file
named passwd, use the following command:

sysadmin@localhost:~$ locate passwd


/etc/passwd
/etc/passwd-
/etc/pam.d/chpasswd
/etc/pam.d/passwd
/etc/security/opasswd
/usr/bin/gpasswd
/usr/bin/passwd
/usr/lib/tmpfiles.d/passwd.conf
/usr/sbin/chgpasswd
/usr/sbin/chpasswd
/usr/sbin/update-passwd
/usr/share/base-passwd
/usr/share/base-passwd/group.master
/usr/share/base-passwd/passwd.master
/usr/share/doc/base-passwd
/usr/share/doc/passwd
/usr/share/doc/base-passwd/README
/usr/share/doc/base-passwd/changelog.gz
/usr/share/doc/base-passwd/copyright
/usr/share/doc/base-passwd/users-and-groups.html
/usr/share/doc/base-passwd/users-and-groups.txt.gz
/usr/share/doc/passwd/NEWS.Debian.gz

A few things to consider when using the locate command:

 The locate command will only return results of files that the current user would normally have access to.
 The locate command will display all files that have the search term anywhere in the file name. For
example, the search term passwd would match both /etc/opasswd and /etc/thishaspasswdinit.
 Like most things in Linux, the locate command is case sensitive. For example, the search term passwd
would not match a file named /etc/PASSWD. To have the locate command not be case sensitive, use the -
i option.

Note

The locate command accepts the -r option to use regular expressions in the search pattern which provides a more
powerful way to search for files.

Regular expressions will be covered in greater detail later in the course.

The locate command is dependent on a database. This database can be updated manually by an administrator
using the updatedb command, though typically this command is run automatically every day through cron, a
system scheduling service that runs commands on a particular recurring schedule.

When executed, the updatedb command creates a database of all files that it finds on the computer for quick
searching. This command can only be executed by a user with administrative access, which can be achieved using
the sudo command:

sysadmin@localhost:~$ sudo updatedb


[sudo] password for sysadmin:

Note
The sudo command allows users to execute commands using the privileges of another user. The sudo command is
the preferred way to run commands with escalated privileges, and the root user is assumed by default.

The sudo command circumvents the need to login as root; this is bad practice because all commands are executed
with root privileges. This is seldom necessary and increases the risk that potentially dangerous commands may be
executed as root, even though root privileges were not required or desired.

Accordingly, some Linux distributions now prevent root logins entirely and require sudo to escalate privileges.
The system administrator must specifically authorize each user that can use the sudo command and must specify
which user(s) they can impersonate. For Linux system administrators, sudo plays a vital role is among the most
frequently used commands.

The updatedb command can be told not to search a particular name, path, or filesystem by changing the
corresponding line in its configuration file, /etc/updatedb.conf. Below is an example of the default file in its
entirety:

sysadmin@localhost:~$ cat /etc/updatedb.conf


PRUNE_BIND_MOUNTS="yes"
# PRUNENAMES=".git .bzr .hg .svn"
PRUNEPATHS="/tmp /var/spool /media /var/lib/os-prober /var/lib/ceph /home/.ecryp
tfs /var/lib/schroot"

PRUNEFS="NFS nfs nfs4 rpc_pipefs afs binfmt_misc proc smbfs autofs iso9660 ncpfs
coda devpts ftpfs devfs devtmpfs fuse.mfs shfs sysfs cifs lustre tmpfs usbfs ud
f fuse.glusterfs fuse.sshfs curlftpfs ceph fuse.ceph fuse.rozofs ecryptfs fusesm
b"

The /etc/updatedb.conf file can be edited as the root user. Any name, path, or filesystem that is listed in the file
on the appropriate line will not be added to the database. Any line starting with the # symbol will be ignored since
it is commented out.

Since the locate command works with a database, it is able to work very quickly even on a system with hundreds
of thousands of files. However, if you want to use the locate command to search for a file that was created very
recently, it will fail to find the file if the database hasn't been updated since the file creation.

Likewise, the database may contain outdated information about files that might have existed in the very recent past,
so the command will report them incorrectly as still existing.

The following example demonstrates the consequences that arise when the database is not updated in real time:

 A new file called lostfile isn't initially found by the locate command.
 sysadmin@localhost:~$ touch lostfile
sysadmin@localhost:~$ locate lostfile

 After the database is updated by the updatedb command, the locate command can find the lostfile file.
 sysadmin@localhost:~$ sudo updatedb
 [sudo] password for sysadmin:
 sysadmin@localhost:~$ locate lostfile
/home/sysadmin/lostfile

 After the lostfile file has been deleted, the locate command will still report that the file exists.
 sysadmin@localhost:~$ rm lostfile
 sysadmin@localhost:~$ locate lostfile
/home/sysadmin/lostfile
6.3.2 find Command
If you want to search for files that are currently in the filesystem, then you should use the find command. The
find command is slower than the locate command because it searches directories in real time; however, it doesn't
suffer from problems associated with an outdated database.

The find command expects a directory as the first argument. This will be the starting point of the search. The find
command will search this directory and all of its subdirectories. If no directory is specified, then the find
command will start the search at the current directory.

find [OPTIONS]... [starting-point...] [expression]

Note that the period . character refers to the current directory in the following example, but the current directory
could also be referred to using the ./ notation. The find command uses the -name option to search for files by
name, in this case, the Downloads directory.

sysadmin@localhost:~$ find . -name Download


sysadmin@localhost:~$ find . -name Downloads
./Downloads
sysadmin@localhost:~$ find . -name Dow*
./Downloads
sysadmin@localhost:~$ find . -name 'Do*'
./Documents
./Downloads

The first search yielded no results because the string must match the exact name of the file, not just part of the
name. The third command demonstrates that globbing can be used, and the fourth command demonstrates multiple
matches (notice that single quotes were added so that the find command will interpret the glob, rather than the
shell).

If the search for the Downloads directory was conducted from the root / directory, many errors would arise:

sysadmin@localhost:~$ find / -name Downloads


find: '/var/lib/apt/lists/partial': Permission denied
find: '/var/cache/ldconfig': Permission denied
find: '/var/cache/apt/archives/partial': Permission denied
find: '/var/spool/rsyslog': Permission denied
find: '/var/spool/cron/crontabs': Permission denied
find: '/etc/ssl/private': Permission denied
find: '/root': Permission denied
Output Omitted...

These errors can be ignored for now, but just be aware that errors like these are typical when either a regular user is
attempting to search root-only areas, or when the root user is attempting to search areas that are dedicated to the
system’s processes.

The find command also offers many options for searching files, unlike the locate command which searches only
for files based on file name. The following table illustrates some of the more commonly used criteria:

⁠ 
Example Meaning
-iname LOSTFILE Case insensitive search by name.
-mtime -3 Files modified less than three days ago.
-mmin -10 Files modified less than ten minutes ago.
Example Meaning
-size +1M Files larger than one megabyte.
-user joe Files owned by the user joe.
-nouser Files not owned by any user.
-empty Files that are empty.
-type d Files that are directory files.
-maxdepth 1 Do not use recursion to enter subdirectories; only search the primary directory.

If multiple criteria are specified, then all criteria must match as the find command automatically assumes a logical
AND condition between criteria, meaning all of the conditions must be met. This could be explicitly stated by using
the -a option between criteria. For example, the Downloads directory must also be owned by the sysadmin user in
order for the find command to produce a result in the following example:

sysadmin@localhost:~$ find . -user sysadmin -a -name Downloads


./Downloads

Logical OR conditions can be specified between criteria with the -o option, meaning at least one of the conditions
must be true. The following output lists files that are either named Downloads or owned by the sysadmin user.

sysadmin@localhost:~$ find . -user sysadmin -o -name Downloads


.
./Public
./Downloads
./Pictures
./Videos
./.selected_editor
./.profile
./.bash_logout
...

Logical groupings of criteria can also be specified using the parentheses. Be careful to precede the parentheses with
a backslash or to use single quotes around them so that the shell doesn't attempt to interpret them as special
characters. Also, as mentioned previously, use quotes around any globs that the find command should interpret
instead of the shell, as shown in the following example:

sysadmin@localhost:~$ find . -iname 'desk*' -o \( -name Downloads -a -user sysadmin \)


./Desktop
./Downloads

In plain text, the find command in the preceding example will return files in the current directory, with the non-
case sensitive name starting with desk OR files with the exact name Downloads owned by the sysadmin user.

By default, the find command simply prints the names of the files that it finds. To generate output showing
additional file details, similar the ls -l command, you can specify the -ls option:

sysadmin@localhost:~$ find . -ls -iname 'desk*' -o \( -name Downloads -a -user sysadmin \)


209950600 4 drwxr-xr-x 1 sysadmin sysadmin 4096 Mar 10 04:08 .
210019331 4 drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 8 19:10 ./Templates
102108986 4 -rw-r--r-- 1 sysadmin sysadmin 220 Apr 4 2018 ./.bash_logout
102108988 4 -rw-r--r-- 1 sysadmin sysadmin 807 Apr 4 2018 ./.profile
210019332 4 drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 8 19:10 ./Downloads
...

To make the output exactly like the output of the ls -l command, use the -exec option to execute ls -l on each
file found. For example:
sysadmin@localhost:~$ find -name 'Documents' -exec ls -l {} \;
total 1100
drwxr-xr-x 5 sysadmin sysadmin 4096 Mar 8 19:10 School
drwxr-xr-x 2 sysadmin sysadmin 4096 Mar 8 19:10 Work
-rw-r--r-- 1 sysadmin sysadmin 39 Mar 8 19:10 adjectives.txt
-rw-r--r-- 1 sysadmin sysadmin 90 Mar 8 19:10 alpha-first.txt
-rw-r--r-- 1 sysadmin sysadmin 106 Mar 8 19:10 alpha-second.txt
-rw-r--r-- 1 sysadmin sysadmin 195 Mar 8 19:10 alpha-third.txt
...

The previous example tells the find command to execute the ls -l command for each file found. The pair of curly
braces {} is a placeholder for the name of each file found; note that there is no space between them. The \; is an
escaped semicolon that is added between each command so that multiple commands may be executed in series.

In order to make the find command confirm the execution of the command for each file found, use the action
option -ok instead of the -exec option:

sysadmin@localhost:~$ touch one two three


sysadmin@localhost:~$ find . -mmin -2 -ok rm {} \;
< rm ... . > ? n
< rm ... ./one > ? y
< rm ... ./two > ? y
< rm ... ./three > ? y

The command above tells the find command to execute the rm command for files that were modified less than two
minutes ago. Did you notice how the first file that the rm command tried to remove was the current directory
(represented by the period. character)? That is enough reason not to use the -exec option because the rm command
would have tried to remove the current directory.

There will be situations where it’s useful to find a file or set of files depending on their age, or when they were last
modified, such as all files that have been changed since a given time (such as the last backup). The modification
time -mtime option to the find command provides the ability to give time as criteria for a search.

First, a word about how the find command uses times is relevant here. When looking for files modified within the
period of a day, such as 3 days ago, you would use -mtime 3, but if you are looking for files that have changed
anytime between 3 days ago and now, you would use -mtime -3. If you are looking to find files older than 3 days,
you would use -mtime +3.

Option Function
-mtime N Files modified N*24 hours ago.
-mtime -N Files modified less than N*24 hours ago.
-mtime +N Files modified more than N*24 hours ago.

To summarize, a number without a + or - means exactly N days ago, a number with a - means anytime between N
days ago and NOW, and a number with a + means N days ago or more.

For example, if you backup every seven days, use the following command to backup all files that are 3 days or less
old:

sysadmin@localhost:~$ find /tmp -mtime -3


/tmp

The above command starts in the /tmp directory and finds all files that have been modified in the last three 24-hour
periods, or 72 hours.
The find command is less exact by default than you might want it to be. When using numbers of days with the -
atime, -ctime or -mtime operators, the days refer to 24-hour blocks. Therefore, you may think that you are
searching to find all files that occurred between now and your last backup by referring to that day, but depending
on the time of day, you may not have found all of the files.

Since the find command’s time operators are effectively tied to 24-hour blocks or days, you can use a reference
file to make certain you have found all files that occurred precisely since your last backup.

To find all files that are newer than your last backup, find out the date and time of that backup, and create a
reference file with that date/time so you can use it with the find -newer command. For example, if the backup
was done at precisely 2300 (11:00 PM) on the 1st of March, 2020, you can create a reference file with that exact
date and time with the following command:

sysadmin@localhost:~$ touch -t 202003012300 /tmp/reference_file

Now that we have a file that mirrors precisely the date and time of our last backup, we can search for all files in the
/home directory that might have been created or modified since the last backup date with the following command:

sysadmin@localhost:~$ find /home -newer /tmp/reference_file


/home
/home/sysadmin
/home/sysadmin/Templates
/home/sysadmin/Downloads
/home/sysadmin/Music
/home/sysadmin/.selected_editor
/home/sysadmin/Documents
/home/sysadmin/Documents/alpha-third.txt
/home/sysadmin/Documents/spelling.txt
/home/sysadmin/Documents/profile.txt
/home/sysadmin/Documents/numbers.txt
/home/sysadmin/Documents/animals.txt
/home/sysadmin/Documents/hidden.txt
/home/sysadmin/Documents/people.csv
/home/sysadmin/Documents/alpha.txt
...

Note

The output will vary, depending on what your system includes for users and what they have been doing, but
typically at least the current user’s .bash_history file will appear as having been changed.

The find command also allows the use of friendly notation to find files that are larger or smaller than a particular
size. Trying to find files that are above 1 Kilobyte on a busy system is like searching for the word “the” on Google;
so much output is returned it’s essentially useless. When searching for files of a given size, or those that are smaller
or larger than a given size, try to restrict the search to the smallest valid set of directories and files possible.

For example, to find all files that are smaller than 1 Kilobyte in the /etc directory, you would use:

sysadmin@localhost:~$ find /etc -size -1k


/etc/.pwd.lock
/etc/security/opasswd
/etc/apparmor.d/local/sbin.dhclient
/etc/apparmor.d/local/usr.sbin.rsyslogd
/etc/apparmor.d/local/usr.sbin.named
/etc/apparmor.d/local/usr.bin.man
find: '/etc/ssl/private': Permission denied
/etc/newt/palette.original
If the files are smaller than 1 Kilobyte, they will be listed as output. You can also use the -size option to find all
files on the system that are 1 Megabyte or more with the command:

sysadmin@localhost:~$ find / -size +1M


find: '/proc/tty/driver': Permission denied
find: '/proc/1/task/1/fd': Permission denied
find: '/proc/1/task/1/fdinfo': Permission denied
find: '/proc/1/task/1/ns': Permission denied
find: '/proc/1/fd': Permission denied
find: '/proc/1/map_files': Permission denied
find: '/proc/1/fdinfo': Permission denied
find: '/proc/1/ns': Permission denied
...

Consider This

The -size option rounds up, to ensure that the find command will display the results you want.

For example, if you have three files, one less than 512 Kilobytes in size, one above 512 Kilobytes but less than
1024 Kilobytes in size, and one that is above 1024 Kilobytes in size, the -size option will not show anything for
the output of -size -1M, since it rounds down to 0.

The output of -size -512K would show only the file that is 512K or less, and if you run the -size +512K
command, the output would show both the file that is 512K or more and the file that is 1024K or more. You may
wish to experiment with this option so you know what to expect.

The find command can also help you find files by specifying a file type, such as regular file, directory, and more,
using the -type option. The table below shows all the different types of files you can find using the -type option:

Symbol File Type


b Block (i.e., disks, storage)
c Character (i.e., keyboards, scanners, mice)
d Directory (directory files)
p Named pipes (Allows for communication between processes)
f Regular file (i.e., scripts, text files, graphics)
s Sockets (Allows for communication between processes)

To demonstrate, in order to search only for directories under the /home directory, you could use the following
command:

sysadmin@localhost:~$ find /home/sysadmin -type d


/home/sysadmin
/home/sysadmin/Desktop
/home/sysadmin/Templates
/home/sysadmin/Documents
/home/sysadmin/Documents/Work
/home/sysadmin/Documents/School
/home/sysadmin/Documents/School/Engineering
/home/sysadmin/Documents/School/Art
/home/sysadmin/Documents/School/Math
/home/sysadmin/Music
/home/sysadmin/Public
/home/sysadmin/Pictures
/home/sysadmin/Videos
/home/sysadmin/Downloads
/home/sysadmin/.cache

The command above will search the /home/sysadmin directory tree structure and filter out all results except for
files that are the specified directory type.

Consider This

To limit the search to just a single level below the /home directory, -maxdepth option to the find command can be
used. The -maxdepth option can be set to almost any numeric value. For example, a depth of 1 will show the top-
level directories in the /home/sysadmin directory:

sysadmin@localhost:~$ find /home/sysadmin -type d -maxdept

6.3.3 whereis Command


There are many commands available to the operating system, and it is sometimes useful to know where they are.
The whereis command can be used to search your PATH for the binary. It is also capable of searching for the man
page, and source files for any given command.

whereis [OPTION]... NAME...

The echo command can be used to determine which directories are in the PATH:

sysadmin@localhost:~$ echo $PATH


/home/sysadmin/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/
usr/local/games

To find out where the grep command is located, use whereis without any options:

sysadmin@localhost:~$ whereis grep


grep: /bin/grep /usr/share/man/man1/grep.1.gz /usr/share/info/grep.info.gz

The output of the whereis command returns three directories. The first is where the grep command is located, in
the /bin/grep directory. There is also a path given for the man page of the grep command at
/usr/share/man/man1/grep.1.gz and another path for the info page at /usr/share/info/grep.info.gz.
Without an option, the whereis command provides all three pieces of information.

To view the location of the binary separate from the man page and info page, use the -b and -m options
respectively:

sysadmin@localhost:~$ whereis -b grep


grep: /bin/grep
sysadmin@localhost:~$ whereis -m grep
grep: /usr/share/man/man1/grep.1.gz /usr/share/info/grep.info.gz

The -s option can be used to find source code that has been installed for a given command. In the case of grep,
only the binary is currently installed:

sysadmin@localhost:~$ whereis -s grep


grep:

Notice that no results are returned because the source code for the grep command is not installed.
The -u option can be used to identify commands that do not have an entry for a requested attribute. To find out
which commands in the /bin directory do not have man pages, use the following command:

sysadmin@localhost:~$ cd /bin
sysadmin@localhost:/bin$ whereis -m -u *
dir: /usr/share/man/man1/dir.1.gz /usr/share/info/dir /usr/share/info/dir.old
grep: /usr/share/man/man1/grep.1.gz /usr/share/info/grep.info.gz
gzip: /usr/share/man/man1/gzip.1.gz /usr/share/info/gzip.info.gz
hostname: /usr/share/man/man7/hostname.7.gz /usr/share/man/man5/hostname.5.gz /u
sr/share/man/man1/hostname.1.gz
ip: /usr/share/man/man7/ip.7.gz /usr/share/man/man8/ip.8.gz
nano: /usr/share/man/man1/nano.1.gz /usr/share/info/nano.info.gz
sed: /usr/share/man/man1/sed.1.gz /usr/share/info/sed.info.gz
sysadmin@localhost:/bin$ cd
sysadmin@localhost:~$

In the previous example, the asterisk * character is used to consider every file in the current directory.

The example below identifies a specific command that does not have a man page:

sysadmin@localhost:~$ whereis type

This means that there is no man page for the type command:

sysadmin@localhost:~$ man type


No manual entry for type

If the same example is repeated for the ls command, there will be no output because ls has a man page.

sysadmin@localhost:~$ whereis ls
ls: /bin/ls /usr/share/man/man1/ls.1.gz

To limit the search to a specific path or paths, capitalized options can be used. The -B option searches for binaries,
the -M option for manuals and documentation, and the -S option for sources. The -f option must be used to
indicate the end of the path list and the beginning of the search term.

whereis [OPTION]... [-BMS directory… -f] name...


sysadmin@localhost:~$ whereis -B /home/sysadmin/ -f Desktop
Desktop: /home/sysadmin//Desktop

This type of searching, however, may be best left to the find command, as it allows for more specific criteria to be
used in a search.

6.3.4 which Command


Sometimes the whereis command returns more than one result on a command. In this case, an administrator would
want to know which command is being used.

which [-a] FILENAME...

The bash command is an example that normally yields two results:

sysadmin@localhost:~$ whereis -b bash


bash: /bin/bash /etc/bash.bashrc
To find out which bash result is the real command, in other words, the result that is used when executing the
command, use the which command:

sysadmin@localhost:~$ which bash


/bin/bash

The -a option can be used with the which command to locate multiple executable files. This would be useful to
know if an executable script was inserted maliciously to override an existing command.

sysadmin@localhost:~$ which -a ping


/bin/ping

By using the which command, an administrator can be fairly certain that the only executable running by the name
of the ping command is located in the /bin directory.

6.3.5 type Command


The type command can be used to determine information about various commands.

type [OPTION]... NAME...

Some commands originate from a specific file:

sysadmin@localhost:~$ type which


which is /usr/bin/which

This output would be similar to the output of the which command:

sysadmin@localhost:~$ which which


/usr/bin/which

The type command can also identify commands that are built into the Bash (or other) shell:

sysadmin@localhost:~$ type echo


echo is a shell builtin

This output is significantly different than the output of the which command:

sysadmin@localhost:~$ which echo


/bin/echo

Using the -a option, the type command can also reveal the path of another command:

sysadmin@localhost:~$ type -a echo


echo is a shell builtin
echo is /bin/echo

The type command can also identify aliases to other commands:

sysadmin@localhost:~$ type ll
ll is aliased to `ls -alF'
sysadmin@localhost:~$ type ls
ls is aliased to `ls --color=auto'
The output of these commands indicates that ll is an alias for ls -alF, and even ls is an alias for ls --
color=auto. Again, the output is significantly different than the which command:

sysadmin@localhost:~$ which ll
sysadmin@localhost:~$ which ls
/bin/ls

The type command supports other options, and can lookup multiple commands simultaneously. To display only a
single word describing the echo, ll, and which commands, use the -t option:

sysadmin@localhost:~$ type -t echo ll which


builtin
alias
file

Sumber : https://content.netdevgroup.com/contents/lpic1-s1/1YpkgvdWxD/
Key Term
/etc/updatedb.conf
A configuration file for the updatedb utility. In some implementations, updatedb.conf is a shell script that
allows more flexibility in defining variables
Section 6.3.1
find
Command used to search for files in a directory hierarchy. find searches the directory tree rooted at each
given file name by evaluating the given the expression from left to right.
Section 6.3.2
locate
Command used to search for files by name. locate reads one or more databases prepared by the updatedb
utility and writes file names matching at least one of the PATTERNs to standard output.
Section 6.3.1
type
Command that indicates how a name would be interpreted if used as a command. When using the type
utility, the path to the command will be displayed.
Section 6.3.5
updatedb
The updatedb utility creates or updates a database to be used by the locate utility.
Section 6.3.1
whereis
Command that is used to locate source/binary and manuals sections for specified rules. This will locate
binary, source, and manual pages for a command.
Section 6.3.3
which
Command that returns the pathnames of the files, or links, which would be executed in the current
environment. It does this by searching the PATH for executables matching the names of the arguments.
Section 6.3.4
LAB 06

6.0 Introduction
In Linux, files are used to store data such as text, graphics, and programs; while directories are a type of file used
to store other files. In this lab, we will cover how to find files in the Linux directory structure, called a filesystem.

The locate and find commands are used to search for a file within a file system. While both commands perform
similar tasks, each does so by using a different technique, with its own distinctive advantages and disadvantages.
The locate command uses a database that is updated once a day using a cron job, while the find command
searches the live filesystem.

It is also useful to know where commands are located in the filesystem. The whereis command can be used to
search the PATH, the man page and source files for any given command. The which command can be used to find
out which executable file is used when executing a command. In addition, the type command can be used to
determine information about various commands.

6.1 Step 1
The locate command searches a database that contains the location of the files on the filesystem. The locate
command accepts a search string as an argument.

locate [OPTION]... PATTERN...

To locate all files which have the word hostname in the file name, execute the following command:

locate hostname
sysadmin@localhost:~$ locate hostname
/bin/hostname
/etc/hostname
/lib/systemd/systemd-hostnamed
/lib/systemd/system/dbus-org.freedesktop.hostname1.service
/lib/systemd/system/hostname.service
/lib/systemd/system/systemd-hostnamed.service
/usr/bin/hostnamectl
/usr/lib/gettext/hostname
/usr/lib/python3/dist-packages/urllib3/packages/ssl_match_hostname
/usr/lib/python3/dist-packages/urllib3/packages/ssl_match_hostname/__init__.py
/usr/lib/python3/dist-packages/urllib3/packages/ssl_match_hostname/__pycache__
/usr/lib/python3/dist-packages/urllib3/packages/ssl_match_hostname/_implementati
on.py
/usr/lib/python3/dist-packages/urllib3/packages/ssl_match_hostname/__pycache__/_
_init__.cpython-36.pyc
/usr/lib/python3/dist-packages/urllib3/packages/ssl_match_hostname/__pycache__/_
implementation.cpython-36.pyc
/usr/share/bash-completion/completions/hostname
/usr/share/bash-completion/completions/hostnamectl
/usr/share/dbus-1/system-services/org.freedesktop.hostname1.service
/usr/share/dbus-1/system.d/org.freedesktop.hostname1.conf
...
Some output has been omitted in the example above.
6.2 Step 2
To locate all files which have the word hostname in the file name and make the search case insensitive, execute the
following command:

locate –i hostname
sysadmin@localhost:~$ locate -i hostname
/bin/hostname
/etc/hostname
/lib/systemd/systemd-hostnamed
/lib/systemd/system/dbus-org.freedesktop.hostname1.service
/lib/systemd/system/hostname.service
/lib/systemd/system/systemd-hostnamed.service
/usr/bin/hostnamectl
/usr/lib/gettext/hostname
/usr/lib/python3/dist-packages/urllib3/packages/ssl_match_hostname
/usr/lib/python3/dist-packages/urllib3/packages/ssl_match_hostname/__init__.py
/usr/lib/python3/dist-packages/urllib3/packages/ssl_match_hostname/__pycache__
/usr/lib/python3/dist-packages/urllib3/packages/ssl_match_hostname/_implementation.py
/usr/lib/python3/dist-
packages/urllib3/packages/ssl_match_hostname/__pycache__/__init__.cpython-36.pyc
/usr/lib/python3/dist-
packages/urllib3/packages/ssl_match_hostname/__pycache__/_implementation.cpython-36.pyc
/usr/lib/x86_64-linux-gnu/perl/5.26.1/Sys/Hostname.pm
/usr/lib/x86_64-linux-gnu/perl/5.26.1/auto/Sys/Hostname
/usr/lib/x86_64-linux-gnu/perl/5.26.1/auto/Sys/Hostname/Hostname.so
...
Some output has been omitted in the example above for brevity.

6.3 Step 3
The locate command will only return results of files that the current user would normally have access to. The
find command will search a directory and all of its subdirectories (including files that the current user may not
have access to).

find [OPTIONS]... [starting-point...] [expression]

The find command searches for files by name when the -name option is used. To find the hostname file in the
/etc directory, execute the following command:

find /etc -name hostname


sysadmin@localhost:~$ find /etc/ -name hostname
/etc/hostname
find: '/etc/ssl/private': Permission denied

The find command generates a lot of output related to files that it cannot access due to inadequate permissions. To
suppress this type of output, redirect it to /dev/null, as shown in the example below. To find the hostname file in
the /etc directory and also redirect the error stream, execute the following command:

find /etc -name hostname 2>/dev/null


sysadmin@localhost:~$ find /etc -name hostname 2>/dev/null
/etc/hostname
6.4 Step 4
The find command has options to find files per their timestamps. To find all files in the /etc directory which were
modified less than 2 days ago, execute the following command:

find /etc -mtime -2 2>/dev/null


sysadmin@localhost:~$ find /etc -mtime -2 2>/dev/null
/etc
/etc/alternatives
/etc/alternatives/editor
/etc/alternatives/editor.pl.1.gz
/etc/alternatives/editor.fr.1.gz
/etc/alternatives/editor.it.1.gz
/etc/alternatives/editor.ru.1.gz
/etc/alternatives/editor.ja.1.gz
/etc/alternatives/editor.1.gz
/etc/subgid
/etc/skel
/etc/skel/.bashrc
/etc/skel/.selected_editor
/etc/hosts
/etc/gshadow
/etc/resolv.conf
...
Some output has been omitted in the example above.

6.5 Step 5
To find all files which were modified less than 30 minutes ago in the /etc directory, execute the following
command:

find /etc -mmin -30 2>/dev/null


sysadmin@localhost:~$ find /etc -mmin -30 2>/dev/null
/etc
/etc/resolv.conf
/etc/hosts
/etc/hostname
/etc/mtab

6.6 Step 6
To find files which are larger than 8MB in size, execute the following command:

find / -size +8M 2>/dev/null


sysadmin@localhost:~$ find / -size +8M 2>/dev/null
/usr/lib/x86_64-linux-gnu/libicudata.so.60.2
/lib/udev/hwdb.bin
/var/lib/apt/lists/archive.ubuntu.com_ubuntu_dists_bionic_universe_binary-amd64_Packages.lz4
/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/resource0
/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.1/resource0
/sys/devices/pci0000:00/0000:00:03.0/0000:02:00.0/resource0
/sys/devices/pci0000:00/0000:00:03.0/0000:02:00.1/resource0
6.7 Step 7
To find all empty files in your home directory, execute the following commands:

touch sample
find ~/ -empty 2>/dev/null
sysadmin@localhost:~$ touch sample
sysadmin@localhost:~$ find ~/ -empty 2>/dev/null
/home/sysadmin/Videos
/home/sysadmin/Documents/Work/.emptydir
/home/sysadmin/Templates
/home/sysadmin/Music
/home/sysadmin/Pictures
/home/sysadmin/Public
/home/sysadmin/Downloads
/home/sysadmin/Desktop
/home/sysadmin/sample
/home/sysadmin/.cache/motd.legal-displayed

6.8 Step 8
To find all files that are directory files in your home directory, execute the following commands:

mkdir dir1 dir2 dir3


find ~/ -type d 2>/dev/null
sysadmin@localhost:~$ find ~/ -type d 2>/dev/null
/home/sysadmin/
/home/sysadmin/Videos
/home/sysadmin/Documents
/home/sysadmin/Documents/Work
/home/sysadmin/Documents/School
/home/sysadmin/Documents/School/Art
/home/sysadmin/Documents/School/Math
/home/sysadmin/Documents/School/Engineering
/home/sysadmin/Templates
/home/sysadmin/Music
/home/sysadmin/Pictures
/home/sysadmin/Public
/home/sysadmin/Downloads
/home/sysadmin/Desktop
/home/sysadmin/dir3
/home/sysadmin/.cache
/home/sysadmin/dir1
/home/sysadmin/dir2

6.9 Step 9
To display a count of all of the files in the /etc directory structure that end in .conf, execute the following
command:

find /etc -name "*.conf" 2>/dev/null | wc -l


Be aware that the last option in the command above is a lowercase "L", not a number one.
sysadmin@localhost:~$ find /etc -name "*conf" 2>/dev/null | wc -l
92
6.10 Step 10
To limit the depth that the find command searches, use the -maxdepth option:

find /etc -name "*.conf" -maxdepth 1 2>/dev/null | wc -l


sysadmin@localhost:~$ find /etc -name "*.conf" -maxdepth 1 2>/dev/null | wc -l
21

6.11 Step 11
To find all files starting with hosts in the /etc directory structure and display detailed information about the files,
use the following command:

find /etc -name "hosts*" -ls 2>/dev/null


sysadmin@localhost:~$ find /etc -name "hosts*" -ls 2>/dev/null

196477184 4 -rw-r--r-- 1 root root 172 Apr 12 14:20 /etc/hosts


196477187 4 -rw-r--r-- 1 root root 10 Apr 12 14:20 /etc/hostname
129630991 4 -rw-r--r-- 1 root root 92 Apr 9 2018 /etc/host.conf
130286175 4 -rw-r--r-- 1 root root 411 Mar 29 17:36 /etc/hosts.allow
130286176 4 -rw-r--r-- 1 root root 711 Mar 29 17:36 /etc/hosts.deny

6.12 Step 12
The -exec option is used to execute a specific command using the results of find as the input. To find all files in
your home directory that end in .conf and delete them with the rm command, execute the following commands:

cp /etc/*.conf .
ls
find ~ -name "*.conf" –exec rm {} \;
ls
sysadmin@localhost:~$ cp /etc/*.conf .
sysadmin@localhost:~$ ls
Desktop ca-certificates.conf host.conf resolv.conf
Documents debconf.conf ld.so.conf rsyslog.conf
Downloads deluser.conf libaudit.conf sample
Music dir1 logrotate.conf sysctl.conf
Pictures dir2 ltrace.conf ucf.conf
Public dir3 mke2fs.conf updatedb.conf
Templates fuse.conf nsswitch.conf
Videos gai.conf pam.conf
adduser.conf hdparm.conf popularity-contest.conf
sysadmin@localhost:~$ find ~ -name "*.conf" -exec rm {} \;
sysadmin@localhost:~$ ls
Desktop Downloads Pictures Templates dir1 dir3
Documents Music Public Videos dir2 sample

6.13 Step 13
The -ok option is used to execute a specific command using the results of the find command as the input after
confirming with the user. To find all files that end with the word .conf and then delete them interactively, execute
the following commands:

cp /etc/*.conf .
ls
find ~ -name "*.conf" –ok rm {} \;

When prompted, type y to delete each directory interactively:

< rm ... /home/sysadmin/debconf.conf > ? y


sysadmin@localhost:~$ cp /etc/*.conf .
sysadmin@localhost:~$ ls
Desktop ca-certificates.conf host.conf resolv.conf
Documents debconf.conf ld.so.conf rsyslog.conf
Downloads deluser.conf libaudit.conf sample
Music dir1 logrotate.conf sysctl.conf
Pictures dir2 ltrace.conf ucf.conf
Public dir3 mke2fs.conf updatedb.conf
Templates fuse.conf nsswitch.conf
Videos gai.conf pam.conf
adduser.conf hdparm.conf popularity-contest.conf
sysadmin@localhost:~$ find ~ -name "*.conf" -ok rm {} \;
< rm ... /home/sysadmin/debconf.conf > ? y
< rm ... /home/sysadmin/fuse.conf > ? y
< rm ... /home/sysadmin/sysctl.conf > ? y
< rm ... /home/sysadmin/updatedb.conf > ? y
< rm ... /home/sysadmin/logrotate.conf > ? y
< rm ... /home/sysadmin/gai.conf > ? y
< rm ... /home/sysadmin/popularity-contest.conf > ? y
< rm ... /home/sysadmin/rsyslog.conf > ? y
< rm ... /home/sysadmin/ca-certificates.conf > ? y
< rm ... /home/sysadmin/resolv.conf > ? y
< rm ... /home/sysadmin/hdparm.conf > ? y
< rm ... /home/sysadmin/pam.conf > ? y
< rm ... /home/sysadmin/libaudit.conf > ? y
< rm ... /home/sysadmin/deluser.conf > ? y
< rm ... /home/sysadmin/ltrace.conf > ? y
< rm ... /home/sysadmin/ld.so.conf > ? y
< rm ... /home/sysadmin/adduser.conf > ? y
< rm ... /home/sysadmin/nsswitch.conf > ? y
< rm ... /home/sysadmin/host.conf > ? y
< rm ... /home/sysadmin/mke2fs.conf > ? y
< rm ... /home/sysadmin/ucf.conf > ? y

6.14 Step 14
The whereis command can be used to search the source files for any given command.

whereis [OPTION]... NAME...

To find out where the find command is located, use the whereis command without any options:

whereis find
sysadmin@localhost:~$ whereis find
find: /usr/bin/find /usr/share/man/man1/find.1.gz /usr/share/info/find.info.gz
The output of the whereis command returns three directories. The first is where the find command is located, in
the usr/bin/find directory. There is also a path given for the man page of the find command at
/usr/share/man/man1/find.1.gz and another path for the info page at /usr/share/info/find.info.gz.

6.15 Step 15
To view the location of the binary for the find command separate from the man page and info page, use the -b and
-m options respectively:

whereis -b find
whereis -m find
sysadmin@localhost:~$ whereis -b find
find: usr/bin/find
sysadmin@localhost:~$ whereis -m find
find: /usr/share/man/man1/find.1.gz /usr/share/info/find.info.g

6.16 Step 16
When the whereis command returns more than one result for a command, it may be useful to know which
command is being used. The which command can be used to find out which result is used when executing the
command.

which [-a] FILENAME...

To find all the binaries for the touch command, execute the following command:

whereis -b touch
sysadmin@localhost:~$ whereis -b touch
touch: /usr/bin/touch /bin/touch

To find out which of the touch command results is the real command, use the which command:

which touch
sysadmin@localhost:~$ which touch
/usr/bin/touch

6.17 Step 17
The -a option can be used with the which command to locate multiple executable files. To locate all the executable
files for the less command, execute the following command:

which -a less
sysadmin@localhost:~$ which -a less
/usr/bin/less
/bin/less
6.18 Step 18
The type command can be used to determine information about various commands.

type [OPTION]... NAME...

To find out which specific file the less command originates from, execute the following command:

type less
sysadmin@localhost:~$ type less
less is /usr/bin/less

The output of the command above is similar to the output of the which command:

sysadmin@localhost:~$ which less


/usr/bin/less

The output of the command above is similar to the output of the which command:

sysadmin@localhost:~$ which less


/usr/bin/less

To reveal all the paths of the less command, execute the type command with the -a option:

type -a less
sysadmin@localhost:~$ type -a less
less is /usr/bin/less
less is /bin/less

Sumber : https://content.netdevgroup.com/labs/lpic1-s1/PrQVzWcZ2f/
NDG Introduction to Linux I - Chapter 7: Text Utilities

A core philosophy that started with UNIX, and lives on in Linux, is that commands should read text as input and write text as
output. To remain true to this philosophy, a large number of commands have been designed with the primary purpose of
processing text files. As you will see, many of these commands act as filters, as they somehow alter the text that they read
before they produce their output.

7.2 Viewing File Contents


With a single file argument, the cat command will simply output the contents of a file:

cat [OPTION]... [FILE]...


sysadmin@localhost:~$ cd Documents
sysadmin@localhost:~/Documents$
sysadmin@localhost:~/Documents$ cat alpha-first.txt
A is for Animal
B is for Bear⁠⁠ 
C is for Cat
D is for Dog
E is for Elephant
F is for Flower
sysadmin@localhost:~/Documents$ cat alpha-second.txt
G is for Grapes
H is for Happy
I is for Ink
J is for Juice
K is for Kangaroo
L is for Lol
M is for Monkey

However, the cat command gets its name from the word concatenate, meaning to merge or append. This command
has the ability to accept two or more files as input and then output the concatenation (merging) of those files:

sysadmin@localhost:~/Documents$ cat alpha-first.txt alpha-second.txt


A is for Animal
B is for Bear
C is for Cat
D is for Dog
E is for Elephant
F is for Flower
G is for Grapes
H is for Happy
I is for Ink
J is for Juice
K is for Kangaroo
L is for Lol
M is for Monkey

While the cat command is often used to quickly view the contents of small files, using it to display the contents of
larger files will result in frustration since the data will be displayed much too quickly and will scroll off the screen.
To display the file one page at a time, use a pager, either the more or the less command.

To view a file with the less command, pass the file name as an argument:
less FILE
sysadmin@localhost:~/Documents$ less words

The more and less commands allow users to navigate the document using keystroke commands. For example,
when using less as a pager, to advance forward a page, press the Spacebar:

The less command might look familiar since it is the pager generally used to view man pages. As you may recall,
the less command requires the use of movement commands to navigate a file. When viewing a file with the less
command, use the H key or Shift + H to display a help screen with a summary of the less commands:

SUMMARY OF LESS COMMANDS


Commands marked with * may be preceded by a number, N.

Notes in parentheses indicate the behavior if N is given.

h H Display this help.


q :q Q :Q ZZ Exit.
------------------------------------------------------------------------
MOVING

e ^E j ^N CR * Forward one line (or N lines).


y ^Y k ^K ^P * Backward one line (or N lines).
f ^F ^V SPACE * Forward one window (or N lines).
b ^B ESC-v * Backward one window (or N lines).
z * Forward one window (and set window to N).
w * Backward one window (and set window to N).
ESC-SPACE * Forward one window, but don't stop at end-of-file.
d ^D * Forward one half-window (and set half-window to N).
u ^U * Backward one half-window (and set half-window to N).
ESC-) RightArrow * Left one half screen width (or N positions).
ESC-( LeftArrow * Right one half screen width (or N positions).
HELP -- Press RETURN for more, or q when done
To exit the less command, use the Q key.

7.3 Splitting Files


While the cat command can concatenate two or more files into one file, the split command can take one file and
split it into multiple files. One application of the split command would be to take a file that is too large to fit on
some kind of removable media and break that file apart so that each piece could be stored on separate media. This
way, the pieces of the split files can each fit on a removable media for transfer to another system.

This can also be a useful way to send larger files across a slow network that has connection issues. Breaking files
into smaller pieces would make it easier to transfer the data across a poor network connection. Once the pieces are
copied to the other system, the cat command can be used to reassemble the pieces into a single file once again.

The syntax for the split command is:

split [OPTION]... [INPUT [PREFIX]]

The INPUT argument is typically a file name, but the split command is able to read from standard input as well.

Note

Standard input and output streams will be covered in greater detail later in the course.

By default, the new files will be named with a prefix of x and an alphabetical suffix of aa, ab, etc.:

sysadmin@localhost:~/Documents$ split longfile.txt


sysadmin@localhost:~/Documents$ ls
School alpha.txt linux.txt profile.txt xac xai
Work animals.txt longfile.txt red.txt xad xaj
adjectives.txt food.txt newhome.txt spelling.txt xae xak
alpha-first.txt hello.sh numbers.txt words xaf
alpha-second.txt hidden.txt os.csv xaa xag
alpha-third.txt letters.txt people.csv xab xah

As indicated by the command syntax, it is possible to specify a prefix other than x. For example, the following
example denotes file. as the prefix:

sysadmin@localhost:~/Documents$ split longfile.txt file.


sysadmin@localhost:~/Documents$ ls
School animals.txt file.ag hidden.txt people.csv xac xaj
Work file.aa file.ah letters.txt profile.txt xad xak
adjectives.txt file.ab file.ai linux.txt red.txt xae
alpha-first.txt file.ac file.aj longfile.txt spelling.txt xaf
alpha-second.txt file.ad file.ak newhome.txt words xag
alpha-third.txt file.ae food.txt numbers.txt xaa xah
alpha.txt file.af hello.sh os.csv xab xai

The -d option will allow for the split files to have a numeric suffix instead of a default alphabetic suffix. If -d is
added to the previous command, the resulting file names would be:

sysadmin@localhost:~/Documents$ split -d longfile.txt file.


sysadmin@localhost:~/Documents$ ls
School file.00 file.08 file.af hidden.txt profile.txt xae
Work file.01 file.09 file.ag letters.txt red.txt xaf
adjectives.txt file.02 file.10 file.ah linux.txt spelling.txt xag
alpha-first.txt file.03 file.aa file.ai longfile.txt words xah
alpha-second.txt file.04 file.ab file.aj newhome.txt xaa xai
alpha-third.txt file.05 file.ac file.ak numbers.txt xab xaj
alpha.txt file.06 file.ad food.txt os.csv xac xak
animals.txt file.07 file.ae hello.sh people.csv xad

By default, the split command will break apart a file into 1,000 line chunks. The first 1,000 lines of the original
file will go into the first file, the second 1,000 lines will go into the second file, etc. The above file longfile.txt
splits into 11 files, meaning it is approximately 11,000 lines long.

The -l option can be used to specify the number of lines to split upon. Alternatively, the -b option may be used to
specify the maximum number of bytes to use per file.

7.4 Numbering the Output of Files


The nl command will number the lines of its output.

nl [OPTION]... [FILE]...

By default, it only numbers non-empty lines:

sysadmin@localhost:~/Documents$ nl newhome.txt
1 Thanks for purchasing your new home!!

2 **Warning** it may be haunted.

3 There are three bathrooms.

4 **Beware** of the ghost in the bedroom.

5 The kitchen is open for entertaining.

6 **Caution** the spirits don't like guests.

7 Good luck!!!

The nl command offers many formatting options for line numbering, including separate styles for headers, footers,
sections, and the body of a file. For example, to have the nl command number every line in the newhome.txt file,
execute the following command:

sysadmin@localhost:~/Documents$ nl -ba newhome.txt


1 Thanks for purchasing your new home!!
2
3 **Warning** it may be haunted.
4
5 There are three bathrooms.
6
7 **Beware** of the ghost in the bedroom.
8
9 The kitchen is open for entertaining.
10
11 **Caution** the spirits don't like guests.
12
13 Good luck!!!
In the previous example, the option -ba may cause some confusion as it is really just one option, not two. The -b
option is the --body-numbering option, abbreviated in its short version as -b. The a is actually an argument that
means number all lines. In other words, the command could also be executed:

sysadmin@localhost:~/Documents$ nl -b a newhome.txt

This is one of the reasons some Linux users prefer the long argument technique. Using a long argument, the
command could have been written:

sysadmin@localhost:~/Documents$ nl --body-numbering=a newhome.txt

Consider This

It is also possible to number lines using the cat -n command with the -n option, which numbers every line by
default.

7.5 Displaying the Beginning of a File


The purpose of the head command is to view the beginning of a file or output.

head [OPTION]... [FILE]...

By default, the head command will display the first ten lines of a file's contents. For example, the following
command displays the first ten lines of the alpha.txt file:

sysadmin@localhost:~/Documents$ head alpha.txt


A is for Apple
B is for Bear
C is for Cat
D is for Dog
E is for Elephant
F is for Flower
G is for Grapes
H is for Happy
I is for Ink
J is for Juice

There are several options for the head command that are useful. For instance, there is the ability to use a number as
an option to indicate how many lines of output to display. For example, to display the first three lines of the
alpha.txt file, execute:

sysadmin@localhost:~/Documents$ head -3 alpha.txt


A is for Apple
B is for Bear
C is for Cat

There is also the -n option which takes an argument for the number of lines to display. So, the following would
also display the first three lines of the alpha.txt file:

sysadmin@localhost:~/Documents$ head -n3 alpha.txt


A is for Apple
B is for Bear
C is for Cat
A negative number can also be used as an argument to the -n option, which tells the head command how many
lines to omit from the bottom of the file. For example, when executing the head -n -90 command on a file that is
100 lines long, the output would only include the first 10 lines by omitting the last 90.

The alpha.txt file is 26 lines long. The following command omits the last 24 lines, resulting in only the first two
lines of the file being displayed:

sysadmin@localhost:~/Documents$ head -n -24 alpha.txt


A is for Apple
B is for Bear

7.6 Displaying the End of a File


The opposite of the head command, the tail command, displays contents from the end of the file and not the
beginning.

head [OPTION]... [FILE]...

The tail command also displays ten lines by default with no options given:

⁠ 
sysadmin@localhost:~/Documents$ tail alpha.txt
Q is for Quark
R is for Rat
S is for Sloth
T is for Turnip
U is for Up
V is for Velvet
W is for Walrus
X is for Xenon
Y is for Yellow
Z is for Zebra

You may use either a number or the -n option as an argument to the tail command to specify how many lines you
want to output from the end of the file. Therefore, the following two commands are equivalent:

sysadmin@localhost:~/Documents$ tail -3 alpha.txt


X is for Xenon
Y is for Yellow
Z is for Zebra
sysadmin@localhost:~/Documents$ tail -n3 alpha.txt
X is for Xenon
Y is for Yellow
Z is for Zebra

With the tail command, the -n option has an interesting twist to it, as well. When using the -n option with a
number prefixed by a plus sign + character, the number is interpreted as the line number in the file to start
displaying content from; it will display from that line to the end of the file. In other words, the -n option used with
the +20 argument will display the contents of the file starting at line twenty and continuing until the end of the file.

sysadmin@localhost:~/Documents$ tail -n +20 alpha.txt


T is for Turnip
U is for Up
V is for Velvet
W is for Walrus
X is for Xenon
Y is for Yellow
Z is for Zebra

Consider This

Another unusual, but useful feature of the tail command is its ability to follow a file. When the tail command is
executed with the -f option and a file name argument, then it will initially output the number of lines specified.
Instead of exiting after displaying the lines, the tail command continues to run, following any changes in the file
and displaying new content as it is added to the end of the file.

One of the main applications for this follow feature is for administrators to watch log files change while they are
troubleshooting problems.

Additionally, the -F option is used when following a log file that may have been rotated or archived, and a new
empty file of the same name replaces it. The -F option allows tail to notice that the underlying inode number that
matches the log file name has changed, and it will continue to watch the new log file.

7.7 Combining File Output


The paste command will merge the lines of one or more files, line by line, separating them with a tab as a
delimiter (separator) by default.

paste [OPTION]... [FILE]...

To demonstrate the paste command’s functionality, the numbers.txt and letters.txt will be used:

sysadmin@localhost:~/Documents$ cat numbers.txt


1
2
3
4
5
sysadmin@localhost:~/Documents$ cat letters.txt
a
b
c
d
e

To paste these files together with a tab between the elements, use the paste command:

sysadmin@localhost:~/Documents$ paste numbers.txt letters.txt


1 a
2 b
3 c
4 d
5 e

It is also possible to use other characters as delimiters. For instance, if the intent is to create a file that a spreadsheet
could easily open, a comma would be chosen as the delimiter. The -d option is used to specify the delimiter.

sysadmin@localhost:~/Documents$ paste -d , numbers.txt letters.txt


1,a
2,b
3,c
4,d
5,e

Similar to the paste command, the join command is able to combine two files. Instead of simply going line by
line through the files, the join command matches the values of fields to determine which lines to combine. In
other words, it will join files based on a common field between the files.

Consider This

For those familiar with Structured Query Language (SQL), the join command is similar to the SQL join
statement, which combines records from two tables of related tables by matching values in joined fields.

In order to break a line into fields, the join command uses either tabs or spaces between the contents of the files
and breaks each line into separate fields.

join [OPTION]... FILE1 FILE2

To demonstrate this properly, we will use the following two files.

sysadmin@localhost:~/Documents$ cat adjectives.txt


1 golden
2 honey
3 fruit
4 grey
5 bald
sysadmin@localhost:~/Documents$ cat animals.txt
1 retriever 
2 badger
3 bat
4 wolf
5 eagle

If the data that is used to join the files is the first field, then there is no need to specify which join fields to use.
However, the field that is used in the joining process must be sorted in both files first, or else errors may occur.
Also, missing elements in the key of either file will not appear in the results.

In the following example, the first field is used to merge the two files together. When the files are joined, the
number field is used as a key to determine which words to join:

sysadmin@localhost:~/Documents$ join adjectives.txt animals.txt


1 golden retriever
2 honey badger
3 fruit bat
4 grey wolf
5 bald eagle

The first field in each file containing numbers is only shown once in the output, followed by a space and the second
field from the first file, finally by another space and the second field from the second file. For illustration purposes,
the same two files are shown being combined with the paste and cat commands:

sysadmin@localhost:~/Documents$ paste adjectives.txt animals.txt


1 golden 1 retriever
2 honey 2 badger
3 fruit 3 bat
4 grey 4 wolf
5 bald 5 eagle
sysadmin@localhost:~/Documents$ cat adjectives.txt animals.txt
1 golden
2 honey
3 fruit
4 grey
5 bald
1 retriever
2 badger
3 bat
4 wolf
5 eagle

Use the -t option to specify an alternate delimiter. For example, if two spreadsheets were exported into comma
separated value .csv files, join could use those commas to distinguish one field from another.

The next example illustrates a more advanced use of the join command. Two files, people.csv and os.csv., will
be combined by the join command using data that isn't in the first field.

sysadmin@localhost:~/Documents$ cat people.csv


Dennis,Richie
Andrew,Tanenbaum
Ken,Thompson
Linus,Torvalds
sysadmin@localhost:~/Documents$ cat os.csv
1970,Unix,Richie
1987,Minix,Tanenbaum
1970,Unix,Thompson
1991,Linux,Torvalds

The following join command will join the files according to the field containing last names:

join -1 2 -2 3 -t',' people.csv os.csv

To specify that the join field for the first file is the second field, -1 2 is used. The -1 option means "field of the
first file" and the 2 argument means "the second field".

To specify that the join field for the second file is the third field, -2 3 is used. The -2 option means "field of the
second file" and the 3 argument means "the third field".

These files also use a delimiter that is neither a tab nor a space, so the delimiter is specified as a comma , character
with the -t',' option:

sysadmin@localhost:~/Documents$ join -1 2 -2 3 -t',' people.csv os.csv


Richie,Dennis,1970,Unix
Tanenbaum,Andrew,1987,Minix
Thompson,Ken,1970,Unix
Torvalds,Linus,1991,Linux

7.8 Command Line Pipes


To make effective use of filter commands, command pipelines are often used. The pipe | character can be used to
send the output of one command to another:

COMMAND 1 | COMMAND 2 | COMMAND 3 ...


Typically, when a command has output or generates an error, the output is displayed on the screen; however, this
does not have to be the case. Instead of being printed to the screen, the output of one command becomes input for
the next command. This tool can be powerful, especially when looking for specific data; piping is often used to
refine the results of an initial command.

The head and tail commands are often used in command pipelines to limit the number of lines when dealing with
large files. For example, to number only the last three lines of the alpha.txt file, pipe the output of the tail
command to the nl command:

sysadmin@localhost:~/Documents$ tail -3 alpha.txt | nl


1 hello
2 inkling
3 jogger

Command pipelines can also be used to filter command output. For example, to list just the first five files in the
current directory, pipe the output of the ls command to the head command:

sysadmin@localhost:~/Documents$ ls | head -5
School
Work
adjectives.txt
alpha-first.txt
alpha-second.txt

Note

Pipes will be covered in greater detail later in the course.

7.9 Extract Fields in a File


The cut command extracts fields of information from a text file.

cut [OPTION]... [FILE]...

Note the output of the following head command for the first line of the /etc/passwd command. There are 7 fields,
each separated by the colon : character as a delimiter:

sysadmin@localhost:~/Documents$ head -1 /etc/passwd


root:x:0:0:root:/root:/bin/bash
roo /roo /bin/ba
root x00
t t sh
1 2345 6 7
The default field separator is either a space or tab; this can be modified with the delimiter -d option. Use the -f
option to specify a list of comma separated field numbers to display or a hyphenated range of fields to display.

To extract certain fields from the /etc/passwd file, specify the delimiter using the colon character as an argument
to the -d option. If only fields 1,5,6, and 7 were important, they could be extracted using the following command:

sysadmin@localhost:~/Documents$ head -1 /etc/passwd | cut -d: -f1,5,6,7


root:root:/root:/bin/bash

The same result could be achieved by combining the fields 5,6,7 into the range 5-7:

sysadmin@localhost:~/Documents$ head -1 /etc/passwd | cut -d: -f1,5-7


root:root:/root:/bin/bash

Given a file that has fields at fixed character positions, the cut command can be used to extract the characters one
at a time by using the character -c option followed by a range.

For example, in the /var/syslog file; the first fifteen characters specify a timestamp. To extract only those
characters from the text, specify 1 through 15:

sysadmin@localhost:~/Documents$ tail /var/log/syslog | cut -c1-15


Jul 20 15:17:01
Jul 20 15:59:02
Jul 20 16:17:01
Jul 20 16:41:22
Jul 20 16:59:02
Jul 20 17:17:01
Jul 20 17:59:02
Jul 20 18:17:01
Jul 20 18:59:02
Jul 20 19:17:01

7.10 Sort File Output


The sort command is used to display a file sorted on a specific field of data.

sort [OPTION]... [FILE]...


Using sort with no options on people.csv results in the lines being sorted in ASCII order, which is similar to
alphabetical order:

sysadmin@localhost:~/Documents$ sort people.csv


Andrew,Tanenbaum
Dennis,Richie
Ken,Thompson
Linus,Torvalds

This command is able to sort using any field, the same way that a spreadsheet is able to sort by any column. By
default, sort breaks up each line of a file into fields using whitespace (tabs or spaces) as delimiters. To specify an
alternate delimiter, use the -t option. To specify the fields to sort from first to last, use one or more -k options. In
the following example, the os.csv file is sorted based on the second field of data, using the comma , character as
a delimiter:

sysadmin@localhost:~/Documents$ sort -t',' -k2 os.csv


1991,Linux,Torvalds
1987,Minix,Tanenbaum
1970,Unix,Richie
1970,Unix,Thompson

While it is possible to sort the first field of os.csv using the ASCII ordering, a numerical sort makes more sense.
In order to have the sort command treat a field numerically, add an n as an argument to the -k option for that key
field specification. Be aware in the following example the -k option has two arguments, the 1 indicates the first
field, and the n specifies sorting that field numerically:

sysadmin@localhost:~/Documents$ sort -t',' -k1n os.csv


1970,Unix,Richie
1970,Unix,Thompson
1987,Minix,Tanenbaum
1991,Linux,Torvalds

To reverse the sort direction from ascending to descending, add an r argument to the key field specification:

sysadmin@localhost:~/Documents$ sort -t',' -k1nr os.csv


1991,Linux,Torvalds
1987,Minix,Tanenbaum
1970,Unix,Richie
1970,Unix,Thompson

The sort command can be combined with other commands to accomplish more sophisticated tasks. For example,
the output of the cut -f7 -d: /etc/passwd command contains many duplicate values:

sysadmin@localhost:~/Documents$ cut -f7 -d: /etc/passwd | head -n4


/bin/bash
/usr/sbin/nologin
/usr/sbin/nologin
/usr/sbin/nologin
⁠ 

By piping this output to the sort command and using the unique -u option, duplicate lines will be removed from
the output:

sysadmin@localhost:~/Documents$ cut -f7 -d: /etc/passwd | sort -u


/bin/bash
/bin/sync
/usr/sbin/nologin
7.11 Remove Duplicate Lines in a File
The uniq command does what the unique -u option did with the sort command. Unlike the sort command,
which rearranges the rows consecutively before eliminating duplicates, the uniq command will only eliminate
duplicates if they are already consecutive lines. If the sort command is already being used to rearrange the
duplicates into consecutive order, then why not just use the -u option to eliminate duplicates?

There are a couple of reasons to use the uniq command instead of the sort -u command. First, there may be times
when the lines should not be sorted first. The uniq command can simply remove lines that are currently
consecutive.

Second, the count -c option to the uniq command outputs the number of duplicates that were counted (a feature
that the sort command lacks):

⁠ 
sysadmin@localhost:~/Documents$ cut -f7 -d: /etc/passwd | sort | uniq -c
3 /bin/bash
1 /bin/sync
23 /usr/sbin/nologin

7.12 Display File Contents in Various Formats


The od command can output data in several different formats. It produces an octal dump by default (hence the
name od). One use of this command is to display the contents of a file when it contains non-printable characters,
such as control characters.

od [OPTION]... [FILE]...

The following table summarizes the formats that the od command can output:

Single Option Option with Argument Meaning


-a -t a Named characters, ignoring high bit
-b -t o1 Octal bytes
-c -t c ASCII characters or backslash escapes
-d -t u2 Unsigned decimal 2-byte units
-f -t fF Floats
-i -t dI Decimal integers
-l -t dL Decimal longs
-o -t o2 Octal 2-byte units
-s -t d2 Decimal 2-byte units
-x -t x2 Hexadecimal 2-byte units

In order to demonstrate the od command, the hidden.txt file will be used:

sysadmin@localhost:~/Documents$ cat hidden.txt


NDG LPIC-1 Curriculum
Is The Best.
It seems straight-forward enough, but there are non-printable control characters \r causing cat to return to the
beginning of the first line. This is where od comes in handy. Use the -c option to examine ASCII characters:

sysadmin@localhost:~/Documents$ od -c hidden.txt
0000000 T h i s \r i s \r a \r h i d
0000020 d e n \r m e s s a g e \r N G
0000040 D L P I C - 1 C u r r i c u
0000060 l u m \n I s T h e B e s t
0000100 . \n \n
0000103

It appears that there was a hidden message in that file that the cat command missed. The point, however, is not to
use od to send secret messages. The od command can be used for file recovery, or to open a file that crashes other
programs.

As the name implies, od can display raw file content in octal form. It also supports hexadecimal and decimal
output. This can be very useful when analyzing a precompiled binary, such as a virus:

sysadmin@localhost:~/Documents$ od -x hidden.txt
0000000 6854 7369 0d20 7369 0d20 2061 680d 6469
0000020 6564 206e 6d0d 7365 6173 6567 0d20 474e
0000040 2044 504c 4349 312d 4320 7275 6972 7563
0000060 756c 206d 490a 2073 6854 2065 6542 7473
0000100 0a2e 000a
0000103

Two other options control where the od command will read its data from the file:

Option Function
-j Specify how many bytes to skip from the input.
-N Specify the total number of bytes the od command will read from the file.

See how these options work with the same hidden.txt file from the previous example, skipping thirteen bytes and
displaying only fifteen bytes total:

sysadmin@localhost:~/Documents$ od -j 13 -N 15 -c hidden.txt
0000015 h i d d e n \r m e s s a g e
0000034

Additional options that are used to affect the output of the od command:

Option Function
-w Specify the width in bytes to output next to the offset address. By default, the width will be sixteen bytes.

The -A option has several ways to specify the offset address to the left of the data as the formatting options covered
earlier:

Option Function
-An Prevents the od command from outputting the offset address to the left of the data.
-Ad Outputs file offsets using decimal addresses.
-Ax Outputs file offsets using hexadecimal addresses.
File offsets are non-negative integers that specify a point within a file that is a specific number of bytes from a
known position. For example, an offset of 64 from the beginning of a file would the denote 65th bit in the file.
Offsets are a way to specify a particular piece of information located within a data file. They can be useful for
dealing with files that are open or have been damaged, or in computer forensics for recovering deleted information.

The following example, the od command displays the file with a width of eight bytes of data, the offset address
suppressed, and the bytes of data being displayed as ASCII characters:

sysadmin@localhost:~/Documents$ od -j 13 -N 15 -c -w8 -An ./hidden.txt


h i d d e n \r
m e s s a g e

7.13 Translate File Characters


The tr command can be used to translate from one set of characters to another.

tr [OPTION]... SET1 [SET2]

The following example will translate all of the lowercase letters in alpha-first.txt to uppercase letters:

sysadmin@localhost:~/Documents$ cat alpha-first.txt | tr 'a-z' 'A-Z'


A IS FOR ANIMAL
B IS FOR BEAR
C IS FOR CAT
D IS FOR DOG
E IS FOR ELEPHANT
F IS FOR FLOWER

The characters that the tr command is translating do not have to be in a range; they can simply be listed for each
set of characters. Be careful to balance the sets to make sure that they both have the same number of characters, or
else strange results may occur. The following example has the tr command replace the vowel characters with
symbols:

sysadmin@localhost:~/Documents$ cat alpha-first.txt | tr 'aeiou' '@&1*^'


A 1s f*r An1m@l
B 1s f*r B&@r
C 1s f*r C@t
D 1s f*r D*g
E 1s f*r El&ph@nt
F 1s f*r Fl*w&r

Aside from performing a translate function, the tr command can also "squeeze" repeated characters and delete
characters. In performing these functions, only one set of characters needs to be specified. For example, to
eliminate duplicates, use the -s option to squeeze repeats of characters from the first set:

sysadmin@localhost:~/Documents$ echo 'aaaaaappleeeeee' | tr -s 'ae'


apple

Using the -d option will delete the characters in the first set:

sysadmin@localhost:~/Documents$ cat alpha-first.txt | tr -d 'AEIOUaeiou'


s fr nml
B s fr Br
C s fr Ct
D s fr Dg
s fr lphnt
F s fr Flwr

7.14 Stream Editor Command


The stream editor sed command is a non-interactive editor that can be used to modify text.

sed [OPTION]... {SCRIPT} [FILE]...

To do a simple search and replace operation, use the following script, or expression. This will search for the pattern
between the first two slashes, and if it finds that text, then it replaces it with what is specified between the last two
slashes:

s/PATTERN/REPLACEMENT/

In the alpha-first.txt file, to replace the word Animal with the word Apple, execute the following command:

sysadmin@localhost:~/Documents$ sed 's/Animal/Apple/' alpha-first.txt


A is for Apple
B is for Bear
C is for Cat
D is for Dog
E is for Elephant
F is for Flower

Unlike most filter commands, the sed command can modify the original file by using the -i option.The -i option
allows for an optional argument, which will be an extension added to the original file. The result is a new file
which is a copy of the original file. For example, if you wanted to backup the original file as alpha-
first.txt.original file, execute the following:

sysadmin@localhost:~/Documents$ sed -i'.original' 's/Animal/Apple/' alpha-first.txt


sysadmin@localhost:~/Documents$ cat alpha-first.txt
A is for Apple
B is for Bear
C is for Cat
D is for Dog
E is for Elephant
F is for Flower
sysadmin@localhost:~/Documents$ cat alpha-first.txt.original
A is for Animal
B is for Bear
C is for Cat
D is for Dog
E is for Elephant
F is for Flower

The original file was modified as a result of the -i option. For the rest of the examples, the -i option will not be
used. The output will be sent to the terminal instead, and the original file will not be changed.

The Global Modifier

When performing a search and replace operation, the sed command will only replace the first occurrence of the
search pattern by default. To replace all occurrences of the pattern, add the global modifier g after the final slash.
s/PATTERN/REPLACEMENT/g

For example, consider the food.txt text file:

sysadmin@localhost:~/Documents$ cat food.txt


Food is good.

The following example will only replace the first occurrence of the oo pattern with the 00 pattern:

sysadmin@localhost:~/Documents$ sed 's/oo/00/' food.txt


F00d is good.

If you want to replace every occurrence of oo with 00, add the g modifier:

sysadmin@localhost:~/Documents$ sed 's/oo/00/g' food.txt


F00d is g00d.

The sed command is also able to either insert text before a pattern or after a pattern. For this type of expression, do
not use the s character before the first slash; use an insert change with the i\ expression or an append change with
the a\ expression.

/PATTERN/i\TEXT\
/PATTERN/a\TEXT\

Inserting text with the i\ expression affects the line before the line containing the search term:

sysadmin@localhost:~/Documents$ sed '/is/i\Hello' food.txt


Hello
Food is good.

Appending text with the a\ expression affects the line after the line containing the search term:

sysadmin@localhost:~/Documents$ sed '/is/a\Hello' food.txt


Food is good.
Hello

The sed command can also be used to search for a line of text containing a pattern and then delete the lines that
match. Place the pattern to search for between two slashes followed by a d to carry out this operation:

/PATTERN/d

Notice the animals.txt file has five lines, but the following example command removes the lines that contain an
a:

sysadmin@localhost:~/Documents$ cat animals.txt


1 retriever
2 badger
3 bat
4 wolf
5 eagle
sysadmin@localhost:~/Documents$ sed '/a/d' animals.txt
1 retriever
4 wolf

To change an entire line that matches a pattern to something else, use a slash, the pattern to match, another slash,
c\, and then the new text.
/PATTERN/c\REPLACEMENT

For example, to change a line containing 3 to three, use the following command:

sysadmin@localhost:~/Documents$ cat numbers.txt


1
2
3
4
5
sysadmin@localhost:~/Documents$ sed '/3/c\three' numbers.txt
1
2
three
4
5

Keep in mind the entire line will be replaced, not just the matching pattern:

sysadmin@localhost:~/Documents$ sed '/3/c\three' animals.txt


1 retriever
2 badger
three
4 wolf
5 eagle

The sed command normally parses only one expression to filter text. To use multiple expressions, use a -e option
with each expression to modify the file.

Notice that the order in which those expressions are placed makes a difference. In the first attempt, both
expressions are effective, but in the second attempt, only the first is effective. After the first expression deletes all
lines containing an a, the second expression doesn't have anything to do because the line that contained 3 was
removed:

sysadmin@localhost:~/Documents$ sed -e '/3/c\three' -e '/a/d' animals.txt


1 retriever
three
4 wolf
sysadmin@localhost:~/Documents$ sed -e '/a/d' -e '/3/c\three' animals.txt
1 retriever
4 wolf

Note

The use of the term pattern in this section refers to one of the most powerful aspects of the sed command, its
compatibility with regular expressions. In each example so far, the sed command has been using literal
expressions involving alphanumeric characters like t or o or strings like three. Regular expressions can be used to
create patterns for use with the sed command and many other, far more powerful commands.

Regular expressions will be covered in greater detail later in the course.

7.15 Counting Lines in a File


The wc command can be used to analyze a text file. By default, wc counts the number of lines, words, and byte
counts in a passage and outputs this information in the following format:
lines words bytes filename

Recall the alpha-first.txt file:

sysadmin@localhost:~/Documents$ cat alpha-first.txt


A is for Apple
B is for Bear
C is for Cat
D is for Dog
E is for Elephant
F is for Flower

Using the wc command on the same file reveals the following:

sysadmin@localhost:~/Documents$ wc alpha-first.txt
6 24 90 alpha-first.txt

The wc command reports that there are 6 lines, containing 24 words, totaling 90 bytes in length. The total number
of bytes includes spaces, punctuation, and carriage returns.

To view each of these numbers separately, options can be used:

sysadmin@localhost:~/Documents$ wc alpha-first.txt -l
6 alpha-first.txt
sysadmin@localhost:~/Documents$ wc alpha-first.txt -w
24 alpha-first.txt
sysadmin@localhost:~/Documents$ wc alpha-first.txt -m
90 alpha-first.txt

In the example, the -l option was used to count the number of lines. In the second example, the -w option was used
to count the number of words. Finally, the -m option indicates the number of characters.

One might imagine that the -c option would count the number of characters, but -c is used to count the number of
bytes. The number of bytes can vary if there are non-printable characters in the file. In this case, they are the same:

sysadmin@localhost:~/Documents$ wc alpha-first.txt -c
90 alpha-first.txt

One last option, -L returns the maximum line length in the file:

sysadmin@localhost:~/Documents$ wc alpha-first.txt -L
17 alpha-first.txt

If the word count of all the files in a particular folder is desired, the asterisk wildcard * can be used:

sysadmin@localhost:~/Documents$ wc *
wc: School: Is a directory
0 0 0 School
wc: Work: Is a directory
0 0 0 Work
5 10 39 adjectives.txt
6 24 90 alpha-first.txt
6 24 90 alpha-first.txt.original
7 28 106 alpha-second.txt
13 52 195 alpha-third.txt
26 104 390 alpha.txt
5 10 42 animals.txt
1 3 14 food.txt
7 14 647 hello.sh
3 11 67 hidden.txt
5 5 10 letters.txt
8 32 187 linux.txt
10240 10236 66540 longfile.txt
13 36 236 newhome.txt
5 5 10 numbers.txt
4 4 77 os.csv
4 4 59 people.csv
6 21 110 profile.txt
11 11 51 red.txt
2 26 130 spelling.txt
102305 102305 971578 words
112682 112965 1040667 total

The output above reveals that longfile.txt really is the longest file in the folder.
Key Terms

split
Command used to take one file and break it into multiple parts. By default it breaks the file up into 1000
line sections.
Section 7.3
tail
Prints the last ten lines of a file by default. The number of lines can be set to any desired value.
Section 7.6
tr
Command used to translate one set of characters to another.
Section 7.13
uniq
Command to remove duplicate lines that are currently consecutive.
Section 7.11
wc
Print newline, word, and byte counts for each FILE, and a total line if more than one FILE is specified.
Section 7.15
LAB 7

7.0 Introduction
Text is the primary form of input and output for Linux commands and therefore there are many commands whose
primary purpose is processing text files.

7.1 Step 1
The cat command (derived from the word concatenate) accepts multiple files as input and outputs a merged file.

cat [OPTION]... [FILE]...

To view the contents of the /etc/hosts and /etc/hostname files, execute the following commands:

cat /etc/hosts
cat /etc/hostname
sysadmin@localhost:~$ cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.1.2 localhost
sysadmin@localhost:~$ cat /etc/hostname
localhost

To concatenate the contents of files /etc/hosts and /etc/hostname, execute the following command:

cat /etc/hosts /etc/hostname


sysadmin@localhost:~$ cat /etc/hosts /etc/hostname
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.1.2 localhost
localhost

7.2 Step 2
The standard output of the cat command can be sent to another file by using redirection. Standard output
redirection is achieved by following a command with the greater-than > character and a destination file.

cat /etc/hosts /etc/hostname > result


sysadmin@localhost:~$ cat /etc/hosts /etc/hostname > result
Standard input and output streams will be covered in greater detail later in the course.

To view the result file created above, execute the following command:
cat result
sysadmin@localhost:~$ cat result
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.1.2 localhost
localhost

7.3 Step 3
To view the result file along with line numbers prefixed to each line, execute the following command:

cat –n result
sysadmin@localhost:~$ cat -n result
1 127.0.0.1 localhost
2 ::1 localhost ip6-localhost ip6-loopback
3 fe00::0 ip6-localnet
4 ff00::0 ip6-mcastprefix
5 ff02::1 ip6-allnodes
6 ff02::2 ip6-allrouters
7 192.168.1.2 localhost
8 localhost
The cat command can be used for viewing text files only.

7.4 Step 4
While viewing small files with the cat command poses no problems, it is not an ideal choice for large files. For
larger files, a pager command can be used to view the contents. Pager commands display one page of data at a
time, allowing you to move forward and backward in the file by using movement keys.

The less command provides a very advanced paging capability. It is usually the default pager used by commands
like the man command.

To view a file with the less command, pass the file name as an argument:

less /etc/passwd
sysadmin@localhost:~$ less /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd/netif:/usr/sbin/nologin
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nol
/etc/passwd

7.5 Step 5
While you are in the output of the less command, you can view the help screen by pressing the h key:

SUMMARY OF LESS COMMANDS

Commands marked with * may be preceded by a number, N.


Notes in parentheses indicate the behavior if N is given.
A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K.

h H Display this help.


q :q Q :Q ZZ Exit.
---------------------------------------------------------------------------

MOVING

e ^E j ^N CR * Forward one line (or N lines).


y ^Y k ^K ^P * Backward one line (or N lines).
f ^F ^V SPACE * Forward one window (or N lines).
b ^B ESC-v * Backward one window (or N lines).
z * Forward one window (and set window to N).
w * Backward one window (and set window to N).
ESC-SPACE * Forward one window, but don't stop at end-of-file.
d ^D * Forward one half-window (and set half-window to N).
u ^U * Backward one half-window (and set half-window to N).
ESC-) RightArrow * Right one half screen width (or N positions).
HELP -- Press RETURN for more, or q when done

.6 Step 6
While you are in the help screen, you can return to the file by pressing the q key.

q
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd/netif:/usr/
sbin/nologin
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nol
/etc/passwd

Then, to exit the less command entirely, press the q key again:

q
sysadmin@localhost:~$

7.7 Step 7
There are two ways to search the output of the less command: searching forward or searching backward from
your current position.

To start a search to look forward from your current position, use the slash / key. Then, type the text or pattern to
match and press the Enter key.

To search for the word sbin in the /etc/passwd file, use the slash / key:

less /etc/passwd
/sbin
Enter
sysadmin@localhost:~$ less /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd/netif:/usr/
sbin/nologin
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nol
/sbin_

Press n to move forward and N to move backward in the search result.


nnnNNN
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd/netif:/usr/
sbin/nologin
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin
:_

Finally, quit the less pager by typing the letter q:

q
sysadmin@localhost:~$

7.8 Step 8
The split command is used to split the input file into two or more files. The syntax for the split command is:

split [OPTION]... [INPUT [PREFIX]]

To split a big file, such as the words file into smaller pieces, first copy the /usr/share/dict/words file to the
current directory:

cp /usr/share/dict/words .
sysadmin@localhost:~$ cp /usr/share/dict/words .

To split the words file into smaller pieces with the prefix output and then verify the result of the split command,
execute the following commands:

split words output


ls output*
sysadmin@localhost:~$ split words output
sysadmin@localhost:~$ ls output*
outputaa outputan outputba outputbn outputca outputcn outputda outputdn
outputab outputao outputbb outputbo outputcb outputco outputdb outputdo
outputac outputap outputbc outputbp outputcc outputcp outputdc outputdp
outputad outputaq outputbd outputbq outputcd outputcq outputdd outputdq
outputae outputar outputbe outputbr outputce outputcr outputde outputdr
outputaf outputas outputbf outputbs outputcf outputcs outputdf outputds
outputag outputat outputbg outputbt outputcg outputct outputdg outputdt
outputah outputau outputbh outputbu outputch outputcu outputdh outputdu
outputai outputav outputbi outputbv outputci outputcv outputdi outputdv
outputaj outputaw outputbj outputbw outputcj outputcw outputdj outputdw
outputak outputax outputbk outputbx outputck outputcx outputdk outputdx
outputal outputay outputbl outputby outputcl outputcy outputdl outputdy
outputam outputaz outputbm outputbz outputcm outputcz outputdm

By default, the new files created with the split command will be named with a prefix of x and an alphabetical
suffix of aa, ab, etc.:

PREFIX

xaa xab xac xad xae xaf xag xah xai xaj xak

SUFFIX

xaa xab xac xad xae xaf xag xah xai xaj xak

In the output of the command above, the words file is split into smaller files which are labeled with the specified
prefix output and the default alphabetical suffix:

PREFIX

outputaa outputan outputba outputbn outputca outputcn outputda outputdn


...

SUFFIX

outputaa outputan outputba outputbn outputca outputcn outputda outputdn


...

7.9 Step 9
The split command allows files to have a numeric suffix instead of a default alphabetic suffix. To split the words
file into files prefixed with the name result and suffixed by numbers, execute the following commands:

split words –d result


ls result*
sysadmin@localhost:~$ split words -d result
sysadmin@localhost:~$ ls result*
result result14 result29 result44 result59 result74 result89
result00 result15 result30 result45 result60 result75 result9000
result01 result16 result31 result46 result61 result76 result9001
result02 result17 result32 result47 result62 result77 result9002
result03 result18 result33 result48 result63 result78 result9003
result04 result19 result34 result49 result64 result79 result9004
result05 result20 result35 result50 result65 result80 result9005
result06 result21 result36 result51 result66 result81 result9006
result07 result22 result37 result52 result67 result82 result9007
result08 result23 result38 result53 result68 result83 result9008
result09 result24 result39 result54 result69 result84 result9009
result10 result25 result40 result55 result70 result85 result9010
result11 result26 result41 result56 result71 result86 result9011
result12 result27 result42 result57 result72 result87 result9012
result13 result28 result43 result58 result73 result88
7.10 Step 10
By default, the split command will break apart a file into 1,000-line chunks. The first 1,000 lines of the original
file will go into the first file, the second 1,000 lines will go into the second file, etc. The -l option can be used to
change the default number of lines to split upon. To split the words file at every 500th line, execute the following
command:

split words result –l 500


ls result*
sysadmin@localhost:~$ split words result -l 500
sysadmin@localhost:~$ ls result*
result00 result44 result88 resultbd resultcv resulten resultgf
result01 result45 result89 resultbe resultcw resulteo resultgg
result02 result46 result9000 resultbf resultcx resultep resultgh
result03 result47 result9001 resultbg resultcy resulteq resultgi
result04 result48 result9002 resultbh resultcz resulter resultgj
result05 result49 result9003 resultbi resultda resultes resultgk
result06 result50 result9004 resultbj resultdb resultet resultgl
result07 result51 result9005 resultbk resultdc resulteu resultgm
result08 result52 result9006 resultbl resultdd resultev resultgn
result09 result53 result9007 resultbm resultde resultew resultgo
result10 result54 result9008 resultbn resultdf resultex resultgp
result11 result55 result9009 resultbo resultdg resultey resultgq
result12 result56 result9010 resultbp resultdh resultez resultgr
result13 result57 result9011 resultbq resultdi resultfa resultgs
result14 result58 result9012 resultbr resultdj resultfb resultgt
result15 result59 resultaa resultbs resultdk resultfc resultgu
result16 result60 resultab resultbt resultdl resultfd resultgv
result17 result61 resultac resultbu resultdm resultfe resultgw
result18 result62 resultad resultbv resultdn resultff resultgx
result19 result63 resultae resultbw resultdo resultfg resultgy
result20 result64 resultaf resultbx resultdp resultfh resultgz
...
Some output has been omitted in the terminal above.

7.11 Step 11
The nl command will number the lines of its output. The syntax for the nl command is:

nl [OPTION]... [FILE]...

To display the newhome.txt file in the Documents directory with line numbers, execute the following commands:

cd Documents/
nl newhome.txt
sysadmin@localhost:~$ cd Documents/
sysadmin@localhost:~/Documents$ nl newhome.txt
1 Thanks for purchasing your new home!!

2 **Warning** it may be haunted.

3 There are three bathrooms.

4 **Beware** of the ghost in the bedroom.

5 The kitchen is open for entertaining.


6 **Caution** the spirits don't like guests.

7 Good luck!!!

7.12 Step 12
By default, the nl command is used to number non-blank lines in the output. To count the number of lines in the
newhome.txt file, including blank lines, execute the following command:

nl –ba newhome.txt
cd
sysadmin@localhost:~/Documents$ nl -ba newhome.txt
1 Thanks for purchasing your new home!!
2
3 **Warning** it may be haunted.
4
5 There are three bathrooms.
6
7 **Beware** of the ghost in the bedroom.
8
9 The kitchen is open for entertaining.
10
11 **Caution** the spirits don't like guests.
12
13 Good luck!!!
sysadmin@localhost:~/Documents$ cd
sysadmin@localhost:~$

7.13 Step 13
The purpose of the head command is to view the beginning of a file or output.

head [OPTION]... [FILE]...

To view the beginning of the /usr/share/dict/words file, execute the following command:

head /usr/share/dict/words
sysadmin@localhost:~$ head /usr/share/dict/words
A
A's
AMD
AMD's
AOL
AOL's
Aachen
Aachen's
Aaliyah
Aaliyah's
7.14 Step 14
If the number of lines is not specified, the head command will display the first 10 lines. To view the first 15 lines
of the output of the /usr/share/dict/words file, execute the following command:

head -15 /usr/share/dict/words


sysadmin@localhost:~$ head -15 /usr/share/dict/words
A
A's
AMD
AMD's
AOL
AOL's
Aachen
Aachen's
Aaliyah
Aaliyah's
Aaron
Aaron's
Abbas
Abbas's
Abbasid

7.15 Step 15
To view the first 5 lines of the /usr/share/dict/words file, execute the following command:

head –n 5 /usr/share/dict/words
sysadmin@localhost:~$ head -n 5 /usr/share/dict/words
A
A's
AMD
AMD's
AOL
7.16 Step 16
To view the first 20 lines of the output of the man ls command, execute the following command:

man ls | head -20


sysadmin@localhost:~$ man ls | head -20
LS(1) User Commands LS(1)

NAME
ls - list directory contents

SYNOPSIS
ls [OPTION]... [FILE]...

DESCRIPTION
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is speci-
fied.

Mandatory arguments to long options are mandatory for short options


too.

-a, --all
do not ignore entries starting with .

-A, --almost-all

7.17 Step 17
The tail command displays contents from the end of the file and not the beginning.

tail [OPTION]... [FILE]...

To view the last 10 lines of the /usr/share/dict/words file, execute the following command:

tail /usr/share/dict/words
sysadmin@localhost:~$ tail /usr/share/dict/words
élan's
émigré
émigré's
émigrés
épée
épée's
épées
étude
étude's
études
7.18 Step 18
To view the last 5 lines of the /usr/share/dict/words file, execute the following command:

tail -5 /usr/share/dict/words
sysadmin@localhost:~$ tail -5 /usr/share/dict/words
épée's
épées
étude
étude's
études

7.19 Step 19
To view the last 5 lines of the output of the ls –ltr command, execute the following command:

ls –ltr /etc | tail –n 5


sysadmin@localhost:~$ ls -ltr /etc | tail -n 5
-rw-r--r-- 1 root root 3611 Jul 3 14:42 mailcap
lrwxrwxrwx 1 root root 12 Apr 12 16:01 mtab -> /proc/mounts
-rw-r--r-- 1 root root 172 Apr 12 16:01 hosts
-rw-r--r-- 1 root root 10 Apr 12 16:01 hostname
-rw-r--r-- 1 root root 38 Apr 12 16:01 resolv.conf

7.20 Step 20
To display the last 4 lines of the /etc/hosts file (the total number of lines in this file is 7, only the last 4 lines will
be displayed), execute the following command:

tail -n -4 /etc/hosts
sysadmin@localhost:~$ tail -n -4 /etc/hosts
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.1.2 localhost

7.21 Step 21
To view the contents of the /etc/hosts file starting from the 3rd line to the end of the file, execute the following
command:

tail –n +3 /etc/hosts
sysadmin@localhost:~$ tail -n +3 /etc/hosts
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.1.2 localhost
7.22 Step 22
The paste command will merge the lines of one or more files, line by line, separating them with a tab as a
delimiter (separator) by default. The paste command is especially useful for files that contain data in column
format. The syntax for the paste command is:

paste [OPTION]... [FILE]...

Execute the following commands to create two files named head and tail and then merge them together into a file
named total:

head -5 words > head


tail -5 words > tail
paste head tail > total
cat total
sysadmin@localhost:~$ head -5 words > head
sysadmin@localhost:~$ tail -5 words > tail
sysadmin@localhost:~$ paste head tail > total
sysadmin@localhost:~$ cat total
A épée's
A's épées
AMD étude
AMD's étude's
AOL études

7.23 Step 23
To merge the two files again using the colon : character as the delimiter instead of the default tab delimiter,
execute the following command:

paste –d : head tail > total


cat total
sysadmin@localhost:~$ paste -d : head tail > total
sysadmin@localhost:~$ cat total
A:épée's
A's:épées
AMD:étude
AMD's:étude's
AOL:études

7.24 Step 24
The cut command is used to extract fields from a text file. The space and tab are the default delimiters and can be
changed using the -d option.

To extract the 1st, 3rd and 4th fields from the /etc/passwd file, execute the following command:

cut –d: -f1,3,4 /etc/passwd | head –n 4


sysadmin@localhost:~$ cut -d: -f1,3,4 /etc/passwd | head -n 4
root:0:0
daemon:1:1
bin:2:2
sys:3:3
In the example above, the head command is used to limit the output of the cut command.

7.25 Step 25
A range of fields can also be provided to the cut command. To extract the fields 1 – 4 from the /etc/passwd file,
execute the following command:

cut –d: -f1-4 /etc/passwd | head –n 4


sysadmin@localhost:~$ cut -d: -f1-4 /etc/passwd | head -n 4
root:x:0:0
daemon:x:1:1
bin:x:2:2
sys:x:3:3

7.26 Step 26
Using the cut command, a specific field or set of fields can also be extracted from data containing fixed width
columns. To extract the contents from column 31 to 44 from the output of the ls -l command, execute the
following command:

ls -l /etc | head | cut -c31-43


sysadmin@localhost:~$ ls -l /etc | head | cut -c31-43

Jul 1 21:35
Mar 7 21:00
Mar 29 17:36
Mar 22 17:41
Mar 22 17:41
Mar 29 17:36
Mar 22 17:40
Apr 4 2018
Apr 2 2018

7.27 Step 27
The sort command is useful for working with data organized in columns. It is used to display a file sorted on a
specific field of data.

sort [OPTION]... [FILE]...

To specify the fields to sort from first to last, use the sort command with one or more -k options.

First, view the file adjectives.txt in the Documents directory using the cat command:

cd Documents/
cat adjectives.txt
sysadmin@localhost:~$ cd Documents/
sysadmin@localhost:~/Documents$ cat adjectives.txt
1 golden
2 honey
3 fruit
4 grey
5 bald

To sort the adjectives.txt file using the second field (i.e., the adjective: 1 golden) as a key, execute the
following command:

sort -k2 adjectives.txt


sysadmin@localhost:~/Documents$ sort -k2 adjectives.txt
5 bald
3 fruit
1 golden
4 grey
2 honey

In the command above, the -k option has one argument: the 2, which indicates the second field to sort.

7.28 Step 28
By default, sort breaks up each line of a file into fields using whitespace (tabs or spaces) as delimiters. To specify
an alternate delimiter, use the -t option.

To sort the /etc/passwd file using the first field (i.e., the user name: bin:x:2:2:bin:/bin:/usr/sbin/nologin)
as a key and using the colon : character as the delimiter, execute the following command:

cd
sort –t: -k1 /etc/passwd | head –n 4
sysadmin@localhost:~/Documents$ cd
sysadmin@localhost:~$ sort -t: -k1 /etc/passwd | head -n 4
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
bind:x:106:111::/var/cache/bind:/usr/sbin/nologin
The head command is used to limit the output to four lines.

7.29 Step 29
To reverse the sorting order in the example from the previous step from ascending to descending, execute the
following command:

sort –t: -k1r /etc/passwd | head –n 4


sysadmin@localhost:~$ sort -t: -k1r /etc/passwd | head -n 4
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
uuidd:x:103:105::/run/uuidd:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin

In the command above, the -k option has two arguments: the 1 indicates the first field to sort and the r argument to
reverse the sort.
7.30 Step 30
For certain fields, the sorting order required may be numerical instead of alphabetical. In order to have the sort
command treat a field numerically, add an n as an argument to the -k option for that key field specification. To
treat the sorting field numerically for the third field of the /etc/passwd file, execute the following command:

sort –t: -k3n /etc/passwd | head –n 4


sysadmin@localhost:~$ sort -t: -k3n /etc/passwd | head -n 4
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin

A closer look at the output above demonstrates that the third field of the /etc/passwd file is now sorted
numerically:

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin

7.31 Step 31
Use the -u option to the sort command to remove duplicate entries, as demonstrated below:

cut -f7 -d: /etc/passwd | head > output


more output
sort -u output
sysadmin@localhost:~$ cut -f7 -d: /etc/passwd | head > output
sysadmin@localhost:~$ more output
/bin/bash
/usr/sbin/nologin
/usr/sbin/nologin
/usr/sbin/nologin
/bin/sync
/usr/sbin/nologin
/usr/sbin/nologin
/usr/sbin/nologin
/usr/sbin/nologin
/usr/sbin/nologin
sysadmin@localhost:~$ sort -u output
/bin/bash
/bin/sync
/usr/sbin/nologin
7.32 Step 32
To remove duplicate lines from the output file and display the count of duplicates, execute the following command:

sort output | uniq –c


sysadmin@localhost:~$ sort output | uniq -c
1 /bin/bash
1 /bin/sync
8 /usr/sbin/nologin

In the command above, the -u option to the sort command rearranges the rows in the file and then removes
duplicates. The uniq command also provides duplicate removal functionality in a slightly different way. It removes
duplicates which are already on consecutive lines i.e. it does not sort data.

The uniq command provides another additional option not supported by the sort command; it can display the
number of duplicates that were counted.

7.33 Step 33
The tr command can be used to translate from one set of characters to another.

tr [OPTION]... SET1 [SET2]

To capitalize the /etc/hosts file with the tr command, execute the following command:

cat /etc/hosts | tr 'a-z' 'A-Z'


sysadmin@localhost:~$ cat /etc/hosts | tr 'a-z' 'A-Z'
127.0.0.1 LOCALHOST
::1 LOCALHOST IP6-LOCALHOST IP6-LOOPBACK
FE00::0 IP6-LOCALNET
FF00::0 IP6-MCASTPREFIX
FF02::1 IP6-ALLNODES
FF02::2 IP6-ALLROUTERS
192.168.1.2 LOCALHOST

7.34 Step 34
To replace the five letters (h, i, p, o, and n) with the five characters (!, @, #, $, and %) in the /etc/hosts file,
execute the following command:

cat /etc/hosts | tr 'hipon' '!@#$%'


sysadmin@localhost:~$ cat /etc/hosts | tr 'hipon' '!@#$%'
127.0.0.1 l$cal!$st
::1 l$cal!$st @#6-l$cal!$st @#6-l$$#back
fe00::0 @#6-l$cal%et
ff00::0 @#6-mcast#ref@x
ff02::1 @#6-all%$des
ff02::2 @#6-allr$uters
192.168.1.2 l$cal!$st
7.35 Step 35
The sed command is a non-interactive editor that can be used to modify, insert, and delete text based on pattern
matching with the specified string. The sed command combined with regular expressions gives very powerful text
processing capabilities.

sed [OPTION]... {SCRIPT} [FILE]...

When performing a search and replace operation, the sed command will only replace the first occurrence of the
search pattern by default. To replace all occurrences of the pattern, add the global modifier g after the final slash.

s/PATTERN/REPLACEMENT/g

To replace all occurrences of the word host with the word NAME in the /etc/hosts file globally, execute the
following command:

cat /etc/hosts
sed 's/host/NAME/g' /etc/hosts
sysadmin@localhost:~$ cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.1.2 localhost
sysadmin@localhost:~$ sed 's/host/NAME/g' /etc/hosts
127.0.0.1 localNAME
::1 localNAME ip6-localNAME ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.1.2 localNAME

7.36 Step 36
The sed command is also able to insert text before a pattern. For this type of expression, do not use the s character
before the first slash; use an insert change with the i\ expression.

/PATTERN/i\TEXT\

To insert the word Report in the /etc/hosts file preceding the line containing 127.0.0.1, execute the following
command:

sed '/127.0.0.1/i\Report' /etc/hosts


sysadmin@localhost:~$ sed '/127.0.0.1/i\Report' /etc/hosts
Report
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.1.2 localhost
7.37 Step 37
The sed command is also able to insert text after a pattern. For this type of expression, use an insert change with
the a\ expression.

/PATTERN/a\TEXT\

To append the string End of report in the /etc/hosts file following the line containing allrouters, execute
the following command:

sed '/allrouters/a\End of report' /etc/hosts


sysadmin@localhost:~$ sed '/allrouters/a\End of report' /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
End of report
192.168.1.2 localhost

7.38 Step 38
The sed command can also be used to search for a line of text containing a pattern and then delete the lines that
match. Place the pattern to search for between two slashes followed by a d to carry out this operation:

/PATTERN/d

To delete lines that contain "localhost" in the /etc/hosts file, execute the following command:

sed '/localhost/d' /etc/hosts


sysadmin@localhost:~$ sed '/localhost/d' /etc/hosts
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
NDG Introduction to Linux I - Chapter 8: Regular Expressions

8.1 Introduction
⁠ Regular expressions (or regex) define a search pattern. They are similar to globbing in that they can be expanded
to match certain sequences of characters in text, but have more variety and power.

A regex pattern is composed of literal characters and operators.

A literal character in a pattern represents the character itself. It has no special meaning, and no substitution is
performed. Literal characters include letters, numbers, some punctuation characters, and basically any other
character that is not an operator.

An operator is a special character or character sequence that has special meaning. Operators give regular
expressions their superpowers! Operators are sometimes referred to as metacharacters. The word “operator” more
readily conveys transformative action, so we will use that term in this chapter.

A regular expression has two common forms: basic and extended. Extended regular expressions support more
operators than their basic counterparts. Most commands that can use regular expressions can interpret basic regular
expressions. Extended regular expressions are not available for all commands and may require an additional option
for them to work correctly.

The man page for regex is a good source of information to learn about basic vs. extended regex, the syntax for
regex, and regex compatibility:

sysadmin@localhost:~$ man regex


REGEX(7) Linux Programmer's Manual REGEX(7)

NAME
regex - POSIX.2 regular expressions

DESCRIPTION
Regular expressions ("RE"s), as defined in POSIX.2, come in two forms:
modern REs (roughly those of egrep; POSIX.2 calls these "extended" REs)
and obsolete REs (roughly those of ed(1); POSIX.2 "basic" REs). Obso-
lete REs mostly exist for backward compatibility in some old programs;
they will be discussed at the end. POSIX.2 leaves some aspects of RE
syntax and semantics open; "(!)" marks decisions on these aspects that
may not be fully portable to other POSIX.2 implementations.

A (modern) RE is one(!) or more nonempty(!) branches, separated by '|'.


It matches anything that matches one of the branches.

A branch is one(!) or more pieces, concatenated. It matches a match


for the first, followed by a match for the second, and so on.

A piece is an atom possibly followed by a single(!) '*', '+', '?', or


bound. An atom followed by '*' matches a sequence of 0 or more matches
of the atom. An atom followed by '+' matches a sequence of 1 or more
Manual page regex(7) line 1 (press h for help or q to quit)

The examples displayed in this chapter will make use of the grep command to demonstrate regular expressions.
The grep command is able to filter text from data, providing a very visual demonstration of how regular
expressions work. The grep command that will be used is actually an alias that runs grep --color so that the text
that matches will be displayed in a red color.
Note

Unlike globs, regular expressions are only supported by a small set of commands. This is because glob expansion
is usually provided by the shell; the command (in most cases) does not need to worry about the implementation of
glob expansion.

On the other hand, commands that support regular expressions must implement regular expression logic, and all the
complexity and extra code that comes with them.

Important

The pattern argument of a command should be protected by strong quotes to prevent the shell from misinterpreting
them as special shell characters. This means that you should place single quotes ' around a regular expression. The
following example demonstrates how not placing single quotes around special characters will result in unexpected
output, which is resolved by adding single quotes:

sysadmin@localhost:~$ echo Use single quotes around characters like $ & * ; .


[1] 85
Use single quotes around characters like $
Desktop: command not found
[1]+ Done echo Use single quotes around characters like $
-bash: .: filename argument required
.: usage: . filename [arguments]
sysadmin@localhost:~$ echo Use single quotes around characters like '$ & * ; .'
Use single quotes around characters like $ & * ; .

8.2 Basic Regular Expressions


The simplest of all regular expressions just use literal characters, such as alphanumeric characters. For example, to
locate all lines of the /etc/passwd file that contain the expression root, use the following command:

sysadmin@localhost:~$ grep 'root' /etc/passwd


root:x:0:0:root:/root:bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

Although very useful for the grep command, literal characters alone provide no wildcarding or special matching
capabilities. For that, let‟s introduce the operators that are available in basic regular expressions.

Basic Regex Operator Meaning


Period . Matches any one single character.
operator
[ ]
Defines a list or range of literal characters that can match one character. If the first
List operator
[^ ] character is the negation ^ operator, it matches any character that is not in the list.
Asterisk * Matches zero or more instances of the previous character.
operator
If ^ is the first character in the pattern, then the entire pattern must be present at the
Front anchor ^
beginning of the line to match. If ^ is not the first character, then it is treated as an
operator
ordinary literal ^ character.
Back anchor $ If $ is the last character in the pattern, then the pattern must be at the end of the line to
operator match, otherwise, it is treated as a literal $ character.
8.2.1 Anchoring
Anchoring is one of the ways regular expressions can be used to narrow search results. For example, the pattern
root appears many times in the /etc/passwd file:

sysadmin@localhost:~$ grep 'root' /etc/passwd


root:x:0:0:root:/root:bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

The front anchor ^ operator can be used to ensure that a pattern appears at the beginning of the line. For example,
to find all lines in /etc/passwd that start with root, use the ^root pattern. Note that the ^ operator must be the
first character in the pattern to be effective.

sysadmin@localhost:~$ grep ^root /etc/passwd


root:x:0:0:root:/root:bin/bash

The back anchor $ operator can be used to ensure a pattern appears at the end of the line, thereby effectively
reducing the search results. To find the lines that end with an r in the alpha-first.txt file, use the r$ pattern:

sysadmin@localhost:~$ cd Documents
sysadmin@localhost:~/Documents$ grep 'r$' alpha-first.txt
B is for Bear
F is for Flower

Again, the position of this operator is important. The $ operator must be the last character in the pattern in order to
be effective as an anchor.

If the ^ and $ operators are used at the beginning and end of the same pattern, the entire line must match the
pattern. Meaning that the only way a line would be returned is if the entire line matched exactly, with no other
characters on the line.

Pattern Meaning
^Hello Matches any line that begins with the Hello string
World$ Matches any line that ends with the World string
^Hello World$ Matches any line which matches the Hello World string exactly

8.2.2 Match a Single Character With .


One of the most useful matching capabilities is provided by the period . operator. It will match any character
except for the new line character. The red.txt file contains a list of words:

sysadmin@localhost:~/Documents$ cat red.txt


red
reef
rot
reeed
rd
rod
roof
reed
root
reel
read

The r..t pattern will find any line that contained the letter r followed by exactly two characters (which can be any
character except a newline) and then the letter t:

sysadmin@localhost:~/Documents$ grep r..t red.txt


root
sysadmin@localhost:~/Documents$ grep r..f red.txt
reef
roof
sysadmin@localhost:~/Documents$ grep r..d red.txt
reed
read
sysadmin@localhost:~/Documents$ grep r.d red.txt
red
rod

Remember, the line does not have to be an exact match, it simply must contain the pattern, as seen here when the
r..t pattern is searched for in the /etc/passwd file:

sysadmin@localhost:~/Documents$ grep r..t /etc/passwd


root:x:0:0:root:/root:/bin/bash
operator:x:1000:37::/root:

8.2.3 Match a Single Character With [ ]


The list [ ] operator works in regular expressions similar to how they work in glob expressions; they match a
single character from the list or range of possible characters contained within the brackets.

For example, given the profile.txt file:

sysadmin@localhost:~/Documents$ cat profile.txt


Hello my name is Joe.
I am 37 years old.
3121991
My favorite food is avocados.
I have 2 dogs.
123456789101112

To find all the lines in the profile.txt file that have a number in them, use either the [0123456789] or [0-9]
pattern:

sysadmin@localhost:~/Documents$ cat profile.txt | grep [0-9]


I am 37 years old.
3121991
I have 2 dogs.
123456789101112

Note

In the last example, the pipe | character is used to send the output of one command to another. Some of the
following examples use the cat command to send the contents of a file to the grep command.
As explained later in this chapter, the pipe | character can also be used as an alternation operator within an
extended regular expression. This should not be confused with the use of pipes in output chains, such as the cat |
grep examples.

Pipes will be covered in greater detail later in the course.

To find all the lines which contain any non-numeric characters, insert the negation ^ operator as the first character
inside the brackets. This negates the characters listed:

sysadmin@localhost:~/Documents$ cat profile.txt | grep [^0-9]


Hello my name is Joe.
I am 37 years old.
My favorite food is avocados.
I have 2 dogs.

Note

Do not mistake [^0-9] to match lines which do not contain numbers. It actually matches lines which contain non-
number characters. Look at the original file to see the difference. The third and sixth lines only contain numbers,
they do not contain non-numbers, so those lines do not match.

When other regular expression operators are placed inside of the list [ ] operators, they are treated as literal
characters. For example, the . character normally matches any one character, but when placed inside the square
brackets, then it will just match the . character itself. In the example, only lines which contain the literal .
character are matched.

sysadmin@localhost:~/Documents$ cat profile.txt | grep [.]


Hello my name is Joe.
I am 37 years old.
My favorite food is avocados.
I have 2 dogs.

8.2.4 Match a Single Character With *


The asterisk * operator is used to match zero or more occurrences of the character preceding it. For example, the
e* pattern would match zero or more occurrences of the e character:

sysadmin@localhost:~/Documents$ cat red.txt


red
reef
rot
reeed
rd
rod
roof
reed
root
reel
rood
read
sysadmin@localhost:~/Documents$ cat red.txt | grep 're*d'
red
reeed
rd
reed
It is also possible to match zero or more occurrences of a list of characters by utilizing the square brackets:

sysadmin@localhost:~/Documents$ cat red.txt | grep 'r[oe]*d'


red
reeed
rd
rod
reed
rood

When used with only one other character, the asterisk * operator isn't very helpful. Any of the following patterns
would match every string or line in the file: '.*' 'e*' 'b*' 'z*' This is because the asterisk * operator can
match zero occurrences of a pattern.

sysadmin@localhost:~/Documents$ cat red.txt | grep 'z*'


red
reef
rot
reeed
rd
rod
roof
reed
root
reel
read
sysadmin@localhost:~/Documents$ cat red.txt | grep 'e*'
red
reef
rot
reeed
rd
rod
roof
reed
root
reel
read

In order to make the asterisk * operator useful, it is necessary to create a pattern which includes more than just the
one character preceding the asterisk * operator. For example, the results above can be refined by adding another e
to make the pattern ee* effectively matching every line which contains at least one e.

sysadmin@localhost:~/Documents$ cat red.txt | grep 'ee*'


red
reef
reeed
reed
reel
read
Pattern Meaning
abc* Matches the ab string followed by one or more c characters
a* Matches zero or more occurrences of the a character
aa* Matches one or more occurrences of the a character
[A-Z][aeiou]* Matches a single capital letter followed by one or more vowel characters
8.3 Extended Regular Expressions
While most commands that use regular expressions can interpret basic regular expressions, the use of extended
regular expressions often requires a special option be provided to the command to recognize them.

Extended regular expression patterns support the basic regex operators PLUS the following additional operators:

Extended Regex Operators Meaning


Grouping operator ( ) Groups characters together to form a subpattern.
Asterisk operator * Previous character (or subpattern) is present zero or more times.
Plus operator + Previous character (or subpattern) is present at least one or more times.
Question mark ? Previous character (or subpattern) is present zero or one time (but not more).
operator
Specify minimum, maximum, or exact matches of the previous character (or
Curly brace operator {,}
subpattern).
Alternation operator | Logical OR of choices. For example, abc|def|xyz matches abc or def or xyz.

The grep command understands both basic and extended regular expressions. By default, the grep command
assumes only basic regular expressions, meaning the +, ?, {, |, (, and ) operators are interpreted as literal
characters.

Historically, there is a command called egrep, which is similar to the grep command, but can understand extended
regular expressions. Now, the egrep command is deprecated in favor of using grep with the -E option.

Note

The term subpattern introduced above will be covered in the next section.

8.3.1 Grouping With ( )


The grouping ( ) operator creates groupings that can be used for several purposes. At the most basic level, they
are used to group together characters that can be targeted by matching operators like *, +, ?, or the curly braces {
}.

This grouping is considered to be a subpattern of the pattern. A subpattern is a smaller pattern within a pattern. The
matching operators *, ?, +, and { } that match single characters, can also be applied to subpatterns.

In the example below, parentheses are used to match the M character, followed by the iss subpattern repeated zero
or more times:

sysadmin@localhost:~/Documents$ echo 'Miss Mister Mississippi Missed Mismatched' | grep -E


'M(iss)*'
Miss Mister Mississippi Missed Mismatched

Note

Don't forget to use grep -E in order to get the command to recognize the extended regular expression character.
8.3.2 Match a Repeated Character With +
Another solution to the problems of using the asterisk * operator is to use the extended regex plus + operator,
instead. This matches at least one of the previous characters, instead of zero, so it is much more selective. For
example, the e+ pattern would only match if the text contained one or more e characters, yielding the same results
as the previously used ee* pattern:

sysadmin@localhost:~/Documents$ cat red.txt | grep -E 'e+'


red
reef
reeed
reed
reel
read
sysadmin@localhost:~/Documents$ cat red.txt | grep -E 're+d'
red
reed
reed

In the example below, grouping is used in conjunction with the + operator to match the recurring iss subpattern:

sysadmin@localhost:~/Documents$ echo 'Miss Mississippi missed her mister.' | grep -E


'(iss)+'
Miss Mississippi missed her mister.
Pattern Meaning
xyz+ Matches the xy string followed by one or more of the z character
(xyz)+ Matches one or more copies of the xyz string

8.3.3 Match an Optional Character With ?


The extended regex question mark ? operator matches the preceding character or grouping zero or one times,
making it optional. For example, consider the word color, which can also be spelled with an optional u as colour
(depending on the English dialect being used). Use the colou?r pattern to match either spelling:

sysadmin@localhost:~/Documents$ grep -E 'colou?r' spelling.txt


American English: Do you consider gray to be a color or a shade?
British English: Do you consider grey to be a colour or a shade?
Pattern Meaning
xyz? Matches the xy string followed by zero or one of the z character
x(yz)? Matches the x character followed by zero or one of the yz string

8.3.4 Match a Repeated Character With { }


The extended regex curly brace { } operator is used to specify the number of occurrences of the preceding
character or subpattern.

Pattern Meaning
a{0,} Zero or more a characters
Pattern Meaning
a{1,} One or more a characters
a{0,1} Zero or one a characters
a{5} Five a characters
a{,5} Five or fewer a characters
a{3,5} From three to five a characters

To demonstrate, the { } operator in action, the example below matches one or more instances of the letter r in the
animals.txt file:

sysadmin@localhost:~/Documents$ grep -E 'r{1,}' animals.txt


1 retriever
2 badger

8.3.4.1 Comparing Quantifiers


The *, +, ?, and { } characters are considered to be quantifying operators. The curly braces { } can be used
instead of the other quantifiers. The following chart illustrates some examples of using curly braces:

Pattern Meaning
xyz*
Matches the xy string followed by zero or more of the z character
xyz{0,}
x(yz)*
Matches the x character followed by zero or more copies of the yz string
x(yz){0,}
xyz+
Matches the xy string followed by one or more of the z character
xyz{1,}
(xyz)+
Matches one or more copies of the xyz string
(xyz){1,}
xyz?
Matches the xy string followed by zero or one of the z character
xyz{0,1}
xyz{,5} Matches the xy string followed by five or fewer of the z character
xyz{5,} Matches the xy string followed by five or more of the z character
xyz{3,5} Matches the xy string followed by three to five of the z character
[0-9]{1,3}% Matches one to three numeric characters, followed by the % character
8.3.5 Match Subpatterns With |
When used in extended regular expressions, the alternation | operator separates alternative expressions that can
match. It acts similarly to a Boolean OR.

For example, to match both the word gray or its alternative spelling grey, use the expression gray|grey:

sysadmin@localhost:~/Documents$ grep -E 'gray|grey' spelling.txt


American English: Do you consider gray to be a color or a shade?
British English: Do you consider grey to be a colour or a shade?

Parentheses can also be used with alternation. The previous example of gray|grey could be rewritten as
gr(a|e)y. When parentheses are used in regular expressions from the command line, remember to enclose them in
the single quotes to prevent the shell from interpreting them:

sysadmin@localhost:~/Documents$ grep -E 'gr(a|e)y' spelling.txt


American English: Do you consider gray to be a color or a shade?
British English: Do you consider grey to be a colour or a shade?
Pattern Meaning
abc|xyz Matches the abc string or the xyz string
ab(c|d|e)
Matches the ab string followed by a c or d or e character
ab[cde]

8.4 Using Special Regular Expression Sequences


In basic regular expressions putting a backslash \ character in front of another character means to match that
character literally. For example, matching the . character with the \. pattern is appropriate.

However, the backslash \ character can also be used for designated backslash character combinations, called
backslash sequences. Backslash sequences can represent special operators or character classes, as illustrated in the
following chart.

A character class represents a range of characters. The digit character class (abbreviated \d) matches any number
[0-9]. The word character class (abbreviated \w) matches any upper and lowercase ASCII character, and numeric
digits [A-Za-z0-9]. More character classes will be introduced in the extended regular expressions section.

Backslash Sequence Pattern Equivalent Matches


\b Word boundary operator
\B Not a word boundary operator
\w [A-Za-z0-9] Word character class
\W [^A-Za-z0-9] Not a word character class
\d [0-9] Digit character class
\s Whitespace character class
\S Not a whitespace character class
\\ Literal backslash character
To demonstrate this concept, take into consideration that words in files don't always have whitespace around them,
sometimes there are commas or other punctuation marks before or after a word. The \b operator can help identify
the edges of words that don't have whitespace around them. Problems like the following may occur if the word
boundary operator is not used:

sysadmin@localhost:~/Documents$ echo 'This is useful' | sed 's/is/was/'


Thwas is useful

Note

Recall that to do a simple search and replace operation with the sed command, use the following script, or
expression:

s/PATTERN/REPLACEMENT/

In the syntax above, the s character signifies substitution and the forward slash / character is used as a delimiter.

Notice that the sed command searched its input for is and replaced it with was. It didn't limit its replacement to the
is that was a separate word, it also affected part of the word This replacing it with Thwas.

It would be better to use the \bis\b search criteria (the is pattern with word boundaries around it) to match the
word is:

sysadmin@localhost:~/Documents$ echo 'This is useful' | sed 's/\bis\b/was/'


This was useful

To delete certain text, the sed command can be used to remove characters defined within square brackets.

For example, if you wanted to delete the leading numbers in the animals.txt file and create a new file without the
numbers, you could use the sed command and define the range 0-9 to be removed:

sysadmin@localhost:~/Documents$ cat animals.txt


1 retriever
2 badger
3 bat
4 wolf
5 eagle
sysadmin@localhost:~/Documents$ sed 's/[0-9]//g' animals.txt > newanimals.txt
sysadmin@localhost:~/Documents$ cat newanimals.txt
retriever
badger
bat
wolf
eagle

Consider This

In some commands, parentheses can be used for referring back to what was matched. What was matched by the
first set of parentheses can be referred to as \1, the second as \2, and so on. For example, if you had a file that
contained a list of people with their first name and then their last name, you could reverse the names with a comma
between them with the following sed command:

sysadmin@localhost:~/Documents$ cat people.csv


Dennis,Richie
Andrew,Tanenbaum
Ken,Thompson
Linus,Torvalds
sysadmin@localhost:~/Documents$ sed -r 's/(\w+),(\w+)/\2, \1/' people.csv
Richie, Dennis
Tanenbaum, Andrew
Thompson, Ken
Torvalds, Linus

The -r option to the sed command indicates the use of extended regular expressions.

8.5 Escaping Special Characters With \


In some cases, you may want to match a character that functions as an operator as a literal character. For example,
consider the newhome.txt file:

sysadmin@localhost:~/Documents$ cat newhome.txt


Thanks for purchasing your new home!!

**Warning** it may be haunted.

There are three bathrooms.

**Beware** of the ghost in the bedroom.

The kitchen is open for entertaining.

**Caution** the spirits don't like guests.

Good luck!!!

The asterisk * character functions an operator, so searching for the re* pattern matches every line which contained
an r character, followed by zero or more of the e character (which means it matches any line containing an r
character).

sysadmin@localhost:~/Documents$ grep 're*' newhome.txt


Thanks for purchasing your new home!!
**Warning** it may be haunted.
There are three bathrooms.
**Beware** of the ghost in the bedroom.
The kitchen is open for entertaining.
**Caution** the spirits don't like guests.

But what if you want to search for a literal asterisk * character? In basic regular expressions, the backslash \
character is as an escape character, meaning the character immediately following it will be interpreted as a literal
character, instead of an operator.

To look for a literal asterisk * character, escape it by placing a backslash \ character before the * character:

sysadmin@localhost:~/Documents$ grep 're\*' newhome.txt


**Beware** of the ghost in the bedroom.

The backslash \ character behaves slightly differently depending on whether or not you are in the realm of basic or
extended regular expressions, and whether or not you are using basic or extended operators.
The Realm of Basic Regular Expressions

When you use the grep command without the -E option, you are in the realm of basic regular expressions. In this
realm, basic operators are interpreted as basic operators. And, as seen in the preceding examples, escaping a basic
operator (placing a backslash \ character in front of it) forces it to be interpreted as a literal character.

In the realm of basic regular expressions, the extended regular expression operators do not have special meaning;
they are interpreted as literal characters. As a result, the backslash \ character has the opposite effect on the
extended operators as it does on basic operators. If an extended operator is escaped in basic regular expressions, it
acts like an extended operator, instead of a literal character.

Not Escaped Escaped

Basic Operators
Operators Literal
. [ ] ^ * ^ $
Extended Operators
Literal Operators
? + { } | ( )

The Realm of Extended Regular Expressions

When the grep -E or egrep commands are used, you are in the realm of extended regular expressions. This means
all regular expression operators (both basic and extended) are interpreted as operators.

Similarly, in extended regular expressions, the backslash \ character treats all operators the same. When an
operator is escaped in the realm of extended regular expressions, it is interpreted as a literal character, regardless of
whether it is a basic or extended operator.

Not Escaped Escaped

Basic Operators
Operators Literal
. [ ] ^ * ^ $
Extended Operators

? + { } | ( )

8.6 Using the fgrep Command


If the entire pattern uses no special characters and you need to use a backslash to escape the special meaning of
characters, then you should use the fixed strings grep fgrep command. The fgrep command always treats its
pattern as literal characters, so you don‟t have to use the backslash to escape the regex characters:

sysadmin@localhost:~/Documents$ cat newhome.txt | fgrep '**'


**Warning** it may be haunted.
**Beware** of the ghost in the bedroom.
**Caution** the spirits don't like guests.
sysadmin@localhost:~/Documents$ cat newhome.txt | fgrep '**Warning** it may be haunted.'
**Warning**it may be haunted.
8.7 Options for the grep Command
The man page for the grep command provides basic information about regular expressions, as well as options for
the grep, egrep, and fgrep commands. The following table lists some of the more commonly used options:

Option Meaning
-i Case insensitive
-v Invert search results (logically negates criteria) - returns all lines that don't contain the specified pattern
-l List the file name of content in file matches
-r Perform a recursive search including subdirectories
-w Match whole word only
-q Quietly operate without producing output

The -i option makes the grep command case insensitive, ignoring capitalization in the expression:

sysadmin@localhost:~/Documents$ grep 'i' profile.txt


Hello my name is Joe.
My favorite food is avocados.
sysadmin@localhost:~/Documents$ grep -i 'i' profile.txt
Hello my name is Joe.
I am 37 years old.
My favorite food is avocados.
I have 2 dogs.

The -v option inverts the search, displaying the lines that don't match the expression. The following search pattern
matches all lines which do not contain numeric characters:

sysadmin@localhost:~/Documents$ grep -v [0-9] profile.txt


Hello my name is Joe.
My favorite food is avocados.

Normally, the grep command will be able to match the expression, even if it is part of another word. When using
the -w option, the expression must match a complete word. This is similar to the word boundary regular expression
that was previously mentioned, however, keep in mind that \b works for many commands that support extended
regular expressions, while the -w option is specific to the grep command:

sysadmin@localhost:~/Documents$ grep 'am' profile.txt


Hello my name is Joe.
I am 37 years old.
sysadmin@localhost:~/Documents$ grep -w 'am' profile.txt
I am 37 years old.

8.8 Using grep to Search Multiple Files


The grep command can search multiple files if a glob character is used for the file names. Keep in mind that the
grep command cannot search a file that the user does not have privileges to read. The following command will
search all of the files in the current directory for the Linux pattern:

sysadmin@localhost:~/Documents$ grep 'Linux' ./*


grep: ./School: Is a directory
grep: ./Work: Is a directory
./linux.txt:Linux is growing !
./linux.txt:Linux is growing !
./linux.txt:Linux is growing !
./linux.txt:Linux is growing !
./os.csv:1991,Linux,Torvalds
./words:Linux
./words:Linux's

Rather than displaying every line in every file that matches the pattern, it may be preferable to see a list of the file
names that have at least one line that matches the pattern. The -l option will list file names that contain matches,
rather than the matches themselves:

sysadmin@localhost:~/Documents$ grep -l 'Linux' ./*


grep: ./School: Is a directory
grep: ./Work: Is a directory
./linux.txt
./os.csv
./words

Using the -r option will allow for directory searches to be recursive, rather than just the files in the current
directory. Often, this option is used in conjunction with the -l option:

sysadmin@localhost:~/Documents$ grep -rl 'rare' /etc/*


grep: /etc/bind/rndc.key: Permission denied
grep: /etc/gshadow: Permission denied
grep: /etc/gshadow-: Permission denied
grep: /etc/security/opasswd: Permission denied
grep: /etc/shadow: Permission denied
grep: /etc/shadow-: Permission denied
/etc/skel/.bashrc
grep: /etc/ssh/ssh_host_ecdsa_key: Permission denied
grep: /etc/ssh/ssh_host_ed25519_key: Permission denied
grep: /etc/ssh/ssh_host_rsa_key: Permission denied
grep: /etc/ssl/private: Permission denied
grep: /etc/sudoers: Permission denied
grep: /etc/sudoers.d/README: Permission denied

Note

The errors above are generated by directories the user does not have permission to view. It is possible to eliminate
this error output from the terminal by redirecting the standard error.

Redirection will be explained in greater detail later in this course.


Key Terms
egrep
Command that performs the same function as grep -E. This command has been deprecated, but is around
for historical applications.
Section 8.3 | Section 8.7
fgrep
Command that performs the same function grep -F. This command has been deprecated, but is around for
historical applications.
Section 8.6
grep
Command used ot print lines matching a specific pattern. grep searches the named input FILE for lines
containing a match to a given PATTERN.
Section 8.1
regex(7)
Regular expression. This is a term used to describe a codified method of searching for text ,or other strings
in text.
Section 8.1
sed
A non-interactive editor that can be used to modify text.
| Section 8.4
LAB 08

8.0 Introduction
Regular expressions are patterns interpreted by certain commands. The patterns are enclosed in single quotes to
prevent the shell from misinterpreting them. Regular expressions differ from globbing, which is a function
performed by the shell and therefore not associated directly with any command.

The grep command is used to demonstrate the use of regular expressions.

There are two types of regular expressions – basic and extended. While the basic expressions are interpreted by
most commands, the extended expressions can be used along with an option in commands that support their
interpretation.

8.1 Step 1
The simplest of all regular expressions just use literal characters, such as alphanumeric characters. Although very
useful for the grep command, literal characters alone provide no wildcarding or special matching capabilities. For
that, you will need to use the operators that are available in basic regular expressions.

Basic Regex Operator Meaning


Period . Matches any one single character.
operator
[ ]
Defines a list or range of literal characters that can match one character. If the first
List operator
[^ ] character is the negation ^ operator, it matches any character that is not in the list.
Asterisk * Matches zero or more instances of the previous character.
operator
If ^ is the first character in the pattern, then the entire pattern must be present at the
Front anchor ^
beginning of the line to match. If ^ is not the first character, then it is treated as an
operator
ordinary literal ^ character.
Back anchor $ If $ is the last character in the pattern, then the pattern must be at the end of the line to
operator match, otherwise, it is treated as a literal $ character.

To find the occurrences of the pattern root in the /etc/passwd file, execute the following command:

grep 'root' /etc/passwd

sysadmin@localhost:~$ grep 'root' /etc/passwd


root:x:0:0:root:/root:/bin/bash
operator:x:1000:37::/root:/bin/bash
The pattern argument of a command should be protected by strong quotes to prevent the shell from misinterpreting
them as special shell characters. This means that you should place single quotes „ around a regular expression.
8.2 Step 2
The front anchor ^ operator can be used to ensure that a pattern appears at the beginning of the line. To find the
occurrences of the pattern root at the beginning of the line in the /etc/passwd file, execute the following
command:

grep '^root' /etc/passwd


sysadmin@localhost:~$ grep '^root' /etc/passwd
root:x:0:0:root:/root:/bin/bash

8.3 Step 3
The back anchor $ operator can be used to ensure a pattern appears at the end of the line. To find the occurrences
of the pattern bash at the end of the line in the /etc/passwd file, execute the following command:

grep 'bash$' /etc/passwd

sysadmin@localhost:~$ grep 'bash$' /etc/passwd


root:x:0:0:root:/root:/bin/bash
operator:x:1000:37::/root:/bin/bash
sysadmin:x:1001:1001:System Administrator,,,,:/home/sysadmin:/bin/bash
alice:x:1002:1005:Alice White:/home/alice:/bin/bash
maya:x:1003:1006:Maya Brown:/home/maya:/bin/bash
joe:x:1004:1007:Joe Green:/home/joe:/bin/bash

8.4 Step 4
The period operator . is used to match any character except the newline character. To match the pattern r..t (i.e.
any pattern containing r, followed by exactly two characters, and then followed by t) in the /etc/passwd file,
execute the following command:

grep 'r..t' /etc/passwd


sysadmin@localhost:~$ grep 'r..t' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:1000:37::/root:/bin/bash

8.5 Step 5
The list operator [] (bracket notation) that is used in file globbing has a similar implementation in regular
expressions, which is to define a list or range of literal characters that can match one character. For example, to
match the single characters 0, 1, 2, 3, and 4 between colon : characters in the /etc/passwd file, execute the
following command:

grep ':[01234]:' /etc/passwd


sysadmin@localhost:~$ grep ':[01234]:' /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
Output Omitted...
8.6 Step 6
When placed in the beginning of the list operator [], the anchor operator ^ denotes negation of the pattern to be
matched. The following will match a single character between the colon : characters that is not a 0, 1, 2, 3, 4, or x:

grep ':[^01234x]:' /etc/passwd


sysadmin@localhost:~$ grep ':[^01234x]:' /etc/passwd
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin

8.7 Step 7
The asterisk operator * is used to match zero or more instances of the previous value. Execute the following
command to match a colon : character, followed by zero or more numbers, followed by a colon:

tail /etc/passwd | grep ':[0-9]*:'


sysadmin@localhost:~$ tail /etc/passwd | grep ':[0-9]*:'
uuidd:x:103:105::/run/uuidd:/usr/sbin/nologin
syslog:x:104:108::/home/syslog:/usr/sbin/nologin
messagebus:x:105:109::/nonexistent:/usr/sbin/nologin
bind:x:106:111::/var/cache/bind:/usr/sbin/nologin
sshd:x:107:65534::/run/sshd:/usr/sbin/nologin
operator:x:1000:37::/root:/bin/bash
sysadmin:x:1001:1001:System Administrator,,,,:/home/sysadmin:/bin/bash
alice:x:1002:1005:Alice White:/home/alice:/bin/bash
maya:x:1003:1006:Maya Brown:/home/maya:/bin/bash
joe:x:1004:1007:Joe Green:/home/joe:/bin/bash

The output in the example above shows how, sometimes, using the asterisk * operator results in bad matches. For
example, in the last six lines of the output, there are five lines that match two colon :: characters only. In most
cases, it may be more useful to match one or more characters rather than zero or more. However, this will require
the use of an extended regular expression (the plus + operator) which will be demonstrated later in the lab.

In this example, the pipe | character is used to send the output of one command to another. Some of the following
examples use the cat command to send the contents of a file to the grep command. Pipes will be covered in
greater detail later in the course.

The pipe | character can also be used as an alternation operator within an extended regular expression. This should
not be confused with the output chaining use of pipe in the cat | grep examples
8.8 Step 8
In basic regular expressions, putting a backslash \ character in front of another character means to match that
character literally. For example, using the \. pattern is an appropriate way to match the . character.

To display the file names of the files in the /etc directory that start with the letters rc, followed by a digit in the
range 3-6, and ending in the file extension .d, execute the following command with the regular expression rc[3-
6]*\.d:

ls /etc | grep 'rc[3-6]*\.d'

sysadmin@localhost:~$ ls /etc | grep 'rc[3-6]*\.d'


rc3.d
rc4.d
rc5.d
rc6.d

In the command above, the asterisk * operator is used to find zero or more instances of digit characters in the range
3-6.

8.9 Step 9
The use of extended regular expressions often requires a special option to be provided to the command to recognize
them. The grep -E command is used to recognize the extended regular expression character. Extended regular
expression patterns support the basic regex operators PLUS the following additional operators:

Extended Regex Operators Meaning


Grouping operator ( ) Groups characters together to form a subpattern.
Asterisk operator * Previous character (or subpattern) is present zero or more times.
Plus operator + Previous character (or subpattern) is present at least one or more times.
Question mark ? Previous character (or subpattern) is present zero or one time (but not more).
operator
Specify minimum, maximum, or exact matches of the previous character (or
Curly brace operator {,}
subpattern).
Alternation operator | Logical OR of choices. For example, abc|def|xyz matches abc or def or xyz.

As indicated in the table above, the plus + operator is used to match one or more instances of the previous value.
Execute the following command to match a colon : character, followed by one or more numbers, followed by
another colon : character:
tail /etc/passwd | grep -E ':[0-9]+:'
sysadmin@localhost:~$ tail /etc/passwd | grep -E ':[0-9]+:'
uuidd:x:103:105::/run/uuidd:/usr/sbin/nologin
syslog:x:104:108::/home/syslog:/usr/sbin/nologin
messagebus:x:105:109::/nonexistent:/usr/sbin/nologin
bind:x:106:111::/var/cache/bind:/usr/sbin/nologin
sshd:x:107:65534::/run/sshd:/usr/sbin/nologin
operator:x:1000:37::/root:/bin/bash
sysadmin:x:1001:1001:System Administrator,,,,:/home/sysadmin:/bin/bash
alice:x:1002:1005:Alice White:/home/alice:/bin/bash
maya:x:1003:1006:Maya Brown:/home/maya:/bin/bash
joe:x:1004:1007:Joe Green:/home/joe:/bin/bash

8.10 Step 10
The question mark ? operator is a part of extended regular expression characters and is used for making the
previous character optional in the pattern. For example, to match the two different ways to spell aging (aging or
ageing) in the dictionary file, execute the following command:

grep –E "^age?ing$" /usr/share/dict/words


sysadmin@localhost:~$ grep -E "^age?ing$" /usr/share/dict/words
ageing
aging

8.11 Step 11
The extended regex plus + operator matches one or more of the previous characters, instead of zero or more like
the basic regex asterisk * operator. To display the file names of the files in the /etc directory that have the literal
characters rc, followed by one or more digit characters in the range 3-6, a literal period . character, and the letter
d, use the extended regular expression rc[3-6]+\.d:

ls /etc | grep –E 'rc[3-6]+\.d'


sysadmin@localhost:~$ ls /etc | grep -E 'rc[3-6]+\.d'
rc3.d
rc4.d
rc5.d
rc6.d

8.12 Step 12
The egrep command is an alternative to the grep –E command. To match the same extended regular expression
used in the previous example, execute the following command:

ls /etc | egrep 'rc[3-6]+\.d'


sysadmin@localhost:~$ ls /etc | egrep 'rc[3-6]+\.d'
rc3.d
rc4.d
rc5.d
rc6.d
8.13 Step 13
The alternation | operator, which is a part of extended regular expression characters, is used for matching two or
more items. For example, to match the word root or games in the /etc/passwd file, execute the following
command:

grep –E 'root|games' /etc/passwd


sysadmin@localhost:~$ grep -E 'root|games' /etc/passwd
root:x:0:0:root:/root:/bin/bash
games:x:5:60:games:/usr/games:/usr/sbin/nologin
operator:x:1000:37::/root:/bin/bash

8.14 Step 14
The extended regex curly brace {} operator is used to specify the number of occurrences of the preceding character
or subpattern.

Pattern Meaning
a{0,} Zero or more a characters
a{1,} One or more a characters
a{0,1} Zero or one a characters
a{5} Five a characters
a{,5} Five or fewer a characters
a{3,5} From three to five a characters

To find all the occurrences of the letter o exactly twice in the /etc/passwd file, execute the following command:

grep –E "o{2}" /etc/passwd


sysadmin@localhost:~$ grep -E "o{2}" /etc/passwd
root:x:0:0:root:/root:/bin/bash
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
operator:x:1000:37::/root:/bin/bash

8.15 Step 15
The grouping () operator is used to group together characters that can be targeted by matching operators like *, +,
?, or the curly braces {}. This grouping is considered to be a subpattern of the pattern.

In the example below, parentheses are used to match the gr string followed by the ey or ay subpattern repeated
zero or more times:

cat spelling.txt | grep -E ‘gr(ay)|gr(ey)’


sysadmin@localhost:~$ cd Documents/
sysadmin@localhost:~/Documents$ cat spelling.txt | grep -E 'gr(ay)|gr(ey)'
American English: Do you consider gray to be a color or a shade?
British English: Do you consider grey to be a colour or a shade?
sysadmin@localhost:~/Documents$ cd
In the command above, the alternator | operator is used to match both sets of patterns; gr(ay) and gr(ey).

8.16 Step 16
The grouping () operator can also be used to refer back to what was previously matched by referring to the match
corresponding to the first set of parentheses as \1 and the second as \2. For example, to reverse the order of the last
two fields of the /etc/passwd, execute the following command:

head /etc/passwd
head /etc/passwd | sed –r 's/([a-z/]+):([a-z/]+)$/\2:\1/'
sysadmin@localhost:~$ head /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
sysadmin@localhost:~$ head /etc/passwd | sed -r 's/([a-z/]+):([a-z/]+)$/\2:\1/'
root:x:0:0:root:/bin/bash:/root
daemon:x:1:1:daemon:/usr/sbin/nologin:/usr/sbin
bin:x:2:2:bin:/usr/sbin/nologin:/bin
sys:x:3:3:sys:/usr/sbin/nologin:/dev
sync:x:4:65534:sync:/bin/sync:/bin
games:x:5:60:games:/usr/sbin/nologin:/usr/games
man:x:6:12:man:/usr/sbin/nologin:/var/cache/man
lp:x:7:7:lp:/usr/sbin/nologin:/var/spool/lpd
mail:x:8:8:mail:/usr/sbin/nologin:/var/mail
news:x:9:9:news:/usr/sbin/nologin:/var/spool/news

In the second command above, the entire expression matches the last two fields in the /etc/passwd file. For
example, consider the first line in the /etc/passwd file.

The first ([a-z/]+) subpattern matches /bin/bash:

's/([a-z/]+):([a-z/]+)$/\2:\1/'
root:x:0:0:root:/bin/bash:/root

The second ([a-z/]+) subpattern matches /root:

's/([a-z/]+):([a-z/]+)$/\2:\1/'
root:x:0:0:root:/bin/bash:/root

The dollar sign $ operator, following the second subpattern is used to match the fields at the end of the line:

's/([a-z/]+):([a-z/]+)$/\2:\1/'
root:x:0:0:root:/bin/bash:/root

The list [ ] operators treat other regular expression operators as literal characters. Therefore, to ensure that the
forward slash / character in the file name is interpreted literally, it is placed inside the brackets:

's/([a-z/]+):([a-z/]+)$/\2:\1/'
root:x:0:0:root:/bin/bash:/root

Lastly, the grouping () operator is used to refer to the first set of parentheses as \1 and the second as \2, which the
sed command will use to reverse the order of the last two fields:

's/([a-z/]+):([a-z/]+)$/\2:\1/'

8.17 Step 17
Special characters, such as the asterisk * operator and the plus + operator, need to be escaped using the backslash \
character to avoid their interpretation as a special character during expression evaluation. To find all occurrences of
the pattern * in the /etc/rsyslog.conf file, execute the following command:

grep "\*" /etc/rsyslog.conf


sysadmin@localhost:~$ grep "\*" /etc/rsyslog.conf
$IncludeConfig /etc/rsyslog.d/*.conf

8.18 Step 18
An alternative to using the backslash \ character to escape every special character is to use the fgrep command,
which always treats its pattern as literal characters.

To match the * pattern in the /etc/rsyslog.conf file, execute the following command:

fgrep "*" /etc/rsyslog.conf


sysadmin@localhost:~$ fgrep "*" /etc/rsyslog.conf
$IncludeConfig /etc/rsyslog.d/*.conf

8.19 Step 19
Regular expressions also use the backslash \ character for designated backslash character combinations, called
backslash sequences. Backslash sequences can represent special operators or character classes. For example, \b
indicates the word boundary operator, \s indicates the whitespace character, and \w indicates a word character.

Word boundary patterns can be specified when searching for a pattern by using the backslash sequence: \b. To
replace the word is with was in the /etc/wgetrc file, execute the following command:

sed 's/\bis\b/was/' /etc/wgetrc | head -n -45 | tail -n -15


sysadmin@localhost:~$ sed 's/\bis\b/was/' /etc/wgetrc | head -n -45 | tail -n -15
# You can set up other headers, like Accept-Language. Accept-Language
# was *not* sent by default.
#header = Accept-Language: en

# You can set the default proxies for Wget to use for http, https, and ftp.
# They will override the value in the environment.
#https_proxy = http://proxy.yoyodyne.com:18023/
#http_proxy = http://proxy.yoyodyne.com:18023/
#ftp_proxy = http://proxy.yoyodyne.com:18023/

# If you do not want to use proxy at all, set this to off.


#use_proxy = on

# You can customize the retrieval outlook. Valid options are default,
# binary, mega and micro.

8.20 Step 20
The grep command provides the -i option for making the pattern matching case insensitive. To match both upper
and lower case of the abid pattern in the /usr/share/dict/words file, execute the following command:

grep –i "abid" /usr/share/dict/words


sysadmin@localhost:~$ grep -i "abid" /usr/share/dict/words
Abidjan
Abidjan's
abide
abided
abides
abiding
rabid

8.21 Step 21
The -v option for the grep command will cause all lines that don't match the pattern to be displayed. To display all
lines that do not contain the local pattern in the /etc/hosts file, execute the following commands:

more /etc/hosts
grep –v "local" /etc/hosts
sysadmin@localhost:~$ more /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.1.2 localhost
sysadmin@localhost:~$ grep -v "local" /etc/hosts
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
8.22 Step 22
In the examples seen so far, the grep command has been used for searching patterns within a single file. The grep
command can also be used for searching in multiple files. To match the test pattern in the files that match m* in
the /etc directory, execute the following command:

grep "test" /etc/m*


sysadmin@localhost:~$ grep "test" /etc/m*
/etc/mailcap:application/x-troff-man; /usr/bin/man -X100 -l '%s'; test=test -n "
$DISPLAY" -a -e /usr/bin/gxditview; description=Man page
/etc/mailcap:text/troff; /usr/bin/man -X100 -l '%s'; test=test -n "$DISPLAY" -a
-e /usr/bin/gxditview; description=Man page
/etc/mailcap:text/plain; view %s; edit=vim %s; compose=vim %s; test=test -x /usr
/bin/vim; needsterminal
/etc/mailcap::text/*; view %s; edit=vim %s; compose=vim %s; test=test -x /usr/bin
/vim; needsterminal
grep: /etc/mc: Is a directory
grep: /etc/modprobe.d: Is a directory
grep: /etc/modules-load.d: Is a directory

8.23 Step 23
To search multiple files but view only the file names instead of every matching line, execute the following
command:

grep –l "script" /etc/mime*


sysadmin@localhost:~$ grep -l "script" /etc/mime*
/etc/mime.types

8.24 Step 24
Using the -r option to the grep command will allow for directory searches to be recursive. To match the find
pattern by recursively searching all of the files in the /etc directory, and then view the matching file names,
execute the following command:

grep -rl 'find' /etc/* 2>/dev/null


sysadmin@localhost:~$ grep -rl 'find' /etc/* 2>/dev/null
/etc/apparmor.d/abstractions/apparmor_api/is_enabled
/etc/apparmor.d/abstractions/apparmor_api/find_mountpoint
/etc/apparmor.d/usr.sbin.tcpdump
/etc/init.d/screen-cleanup
/etc/init.d/ufw
/etc/locale.gen
/etc/rmt
/etc/vim/vimrc
/etc/wgetrc
The 2>/dev/null command is sending the error output (stderr) to the null device so that it is not displayed on the
screen.
NDG Introduction to Linux I - Chapter 9: The vi Editor

9.1 Introduction
The premier text editor for Linux and UNIX is the vi program. While there are numerous editors available for
Linux that range from the tiny editor nano to the massive emacs editor, there are several advantages to the vi
editor:

 The vi editor is available on every Linux distribution in the world. This is not true of any other editor.
 The vi editor can be executed both in a CLI and a GUI. While graphical editors, like gedit from the
Gnome desktop environment or kedit from K desktop environment, are easier to use, they require a GUI,
which servers won't always have running.
 While new features have been added to the vi editor, the core functions have been around for decades. This
means if someone learned the vi editor in the 1970s, they could use a modern version without any problem.
While that may seem trivial today, it may not seem so trivial twenty years from now.

Consider This

The correct way to pronounce "the vi editor" is "the vee-eye editor." The letters vi are short for "visual", but it was
never pronounced "vi" by the developers, but rather the letter "v" followed by the letter "i".

The original vi editor was written by Bill Joy, the co-founder of Sun Microsystems. Since vi is part of the Single
UNIX Specification (SUS), it is required that conforming UNIX-based systems have it. Since the Linux Standards
Base (LSB) mirrors the requirements of SUS, Linux systems that conform to LSB must also include the vi editor.

In reality, most Linux systems don't include the original vi, but instead include an improved version of it, known
as vim, for vi improved. This fact may be hidden by most Linux distributions. On some distributions, the vi file
will link to vim:

sysadmin@localhost:~$ which vi
/usr/bin/vi
sysadmin@localhost:/etc/alternatives$ ls -l vi
lrwxrwxrwx 1 root root 17 Mar 2 2016 vi -> /usr/bin/vim.tiny

⁠ While on other distributions, an alias exists that will execute vim when the vi command is run:

[sysadmin@localhost ~]$ which vi


alias vi='vim'
/usr/bin/vim
⁠ 

For the most part, vim works just like vi but has additional features, including the ability to use the arrow ←↓↑→
keys for navigation.

For the topics that will be covered in this course, either vi or vim will work. For simple editing tasks, nano is
available on many systems. Users who don’t have all the keyboard commands memorized that are needed for vi
will appreciate its menu at the bottom of the editing screen and straightforward command structure.

On the other end of the spectrum is the emacs editor, an “extensible, customizable, self-documenting real-time
display editor.” For programmers and others that need sophisticated editing tools in a command line environment,
this piece of GNU software provides maximum capability and flexibility. Emacs goes far beyond just text editing
with a built-in Lisp programming interpreter and content-aware editing modes that allow syntax coloring for
different file types. It includes a packaging system for downloading and installing custom user extensions to
expand its capabilities, which include project planning, mail and news readers, debuggers, calendars, and many
other productivity tools. Emacs also has a built-in documentation system with tutorials, and full Unicode support
for almost every character set and script imaginable, so practically anyone can use it in their native language.
Essentially, it’s a power tool for power users that can perform as an infinitely customizable user interface for those
that wish to control every aspect of their systems.

This chapter will mainly focus on how to use vi and how to configure the default editor in the shell. To get started
using the vi editor, simply type the command, followed by the path name of the file to edit or create:

sysadmin@localhost:~$ vi newfile

9.2 Command Mode Movement


There are three modes used in the vi editor: command mode, insert mode, and ex mode.

Initially, the program starts in command mode. Command mode is used to type commands, such as those used to
move around a document, manipulate text, and access the other two modes. To return to command mode at any
time, press the Esc key.

Once some text has been added into a document, to perform actions like moving the cursor, the Esc key needs to
be pressed first to return to command mode. This seems like a lot of work, but remember that vi works in a
terminal environment where a mouse is useless.

Movement commands in vi have two aspects: a motion and an optional number prefix, which indicates how many
times to repeat that motion. The general format is as follows:

[count] motion

The following table summarizes the motion keys available:

⁠ 
Motion Result
h Left one character
j Down one line
k Up one line
l Right one character
w One word forward
b One word back
^ Beginning of the line
$ End of the line

Note

Since the upgrade to vim, it is also possible to use the arrow ←↓↑→ keys instead of hjkl respectively.
These motions can be prefixed with a number to indicate how many times to perform the movement. For example,
the 5h command would move the cursor five characters to the left and 3w would move the cursor three words to the
right.

To move the cursor to a specific line number, type that line number followed by the G character. For example, to
get to the fifth line of the file, type the 5G command. The 1G or gg commands can be used to go to the first line of
the file, while a single G will take you to the last line. To find out which line the cursor is currently on, use Ctrl+G.

9.3 Command Mode Actions


The standard convention for editing content with word processors is to use copy, cut, and paste. The vi program
does not use these; instead, it uses the following three commands:

⁠ 

Standard Vi Meaning

cut d delete

copy y yank

paste P | p put

The motions learned from the previous page are used to specify where the action is to take place, always beginning
with the present cursor location. Either of the following general formats for action commands is acceptable:

action [count] motion


[count] action motion

Delete

Delete removes the indicated text from the page and saves it into the buffer, the buffer being the equivalent of the
"clipboard" used in Windows or Mac OSX. The following table provides some common usage examples:

Action Result

dd Delete the current line

3dd Delete the next three lines

dw Delete the current word

d3w Delete the next three words

d4h Delete four characters to the left


Change

Change is very similar to delete, where the text is removed and saved into the buffer. However, when using
change, the program is switched to insert mode to allow immediate changes to the text. The following table
provides some common usage examples:

Action Result

cc Change the current line

cw Change the current word

c3w Change the next three words

c5h Change five characters to the left

Yank

Yank places content into the buffer without deleting it. The following table provides some common usage
examples:

Action Result

yy Yank the current line

3yy Yank the next three lines

yw Yank the current word

y$ Yank to the end of the line

Put

Put places the text saved in the buffer either before or after the cursor position. Notice that these are the only two
options as put does not use the motions like the previous action commands.

Action Result

p Put (paste) after the cursor

P Put before cursor

Searching in vi

Another standard function that word processors offer is the find function. Often, people use Ctrl+F or look under
the edit menu. The vi program uses search. Search is more powerful than find because it supports both literal text
patterns and regular expressions.
To search forward from the current position of the cursor, use the slash / character to start the search, type a search
term, and then press the Enter key to begin the search. The cursor will move to the first match that is found.

To proceed to the next match using the same pattern, press the N key. To go back to a previous match, press the
Shift+N key combination. If the end or the beginning of the document is reached, it will automatically wrap around
to the other side of the document.

To start searching backward from the cursor position, start by typing ?, then type the pattern to search for matches
and press the Enter key.

Action Result

/term Search forwards for term

?term Search backward for term


9.4 Insert Mode
Insert mode is used to add text to the document. There a few ways to enter insert mode from command mode, each
differing by where the text insertion will begin. The following table covers the most common. After using one of
these commands, you may enter text. To return to command mode, use the Esc key.

Input Purpose
a Enter insert mode right after the cursor
A Enter insert mode at the end of the line
i Enter insert mode right before the cursor
I Enter insert mode at the beginning of the line
o Enter insert mode on a blank line after the cursor
O Enter insert mode on a blank line before the cursor

9.5 Ex Mode
Originally, the vi editor was called the ex editor. The name vi was the abbreviation of the visual command inside
the ex editor that switched the editor to "visual" mode.

In the original normal mode, the ex editor only allowed users to see and modify one line at a time. In the visual
mode, users could see as much of the document that will fit on the screen. Since most users preferred the visual
mode to the line editing mode, the ex program file was linked to a vi file, so that users could start ex directly in
visual mode when they ran the vi link.

Eventually, the actual program file was renamed vi, and the ex editor became a link that pointed to the vi editor.

When the ex mode of the vi editor is being used, it is possible to view or change settings, as well as carry out file-
related commands like opening, saving, or aborting changes to a file. In order to get to the ex mode, type a colon :
character in command mode. The following table lists some common actions performed in ex mode:

Input Purpose
:w Write the current file to the filesystem
:w filename Save a copy of the current file as filename
:w! Force writing to the current file
:1 Go to line number 1 or whatever number is given
:e filename Open filename
:q Quit if no changes made to file
:q! Quit without saving changes to file

A quick analysis of the table above reveals if an exclamation mark ! character is added to a command, then the
command attempts to force the operation. For example, imagine you make changes to a file in the vi editor and
then try to quit with the :q command, only to discover that the "quit" command fails. The vi editor doesn't want to
quit without saving the changes you made to a file, but you can force it to quit with the :q! command.
Note

While it may seem impossible, the vi editor can save changes to a read-only file. The command :w! will try to
write to a file, even if it is read-only, by attempting to change the permissions on the file, perform the write to the
file, and then change the permissions back to what they were originally.

This means that the root user can make changes to almost any file in the vi editor, regardless of the permissions on
the file. However, ordinary users will only be able to force writing to the files that they own. Using vi doesn't
change the fact that regular users can't modify the permissions on files that they do not own.

Permissions will be covered in greater detail later in the course.

Although the ex mode offers several ways to save and quit, there's also the ZZ command that is available in
command mode; this is the equivalent of :wq. There are many more overlapping functions between ex mode and
command mode. For example, ex mode can be used to navigate to any line in the document by typing the colon :
character followed by the line number, while the G command can be used in command mode as previously
demonstrated.

9.6 Configuring the Standard Editor


There are a number of ways to configure and invoke the standard editor, which is the default text editor on the
command-line for the Linux distribution being used. This section will explain two methods to configure the
standard editor.

Note

We encourage you to use the terminal as often as possible while reading the chapter content. However, there are
places where the output will differ, or you will not be able to reproduce the examples altogether. The examples in
this section were designed to introduce a concept, whereas the labs that follow the chapters were designed to take
you through the material step-by-step, working with the CLI to give you practical experience.

Typing the /usr/bin/editor command will invoke the standard editor, which in the case of our Ubuntu virtual
machine, is VIM.

sysadmin@localhost:~$ /usr/bin/editor

The command above will bring up the default editor window:

~
~
~ VIM - Vi IMproved
~
~ version 8.0.1453
~ by Bram Moolenaar et al.
~ Modified by pkg-vim-maintainers@lists.alioth.debian.org
~ Vim is open source and freely distributable
~
~ Help poor children in Uganda!
~ type :help iccf<Enter> for information
~
~ type :q<Enter> to exit
~ type :help<Enter> or <F1> for on-line help
~ type :help version8<Enter> for version info
~

To exit the window, type the :q command.

There are a number of ways to change the standard editor, but the easiest one on Ubuntu 18.04 is to use the
update-alternatives command with the --config editor option. Note that this command requires
administrative access. After executing the command, type the selection number of the editor:

Note

The sudo command allows a user to execute a command as another user without creating a new shell. To execute a
command with administrative privileges, use it as an argument to the sudo command. The sudo command assumes
by default the root user account should be used to execute commands.

Using sudo in our virtual machine environment requires the root password netlab123. As a security measure, the
password will not be visible as it is typed.

sysadmin@localhost:~$ sudo update-alternatives --config editor


[sudo] password for sysadmin:
There are 3 choices for the alternative editor (providing /usr/bin/editor).

Selection Path Priority Status


------------------------------------------------------------
0 /bin/nano 40 auto mode
1 /bin/nano 40 manual mode
2 /usr/bin/mcedit 25 manual mode
* 3 /usr/bin/vim.tiny 15 manual mode

Press <enter> to keep the current choice[*], or type selection number: 0


update-alternatives: using /bin/nano to provide /usr/bin/editor (editor) in auto mode

Now the /usr/bin/editor command will invoke the nano editor as the standard editor instead of the vi editor:

GNU nano 2.9.3 New Buffer

^G Get Help ^O Write Out ^W Where Is ^K Cut Text ^J Justify ^C Cur Pos
^X Exit ^R Read File ^\ Replace ^U Uncut Text^T To Spell ^_ Go To Line

To exit nano, type Ctrl+X.

Another way of changing the standard editor is by editing the .bashrc file. Since the .bashrc file only loads when
a new shell is created, it still shows vi as the standard editor; we can confirm this by viewing the $EDITOR variable:

sysadmin@localhost:~$ echo $EDITOR


vi

To edit the .bashrc file using nano , you would type the following command:

sysadmin@localhost:~$ nano .bashrc


The following example shows the environment variables for the standard editor at the bottom of the .bashrc file.
To change the standard editor to nano, you would simply change the variables by replacing their current value of
vi and setting them to nano:

GNU nano 2.9.3 .bashrc Modified

# set editor and visual envs to vim


EDITOR=vi
VISUAL=vi

# change to home dir


cd ~

^G Get Help ^O Write Out ^W Where Is ^K Cut Text ^J Justify ^C Cur Pos
^X Exit ^R Read File ^\ Replace ^U Uncut Text^T To Spell ^_ Go To Line

In order to see these changes, a new shell will need to be opened using the bash command in order to reload the
.bashrc file. In the new shell, displaying the $EDITOR variable can be used to confirm the changes:

sysadmin@localhost:~$ echo $EDITOR


nano

Of course, the vi editor will still be available at the command line. To continue to using vi after changing the
standard editor, simply type the vi command followed by the path and name of the file to edit or the file you wish
to create:

sysadmin@localhost:~$ vi newfile
Key Terms
/, ?
This is used to search for text while in command mode. the / is used to start searching. Enter a key term and
press enter to begin searching the file for the text entered. If the user would like to search backwards in the
document, a ? can be used instead of the /.
Section 9.3
EDITOR

Section 9.6
ZZ, :w!, :q!
These keys are used to exit the vi editor from command mode. ZZ is used to save and quit the file. It must
be done for each file. :w! will force the writing of the current file. :q! will exit the editor without saving
changes to the current file.
Section 9.5
d, p, y, dd, yy
These are used to copy, replace and paste text when in command mode. d is used to cut one alphabetic
word, where as dd is used to cut an entire line of text. y is used to copy one one alphabetic word, where as
yy is used to copy and entire line at a time. If a number precedes either dd or yy, this will copy that number
of lines. For example if 3dd is typed this will cut 3 lines at a time.
Section 9.3
h,j,k,l
These keys are used for basic cursor movement in vi when in command mode. h moves left one character, j
moves down one line, k moves up one line, and l moves right one character.
Section 9.2
i, o, a
i, o, and a are used to enter insert mode from command mode. i will allow a user to start inserting text at the
current location of the cursor. o will allow a user to start inserting text a line below the current location of
the cursor, and a will allow a user to insert text one postion after the current location of the cursor.
Section 9.4
vi
A screen-oriented text editor originally created for Unix operating systems. vi is also known as a modal
editor in which the user must switch modes to create, edit, and search text in a file.
Section 9.1 | Section 9.2 | Section 9.3 | Section 9.4 | Section 9.5
LAB 09
9.0 Introduction
The vi editor is available on every Linux distribution in the world and can execute both in a CLI as well as a GUI
interface. Most Linux systems have an alias for vi that executes the vim command, an improved version of the
original vi editor. The commands provided in this lab work both in vi and vim.

The vi editor works in three modes: command mode, insert mode, and ex mode. The command mode is used to
type commands to navigate a document, the insert mode is used to enter new text into a document, and the ex mode
is used for file operations such as saving and quitting.

While example terminal boxes are useful for most of the labs in this course, because of the nature of vi (most
commands when typed are not visible on the screen), example terminal boxes will not be useful in all steps of this
lab. As a result, some of the steps in this lab do not include example terminal boxes.

9.1 Step 1
To create a new file called edit.txt using vi, execute the following command:

vi edit.txt
sysadmin@localhost:~$ vi edit.txt

The vi editor will open as shown below:

~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
"edit.txt" [New File]
9.2 Step 2
To exit the vi editor, type in the following:

:q!
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
:q!

9.3 Step 3
To make this lab more effective, you will create a file with the output of the ls command. This provides you with a
file that already contains data (rather than having you create a file from scratch). Execute the following command
to generate a file that you can work with:

ls -lR /usr > data.txt


sysadmin@localhost:~$ ls -lR /usr > data.txt

9.4 Step 4
To open the file data.txt for editing, execute the following command:

vi data.txt

The vi editor will open the file, data.txt, for editing as shown below:

/usr:
total 32
drwxr-xr-x 1 root root 4096 Apr 3 22:24 bin
drwxr-xr-x 2 root root 4096 Apr 24 2018 games
drwxr-xr-x 1 root root 4096 Mar 22 17:41 include
drwxr-xr-x 1 root root 4096 Mar 29 17:36 lib
drwxr-xr-x 1 root root 4096 Mar 7 21:00 local
drwxr-xr-x 1 root root 4096 Mar 29 17:36 sbin
drwxr-xr-x 1 root root 4096 Mar 29 17:36 share
drwxr-xr-x 2 root root 4096 Apr 24 2018 src

/usr/bin:
total 42800
-rwxr-xr-x 1 root root 51384 Jan 18 2018 [
-rwxr-xr-x 1 root root 22696 Sep 27 2018 aa-enabled
-rwxr-xr-x 1 root root 22696 Sep 27 2018 aa-exec
-rwxr-xr-x 1 root root 22608 Oct 15 20:29 addpart
lrwxrwxrwx 1 root root 6 Aug 4 2018 apropos -> whatis
-rwxr-xr-x 1 root root 14424 Mar 11 09:34 apt
-rwxr-xr-x 1 root root 80032 Mar 11 09:34 apt-cache
-rwxr-xr-x 1 root root 22688 Mar 11 09:34 apt-cdrom
-rwxr-xr-x 1 root root 22616 Mar 11 09:34 apt-config
-rwxr-xr-x 1 root root 22688 Mar 11 09:34 apt-extracttemplates
"data.txt" 27916 lines, 1324425 characters

9.5 Step 5
To switch to the insert mode and enter data on the first line where the cursor is positioned, type i. Then, type
Start inserting now:

i
Start inserting now
Start inserting now/usr:
total 32
drwxr-xr-x 1 root root 4096 Apr 3 22:24 bin
drwxr-xr-x 2 root root 4096 Apr 24 2018 games
drwxr-xr-x 1 root root 4096 Mar 22 17:41 include
drwxr-xr-x 1 root root 4096 Mar 29 17:36 lib
drwxr-xr-x 1 root root 4096 Mar 7 21:00 local
drwxr-xr-x 1 root root 4096 Mar 29 17:36 sbin
drwxr-xr-x 1 root root 4096 Mar 29 17:36 share
drwxr-xr-x 2 root root 4096 Apr 24 2018 src

/usr/bin:
total 42800
-rwxr-xr-x 1 root root 51384 Jan 18 2018 [
-rwxr-xr-x 1 root root 22696 Sep 27 2018 aa-enabled
-rwxr-xr-x 1 root root 22696 Sep 27 2018 aa-exec
-rwxr-xr-x 1 root root 22608 Oct 15 20:29 addpart
lrwxrwxrwx 1 root root 6 Aug 4 2018 apropos -> whatis
-rwxr-xr-x 1 root root 14424 Mar 11 09:34 apt
-rwxr-xr-x 1 root root 80032 Mar 11 09:34 apt-cache
-rwxr-xr-x 1 root root 22688 Mar 11 09:34 apt-cdrom
-rwxr-xr-x 1 root root 22616 Mar 11 09:34 apt-config
-rwxr-xr-x 1 root root 22688 Mar 11 09:34 apt-extracttemplates
"data.txt" 27916 lines, 1324425 characters

9.6 Step 6
Press the Escape key to return to the command mode, then press the Down Arrow ↓ key six times to move down
six lines. Press i to insert text at the beginning of the line and type Inserting on line 7:

ESC
Down Arrow 6x
I
Inserting on line 7
Start inserting now/usr:
total 32
drwxr-xr-x 1 root root 4096 Apr 3 22:24 bin
drwxr-xr-x 2 root root 4096 Apr 24 2018 games
drwxr-xr-x 1 root root 4096 Mar 22 17:41 include
drwxr-xr-x 1 root root 4096 Mar 29 17:36 lib
Inserting on line 7drwxr-xr-x 1 root root 4096 Mar 7 21:00 local
drwxr-xr-x 1 root root 4096 Mar 29 17:36 sbin
drwxr-xr-x 1 root root 4096 Mar 29 17:36 share
drwxr-xr-x 2 root root 4096 Apr 24 2018 src

/usr/bin:
total 42800
-rwxr-xr-x 1 root root 51384 Jan 18 2018 [
-rwxr-xr-x 1 root root 22696 Sep 27 2018 aa-enabled
-rwxr-xr-x 1 root root 22696 Sep 27 2018 aa-exec
-rwxr-xr-x 1 root root 22608 Oct 15 20:29 addpart
lrwxrwxrwx 1 root root 6 Aug 4 2018 apropos -> whatis
-rwxr-xr-x 1 root root 14424 Mar 11 09:34 apt
-rwxr-xr-x 1 root root 80032 Mar 11 09:34 apt-cache
-rwxr-xr-x 1 root root 22688 Mar 11 09:34 apt-cdrom
-rwxr-xr-x 1 root root 22616 Mar 11 09:34 apt-config
-rwxr-xr-x 1 root root 22688 Mar 11 09:34 apt-extracttemplates
"data.txt" 27916 lines, 1324425 characters

9.7 Step 7
Press the Escape key to return to the command mode. Type dd to delete the current line:

ESC
dd

9.8 Step 8
Move to the end of the document by typing a G character:

G
-rw-r--r-- 1 root root 3105 Jan 28 2018 _busctl
-rw-r--r-- 1 root root 2270 Jan 28 2018 _hostnamectl
-rw-r--r-- 1 root root 5975 Jan 28 2018 _journalctl
-rw-r--r-- 1 root root 651 Jan 28 2018 _kernel-install
-rw-r--r-- 1 root root 3585 Jan 28 2018 _localectl
-rw-r--r-- 1 root root 5804 Jan 28 2018 _loginctl
-rw-r--r-- 1 root root 1243 Jan 28 2018 _networkctl
-rw-r--r-- 1 root root 116 Jan 28 2018 _sd_hosts_or_user_at_host
-rw-r--r-- 1 root root 279 Jan 28 2018 _sd_outputmodes
-rw-r--r-- 1 root root 255 Jan 28 2018 _sd_unit_files
-rw-r--r-- 1 root root 15069 Feb 28 21:03 _systemctl
-rw-r--r-- 1 root root 3839 Jan 28 2018 _systemd
-rw-r--r-- 1 root root 2912 Jan 28 2018 _systemd-analyze
-rw-r--r-- 1 root root 564 Jan 28 2018 _systemd-delta
-rw-r--r-- 1 root root 1061 Jan 28 2018 _systemd-inhibit
-rw-r--r-- 1 root root 2378 Jan 28 2018 _systemd-resolve
-rw-r--r-- 1 root root 3136 Jan 28 2018 _systemd-run
-rw-r--r-- 1 root root 736 Jan 28 2018 _systemd-tmpfiles
-rw-r--r-- 1 root root 2042 Jan 28 2018 _timedatectl
-rw-r--r-- 1 root root 5997 Jan 28 2018 _udevadm
/usr/src:
total 0

9.9 Step 9
To add a new line at the end of the document, type an o character and then type the end. Press the Escape key to
return to the command mode:

o
the end
ESC
-rw-r--r-- 1 root root 2270 Jan 28 2018 _hostnamectl
-rw-r--r-- 1 root root 5975 Jan 28 2018 _journalctl
-rw-r--r-- 1 root root 651 Jan 28 2018 _kernel-install
-rw-r--r-- 1 root root 3585 Jan 28 2018 _localectl
-rw-r--r-- 1 root root 5804 Jan 28 2018 _loginctl
-rw-r--r-- 1 root root 1243 Jan 28 2018 _networkctl
-rw-r--r-- 1 root root 116 Jan 28 2018 _sd_hosts_or_user_at_host
-rw-r--r-- 1 root root 279 Jan 28 2018 _sd_outputmodes
-rw-r--r-- 1 root root 255 Jan 28 2018 _sd_unit_files
-rw-r--r-- 1 root root 15069 Feb 28 21:03 _systemctl
-rw-r--r-- 1 root root 3839 Jan 28 2018 _systemd
-rw-r--r-- 1 root root 2912 Jan 28 2018 _systemd-analyze
-rw-r--r-- 1 root root 564 Jan 28 2018 _systemd-delta
-rw-r--r-- 1 root root 1061 Jan 28 2018 _systemd-inhibit
-rw-r--r-- 1 root root 2378 Jan 28 2018 _systemd-resolve
-rw-r--r-- 1 root root 3136 Jan 28 2018 _systemd-run
-rw-r--r-- 1 root root 736 Jan 28 2018 _systemd-tmpfiles
-rw-r--r-- 1 root root 2042 Jan 28 2018 _timedatectl
-rw-r--r-- 1 root root 5997 Jan 28 2018 _udevadm

/usr/src:
total 0
the end

9.10 Step 10
Go to line #1 by typing 1G. Search for local by typing /local and press Enter. Type the letter n to move to the
second occurrence of local:

1G
/local
Enter
n
-rwxr-xr-x 1 root root 92744 Aug 4 2018 lexgrog
-rwxr-xr-x 1 root root 15775 Nov 19 15:54 libnetcfg
-rwxr-xr-x 1 root root 30904 Jan 18 2018 link
-rwxr-xr-x 1 root root 4090 Jun 21 2016 linux-check-removal
-rwxr-xr-x 1 root root 6320 Jun 5 2016 linux-update-symlinks
-rwxr-xr-x 1 root root 2696 Sep 17 2016 linux-version
lrwxrwxrwx 1 root root 7 Oct 15 2018 linux32 -> setarch
lrwxrwxrwx 1 root root 7 Oct 15 2018 linux64 -> setarch
-rwxr-xr-x 1 root root 22888 Feb 26 2018 lnstat
lrwxrwxrwx 1 root root 13 Mar 22 17:41 loadkeys -> /bin/loadkeys
-rwxr-xr-x 1 root root 26760 Jan 22 2018 loadunimap
-rwxr-xr-x 1 root root 50592 Apr 16 2018 locale
-rwxr-xr-x 1 root root 10240 Feb 5 07:32 locale-check
-rwxr-xr-x 1 root root 22600 Feb 28 21:03 localectl
-rwxr-xr-x 1 root root 338744 Apr 16 2018 localedef
lrwxrwxrwx 1 root root 24 Mar 22 17:41 locate -> /etc/alternatives/locate
-rwxr-xr-x 1 root root 47792 Oct 15 2018 logger
-rwxr-xr-x 1 root root 30904 Jan 18 2018 logname
-rwxr-xr-x 1 root root 10472 Jan 17 2018 look
-rwxr-xr-x 1 root root 2885 Jan 17 2018 lorder
-rwxr-xr-x 1 root root 10240 Jan 24 23:11 lsattr
-rwxr-xr-x 1 root root 3638 Aug 7 2017 lsb_release
/local

9.11 Step 11
Delete the current word by typing dw:

dw
-rwxr-xr-x 1 root root 92744 Aug 4 2018 lexgrog
-rwxr-xr-x 1 root root 15775 Nov 19 15:54 libnetcfg
-rwxr-xr-x 1 root root 30904 Jan 18 2018 link
-rwxr-xr-x 1 root root 4090 Jun 21 2016 linux-check-removal
-rwxr-xr-x 1 root root 6320 Jun 5 2016 linux-update-symlinks
-rwxr-xr-x 1 root root 2696 Sep 17 2016 linux-version
lrwxrwxrwx 1 root root 7 Oct 15 2018 linux32 -> setarch
lrwxrwxrwx 1 root root 7 Oct 15 2018 linux64 -> setarch
-rwxr-xr-x 1 root root 22888 Feb 26 2018 lnstat
lrwxrwxrwx 1 root root 13 Mar 22 17:41 loadkeys -> /bin/loadkeys
-rwxr-xr-x 1 root root 26760 Jan 22 2018 loadunimap
-rwxr-xr-x 1 root root 50592 Apr 16 2018 locale
-rwxr-xr-x 1 root root 10240 Feb 5 07:32 -check
-rwxr-xr-x 1 root root 22600 Feb 28 21:03 localectl
-rwxr-xr-x 1 root root 338744 Apr 16 2018 localedef
lrwxrwxrwx 1 root root 24 Mar 22 17:41 locate -> /etc/alternatives/locate
-rwxr-xr-x 1 root root 47792 Oct 15 2018 logger
-rwxr-xr-x 1 root root 30904 Jan 18 2018 logname
-rwxr-xr-x 1 root root 10472 Jan 17 2018 look
-rwxr-xr-x 1 root root 2885 Jan 17 2018 lorder
-rwxr-xr-x 1 root root 10240 Jan 24 23:11 lsattr
-rwxr-xr-x 1 root root 3638 Aug 7 2017 lsb_release
/local

9.12 Step 12
Type 1G to return to the first line and then 5dd to delete five lines:

1G
5dd
drwxr-xr-x 1 root root 4096 Apr 17 20:09 lib
drwxr-xr-x 1 root root 4096 Apr 17 20:09 sbin
drwxr-xr-x 1 root root 4096 Apr 17 20:09 share
drwxr-xr-x 2 root root 4096 Apr 24 2018 src

/usr/bin:
total 57052
-rwxr-xr-x 1 root root 51384 Jan 18 2018 [
-rwxr-xr-x 1 root root 22696 Sep 27 2018 aa-enabled
-rwxr-xr-x 1 root root 22696 Sep 27 2018 aa-exec
-rwxr-xr-x 1 root root 22608 Oct 15 2018 addpart
lrwxrwxrwx 1 root root 26 Sep 12 2018 addr2line -> x86_64-linux-gnu-add
r2line
lrwxrwxrwx 1 root root 6 Aug 4 2018 apropos -> whatis
-rwxr-xr-x 1 root root 14424 Mar 11 09:34 apt
-rwxr-xr-x 1 root root 80032 Mar 11 09:34 apt-cache
-rwxr-xr-x 1 root root 22688 Mar 11 09:34 apt-cdrom
-rwxr-xr-x 1 root root 22616 Mar 11 09:34 apt-config
-rwxr-xr-x 1 root root 22688 Mar 11 09:34 apt-extracttemplates
-rwxr-xr-x 1 root root 247968 Mar 11 09:34 apt-ftparchive
-rwxr-xr-x 1 root root 43168 Mar 11 09:34 apt-get
-rwxr-xr-x 1 root root 27391 Mar 11 09:34 apt-key
-rwxr-xr-x 1 root root 43168 Mar 11 09:34 apt-mark
5 fewer lines

9.13 Step 13
Copy three lines by typing 3yy:

3yy
drwxr-xr-x 1 root root 4096 Apr 17 20:09 lib
drwxr-xr-x 1 root root 4096 Apr 17 20:09 sbin
drwxr-xr-x 1 root root 4096 Apr 17 20:09 share
drwxr-xr-x 2 root root 4096 Apr 24 2018 src

/usr/bin:
total 57052
-rwxr-xr-x 1 root root 51384 Jan 18 2018 [
-rwxr-xr-x 1 root root 22696 Sep 27 2018 aa-enabled
-rwxr-xr-x 1 root root 22696 Sep 27 2018 aa-exec
-rwxr-xr-x 1 root root 22608 Oct 15 2018 addpart
lrwxrwxrwx 1 root root 26 Sep 12 2018 addr2line -> x86_64-linux-gnu-add
r2line
lrwxrwxrwx 1 root root 6 Aug 4 2018 apropos -> whatis
-rwxr-xr-x 1 root root 14424 Mar 11 09:34 apt
-rwxr-xr-x 1 root root 80032 Mar 11 09:34 apt-cache
-rwxr-xr-x 1 root root 22688 Mar 11 09:34 apt-cdrom
-rwxr-xr-x 1 root root 22616 Mar 11 09:34 apt-config
-rwxr-xr-x 1 root root 22688 Mar 11 09:34 apt-extracttemplates
-rwxr-xr-x 1 root root 247968 Mar 11 09:34 apt-ftparchive
-rwxr-xr-x 1 root root 43168 Mar 11 09:34 apt-get
-rwxr-xr-x 1 root root 27391 Mar 11 09:34 apt-key
-rwxr-xr-x 1 root root 43168 Mar 11 09:34 apt-mark
3 lines yanked

Then, move to the end of the document by typing G. Paste the three lines by typing p:

G
p
-rw-r--r-- 1 root root 3585 Jan 28 2018 _localectl
-rw-r--r-- 1 root root 5804 Jan 28 2018 _loginctl
-rw-r--r-- 1 root root 1243 Jan 28 2018 _networkctl
-rw-r--r-- 1 root root 116 Jan 28 2018 _sd_hosts_or_user_at_host
-rw-r--r-- 1 root root 279 Jan 28 2018 _sd_outputmodes
-rw-r--r-- 1 root root 255 Jan 28 2018 _sd_unit_files
-rw-r--r-- 1 root root 15069 Feb 28 21:03 _systemctl
-rw-r--r-- 1 root root 3839 Jan 28 2018 _systemd
-rw-r--r-- 1 root root 2912 Jan 28 2018 _systemd-analyze
-rw-r--r-- 1 root root 564 Jan 28 2018 _systemd-delta
-rw-r--r-- 1 root root 1061 Jan 28 2018 _systemd-inhibit
-rw-r--r-- 1 root root 2378 Jan 28 2018 _systemd-resolve
-rw-r--r-- 1 root root 3136 Jan 28 2018 _systemd-run
-rw-r--r-- 1 root root 736 Jan 28 2018 _systemd-tmpfiles
-rw-r--r-- 1 root root 2042 Jan 28 2018 _timedatectl
-rw-r--r-- 1 root root 5997 Jan 28 2018 _udevadm

/usr/src:
total 0
the end
drwxr-xr-x 1 root root 4096 Apr 17 20:09 lib
3 more lines

9.14 Step 14
Undo the paste command by typing the letter u:

u
-rw-r--r-- 1 root root 3585 Jan 28 2018 _localectl
-rw-r--r-- 1 root root 5804 Jan 28 2018 _loginctl
-rw-r--r-- 1 root root 1243 Jan 28 2018 _networkctl
-rw-r--r-- 1 root root 116 Jan 28 2018 _sd_hosts_or_user_at_host
-rw-r--r-- 1 root root 279 Jan 28 2018 _sd_outputmodes
-rw-r--r-- 1 root root 255 Jan 28 2018 _sd_unit_files
-rw-r--r-- 1 root root 15069 Feb 28 21:03 _systemctl
-rw-r--r-- 1 root root 3839 Jan 28 2018 _systemd
-rw-r--r-- 1 root root 2912 Jan 28 2018 _systemd-analyze
-rw-r--r-- 1 root root 564 Jan 28 2018 _systemd-delta
-rw-r--r-- 1 root root 1061 Jan 28 2018 _systemd-inhibit
-rw-r--r-- 1 root root 2378 Jan 28 2018 _systemd-resolve
-rw-r--r-- 1 root root 3136 Jan 28 2018 _systemd-run
-rw-r--r-- 1 root root 736 Jan 28 2018 _systemd-tmpfiles
-rw-r--r-- 1 root root 2042 Jan 28 2018 _timedatectl
-rw-r--r-- 1 root root 5997 Jan 28 2018 _udevadm

/usr/src:
total 0
the end
~
3 fewer lines; before #7 26 seconds ago

9.15 Step 15
Type :q and then press the Enter key to attempt to quit the document:

:q
Enter
-rw-r--r-- 1 root root 5975 Jan 28 2018 _journalctl
-rw-r--r-- 1 root root 651 Jan 28 2018 _kernel-install
-rw-r--r-- 1 root root 3585 Jan 28 2018 _localectl
-rw-r--r-- 1 root root 5804 Jan 28 2018 _loginctl
-rw-r--r-- 1 root root 1243 Jan 28 2018 _networkctl
-rw-r--r-- 1 root root 116 Jan 28 2018 _sd_hosts_or_user_at_host
-rw-r--r-- 1 root root 279 Jan 28 2018 _sd_outputmodes
-rw-r--r-- 1 root root 255 Jan 28 2018 _sd_unit_files
-rw-r--r-- 1 root root 15069 Feb 28 21:03 _systemctl
-rw-r--r-- 1 root root 3839 Jan 28 2018 _systemd
-rw-r--r-- 1 root root 2912 Jan 28 2018 _systemd-analyze
-rw-r--r-- 1 root root 564 Jan 28 2018 _systemd-delta
-rw-r--r-- 1 root root 1061 Jan 28 2018 _systemd-inhibit
-rw-r--r-- 1 root root 2378 Jan 28 2018 _systemd-resolve
-rw-r--r-- 1 root root 3136 Jan 28 2018 _systemd-run
-rw-r--r-- 1 root root 736 Jan 28 2018 _systemd-tmpfiles
-rw-r--r-- 1 root root 2042 Jan 28 2018 _timedatectl
-rw-r--r-- 1 root root 5997 Jan 28 2018 _udevadm

/usr/src:
total 0
the end
~
E37: No write since last change (add ! to override)

9.16 Step 16
The previous command :q failed because you have not saved the changes that you made in the file. To quit without
saving, type :q! and press the Enter key to quit the document and not save any changes:

:q!
Enter
:q!
sysadmin@localhost:~$

9.17 Step 17
Open the data.txt file by executing the following command:

vi data.txt
sysadmin@localhost:~$ vi data.txt
9.18 Step 18
Type 1G to return to the first line of the file (if needed). Change (replace) the first line of the document by typing
cc and then Output:.

1G
cc
Output:
Output:
total 32
drwxr-xr-x 1 root root 4096 Apr 24 16:25 bin
drwxr-xr-x 2 root root 4096 Apr 24 2018 games
drwxr-xr-x 1 root root 4096 Apr 17 20:09 include
drwxr-xr-x 1 root root 4096 Apr 17 20:09 lib
drwxr-xr-x 1 root root 4096 Mar 7 21:00 local
drwxr-xr-x 1 root root 4096 Apr 17 20:09 sbin
drwxr-xr-x 1 root root 4096 Apr 17 20:09 share
drwxr-xr-x 2 root root 4096 Apr 24 2018 src

/usr/bin:
total 57052
-rwxr-xr-x 1 root root 51384 Jan 18 2018 [
-rwxr-xr-x 1 root root 22696 Sep 27 2018 aa-enabled
-rwxr-xr-x 1 root root 22696 Sep 27 2018 aa-exec
-rwxr-xr-x 1 root root 22608 Oct 15 2018 addpart
lrwxrwxrwx 1 root root 26 Sep 12 2018 addr2line -> x86_64-linux-gnu-add
r2line
lrwxrwxrwx 1 root root 6 Aug 4 2018 apropos -> whatis
-rwxr-xr-x 1 root root 14424 Mar 11 09:34 apt
-rwxr-xr-x 1 root root 80032 Mar 11 09:34 apt-cache
-rwxr-xr-x 1 root root 22688 Mar 11 09:34 apt-cdrom
"data.txt" 32447 lines, 1589342 characters

9.19 Step 19
Press the Escape key to return to the command mode. Then, type :w to save the changes:

ESC
:w
:w
Output:
total 32
drwxr-xr-x 1 root root 4096 Apr 24 16:25 bin
drwxr-xr-x 2 root root 4096 Apr 24 2018 games
drwxr-xr-x 1 root root 4096 Apr 17 20:09 include
drwxr-xr-x 1 root root 4096 Apr 17 20:09 lib
drwxr-xr-x 1 root root 4096 Mar 7 21:00 local
drwxr-xr-x 1 root root 4096 Apr 17 20:09 sbin
drwxr-xr-x 1 root root 4096 Apr 17 20:09 share
drwxr-xr-x 2 root root 4096 Apr 24 2018 src

/usr/bin:
total 57052
-rwxr-xr-x 1 root root 51384 Jan 18 2018 [
-rwxr-xr-x 1 root root 22696 Sep 27 2018 aa-enabled
-rwxr-xr-x 1 root root 22696 Sep 27 2018 aa-exec
-rwxr-xr-x 1 root root 22608 Oct 15 2018 addpart
lrwxrwxrwx 1 root root 26 Sep 12 2018 addr2line -> x86_64-linux-gnu-add
r2line
lrwxrwxrwx 1 root root 6 Aug 4 2018 apropos -> whatis
-rwxr-xr-x 1 root root 14424 Mar 11 09:34 apt
-rwxr-xr-x 1 root root 80032 Mar 11 09:34 apt-cache
-rwxr-xr-x 1 root root 22688 Mar 11 09:34 apt-cdrom
"data.txt" 32447 lines, 1589344 characters written

9.20 Step 20
Type :q to quit the vi editor:

:q
Output Omitted...
:q

You can verify that your updates were written to the file by entering the following command, which will display
the first 10 lines of the file.

head data.txt
sysadmin@localhost:~$ head data.txt
Output:
total 32
drwxr-xr-x 1 root root 4096 Apr 3 22:24 bin
drwxr-xr-x 2 root root 4096 Apr 24 2018 games
drwxr-xr-x 1 root root 4096 Mar 22 17:41 include
drwxr-xr-x 1 root root 4096 Mar 29 17:36 lib
drwxr-xr-x 1 root root 4096 Mar 7 21:00 local
drwxr-xr-x 1 root root 4096 Mar 29 17:36 sbin
drwxr-xr-x 1 root root 4096 Mar 29 17:36 share
drwxr-xr-x 2 root root 4096 Apr 24 2018 src

9.21 Step 21
The standard editor is the program that the system calls by default for editing text files. It’s possible to change the
standard editor by customizing the system you are logged into. Regular users can change this default for their own
login but changing it for all users requires root privileges. First, let's determine what the standard editor is on our
system by typing the following command:

echo $EDITOR
sysadmin@localhost:~$ echo $EDITOR
vi

9.22 Step 22
To use nano to view and edit the .bashrc file, use the following command:

nano .bashrc
sysadmin@localhost:~$ nano .bashrc
The .bashrc file contains the environment variables for the standard editor at the bottom of the file. Unlike vi ,
nano allows you to simply use the Arrow Keys ←↑→↓ to navigate to any place in the document. Use the Down
Arrow ↓ key to scroll to the bottom of the file:

GNU nano 2.9.3 .bashrc

elif [ -f /etc/bash_completion ]; then


. /etc/bash_completion
fi
fi

# add user bin to path


PATH="$HOME/bin:$PATH"

# set editor and visual envs to vim


EDITOR=vi
VISUAL=vi

# change to home dir


cd ~

^G Get Help ^O Write Out ^W Where Is ^K Cut Text ^J Justify ^C Cur Pos
^X Exit ^R Read File ^\ Replace ^U Uncut Text^T To Spell ^_ Go To Line
9.23 Step 23
Press the Down Arrow ↓ key (or Up Arrow ↑ key if you scrolled too far down) until you get to # set the
editor and visual envs to vim, then use the Arrow Keys ←↑→↓ to replace vi with nano:

nano .bashrc
GNU nano 2.9.3 .bashrc Modified

elif [ -f /etc/bash_completion ]; then


. /etc/bash_completion
fi
fi

# add user bin to path


PATH="$HOME/bin:$PATH"

# set editor and visual envs to vim


EDITOR=nano
VISUAL=nano

# change to home dir


cd ~

^G Get Help ^O Write Out ^W Where Is ^K Cut Text ^J Justify ^C Cur Pos
^X Exit ^R Read File ^\ Replace ^U Uncut Text^T To Spell ^_ Go To Line
9.24 Step 24
Press Ctrl+X to exit and type y to save:

Ctrl+x
y
GNU nano 2.9.3 .bashrc Modified

elif [ -f /etc/bash_completion ]; then


. /etc/bash_completion
fi
fi

# add user bin to path


PATH="$HOME/bin:$PATH"

# set editor and visual envs to vim


EDITOR=nano
VISUAL=nano

# change to home dir


cd ~

Save modified buffer? (Answering "No" will DISCARD changes.)


Yes
No ^C Cancel

Press Enter:

Enter
GNU nano 2.9.3 .bashrc Modified

elif [ -f /etc/bash_completion ]; then


. /etc/bash_completion
fi
fi

# add user bin to path


PATH="$HOME/bin:$PATH"

# set editor and visual envs to vim


EDITOR=nano
VISUAL=nano

# change to home dir


cd ~

File Name to Write: .bashrc


^G Get Help M-D DOS Format M-A Append M-B Backup File
^C Cancel M-M Mac Format M-P Prepend ^T To Files
sysadmin@localhost:~$
9.25 Step 25
Load a new shell by typing the bash command at the prompt.

bash
sysadmin@localhost:~$ bash
sysadmin@localhost:~$

Use the following command to see the change.

echo $EDITOR
sysadmin@localhost:~$ echo $EDITOR
nano

9.26 Step 26
Of course, vi is still available at the command line. To get started using vi, simply type the command followed by
the path and name of the file to edit or the file you wish to create:

vi newfile
sysadmin@localhost:~$ vi newfile
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
"newfile" [New File]
NDG Introduction to Linux I - Chapter 10: Standard Text
Streams and Redirection

10.1 Introduction
One of the key points in the UNIX philosophy was that all CLI commands should accept text as input and produce
text as output. As this concept was applied to the development of UNIX (and later Linux), commands were
developed to accept text as input, perform some kind of operation on the text and then produce text as output.
Commands that read in text as input, alter that text in some way, and then produce text as output are sometimes
known as filters.

⁠ 

In order to be able to apply filter commands and work with text streams, it is helpful to understand a few forms of
redirection that can be used with most commands: pipelines, standard output redirection, error output redirection,
and input redirection.

10.2 Standard Output


When a command executes without any errors, the output that is produced is known as standard out, also called
stdout or STDOUT. By default, this output will be sent to the terminal where the command is being executed.

It is possible to redirect standard out from a command so it will go to a file instead of the terminal. Standard output
redirection is achieved by following a command with the greater-than > character and a destination file. For
example, the ls ~ command will list the files in the home directory. To save a list of the files in the home
directory, you must direct the output into a text file. To create the /tmp/home.txt file:

sysadmin@localhost:~$ ls ~ > /tmp/home.txt

After which, the home.txt file will resemble:

sysadmin@localhost:~$ cat /tmp/home.txt


Desktop
Documents
Downloads
Music
Pictures
Public
Templates
Videos

Redirecting output using a single greater-than > character will create a new file, or overwrite the contents of an
existing file with the same name. Redirecting standard output with two greater-than >> characters will also create a
new file if it does not exist. The difference is that when using the >> characters, the output of the command will be
appended to the end of a file if it does already exist. For example, to append to the file that was created by the
previous command, execute the following:
sysadmin@localhost:~$ date >> /tmp/home.txt

Which will update the home.txt file to:

sysadmin@localhost:~$ cat /tmp/home.txt


Desktop
Documents
Downloads
Music
Pictures
Templates
Videos
Thu Oct 2 17:36:02 UTC 2020

There is a number associated with the standard output file descriptor (the > character): the number 1 (one).
However, since standard output is the most commonly redirected command output, the number can be omitted.
Technically, the commands should be executed as shown below:

sysadmin@localhost:~$ ls 1> /tmp/ls.txt


sysadmin@localhost:~$ date 1>> /tmp/ls.txt
COMMAND > FILE
COMMAND 1> FILE Create or overwrite FILE with the standard output of COMMAND
COMMAND >> FILE
COMMAND 1>> FILE Create or append to FILE with the standard

10.3 Standard Error


When a command encounters an error, it will produce output that is known as standard error, also called stderr
or STDERR. Like standard out, the standard error output is normally sent to the same terminal where the command is
currently being executed. The number associated with the standard error file descriptor is 2 (two).

If you tried to execute the ls /junk command, then the command would produce standard error messages because
the /junk directory does not exist.
sysadmin@localhost:~$ ls /junk
ls: cannot access /junk: No such file or directory

Because this output goes to standard error, the greater-than > character alone will not successfully redirect it, and
the output of the command will still be sent to the terminal:

sysadmin@localhost:~$ ls /junk > output


ls: cannot access /junk: No such file or directory

To redirect these error messages, you must use the correct file descriptor, which for standard error is the number 2.
Execute the following, and the error will be redirected into the /tmp/ls.err file:

sysadmin@localhost:~$ ls /junk 2> /tmp/ls.err

Just like standard output, the use of a single > character for redirection will either create the file if it doesn’t exist or
clobber (overwrite) an existing file's contents. To prevent clobbering an existing file when redirecting standard
error, use the double >> characters after the number 2 to append instead:

sysadmin@localhost:~$ ls /junk 2>> /tmp/ls.err

The /tmp/ls.err file now contains the redirected error messages:

sysadmin@localhost:~$ cat /tmp/ls.err


ls: cannot access '/junk': No such file or directory
ls: cannot access '/junk': No such file or directory
COMMAND 2> FILE Create or overwrite FILE with the standard error of COMMAND
COMMAND 2>> FILE Create or append to FILE with the standard error of COMMAND

Some commands will produce both stdout and stderr output:

sysadmin@localhost:~$ find /etc -name passwd


/etc/pam.d/passwd
/etc/passwd
find: '/etc/ssl/private': Permission denied

These two different outputs can be redirected into two separate files by using the following syntax:

sysadmin@localhost:~$ find /etc -name passwd > /tmp/output.txt 2> /tmp/error.txt

The cat command can be used to verify the success of the redirection above:

sysadmin@localhost:~$ cat /tmp/output.txt


/etc/pam.d/passwd
/etc/passwd
sysadmin@localhost:~$ cat /tmp/error.txt
find: '/etc/ssl/private': Permission denied

Sometimes it isn't useful to have the error messages displayed in the terminal or stored in a file. To discard these
error messages, use the /dev/null file.

The /dev/null file is like a trash can, where anything sent to it disappears from the system; it's sometimes called
the bit bucket or black hole. Any type of output can be redirected to the /dev/null file; most commonly users will
redirect standard error to this file, rather than standard output.

The syntax to use the /dev/null file is the same as it is for redirecting to a regular file:
sysadmin@localhost:~$ find /etc -name passw 2> /dev/null
/etc/pam.d/passwd
/etc/passwd

What if you wanted all output (standard error and standard out) sent to one file? There are two techniques to
redirect both standard error and standard out:

sysadmin@localhost:~$ ls > /tmp/ls.all 2>&1


sysadmin@localhost:~$ ls &> /tmp/ls.all

Both of the preceding command lines will create a file called /tmp/ls.all that contains all standard out and
standard error. The first command redirects stdout to /tmp/ls.all and the 2>&1 expression means "send stderr
wherever stdout is going". In the second example, the &> expression means "redirect all output".

A similar technique can be used to append all output to a single file:

sysadmin@localhost:~$ ls /etc/au* >> /tmp/ls.all 2>&1


sysadmin@localhost:~$ ls /etc/au* &>> /tmp/ls.all

COMMAND &> FILE


COMMAND > FILE 2>&1 Create or overwrite FILE with all output (stdout, stderr) of COMMAND
COMMAND &>> FILE
COMMAND >> FILE 2>&1

10.4 Standard Input


Standard in, also called stdin or STDIN, normally comes from the keyboard with input provided by the user who
runs the command. Although most commands are able to read input from files, there are some that expect the user
to enter it using the keyboard.

Note
One common way that text files are used as standard input for commands is by creating script files. Scripts are
plain text files which are interpreted by the shell when given the proper permissions and prefaced with #!/bin/sh
on the first line, which tells the shell to interpret the script as standard input:

GNU nano 2.9.3 examplescriptfile.sh

#!/bin/sh
echo HelloWorld

When the script file is invoked at the prompt using the ./ syntax, the shell will run all commands in the script file
and return the result to the terminal window, or wherever the output is specified to be sent to:

sysadmin@localhost:~$ ./examplescriptfile.sh
HelloWorld

One example of a command, that isn’t normally executed properly from a text file, is the cd command. When the
following script is run in the terminal, it is run as a child process, however, in order to successfully change to
another directory, the cd command must be run as a parent process. Consider the example testcd.sh script file
below, which specifies to use the cd command to change to the School directory then use the echo command to
print the string HelloWorld:

GNU nano 2.9.3 testcd.sh

#!/bin/sh
cd /home/sysadmin/Documents/School
echo HelloWorld

[ Read 3 lines ]
^G Get Help ^O Write Out ^W Where Is ^K Cut Text ^J Justify ^C Cur Pos
^X Exit ^R Read File ^\ Replace ^U Uncut Text^T To Linter ^_ Go To Line

When we try to run the testcd.sh script the following occurs:

sysadmin@localhost:~$ ./testcd.sh
HelloWorld

The script executes the echo command and prints HelloWorld, but the cd command cannot run as a parent
process, so we are still in the directory where we started.

Therefore, even though the standard input doesn’t return an error, it won’t create the desired outcome of changing
the directory to /home/sysadmin/Documents/School. However, when the standard input is typed by a user, and
the desired directory is provided as an argument to the cd command at the command line, it functions normally:

sysadmin@localhost:~$ cd /home/sysadmin/Documents/School
sysadmin@localhost:~/Documents/School$

Scripting is covered in greater detail later in the NDG Introduction to Linux 2.

In some cases, it is useful to redirect standard input, so it comes from a file instead of the keyboard. A good
example of when input redirection is desirable involves the tr command. The tr command translates characters
by reading data from standard input; translating one set of characters to another set of characters and then writing
the changed text to standard output.
For example, the following tr command would take input from a user (via the keyboard) to perform a translation
of all lowercase characters to uppercase characters. Execute the following command, type some text, and press
Enter to see the translation:

sysadmin@localhost:~$ tr 'a-z' 'A-Z'


hello
HELLO

The tr command doesn't stop reading from standard input unless it's terminated or receives an "End of
Transmission" character. This can be accomplished by typing Ctrl+D.

The tr command won't accept a file name as an argument on the command line. To perform a translation using a
file as input, utilize input redirection. To use input redirection, type the command with its options and arguments
followed by the less-than < character and a path to a file to use for input. For example:

sysadmin@localhost:~$ cat Documents/animals.txt


1 retriever
2 badger
3 bat
4 wolf
5 eagle
sysadmin@localhost:~$ tr 'a-z' 'A-Z' < Documents/animals.txt
1 RETRIEVER
2 BADGER
3 BAT
4 WOLF
5 EAGLE

The output shows the animals.txt file "translated" into all uppercase characters.

COMMAND < FILE Use FILE as standard input to COMMAND

Important

Do not attempt to use the same file for input and output redirection, as the results are probably not desirable (you
end up losing all data). Instead, capture the output and place it into another file; use a different file name as shown
below:

sysadmin@localhost:~$ tr 'a-z' 'A-Z' < Documents/animals.tx

10.5 Command Pipelines


Command pipelines are often used to make effective use of filter commands. In a command pipeline, the output of
one command is sent to another command as input. In Linux and most operating systems, the vertical bar or pipe |
character is used between two commands to represent a command pipeline.
For example, imagine that the output of the history command is very large. To send this output to the less
command, which displays one "page" of data at a time, the following command pipeline can be used:

sysadmin@localhost:~$ history | less

Note

To exit the less pager command, press the Q key.

Even better, take the output of the history command and filter the output by using the grep command. In the
following example, the text output by the history command is redirected to the grep command as input. The grep
command matches the ls strings and sends its output to standard out:

sysadmin@localhost:~$ history | grep "ls"


1 ls ~ > /tmp/home.txt
5 ls l> /tmp/ls.txt
6 ls 1> /tmp/ls.txt
7 date 1>> /tmp/ls.txt
8 ls /junk
9 ls /junk > output
10 ls /junk 2> /tmp/ls.err
11 ls /junk 2>> /tmp/ls.err
14 ls > /tmp/ls.all 2>&1
15 ls &> /tmp/ls.all
16 ls /etc/au* >> /tmp/ls.all 2>&1
17 ls /etc/au* &>> /tmp.ls.all
20 history | grep "ls"

Command pipelines become really powerful when three or more commands are combined. For example, view the
contents of the os.csv file in the Documents directory:

sysadmin@localhost:~$ cat Documents/os.csv


1970,Unix,Richie
1987,Minix,Tanenbaum
1970,Unix,Thompson
1991,Linux,Torvalds

The following command line will extract some fields from the os.csv file with the cut command, then sort these
lines with the sort command, and finally eliminate duplicate lines with the uniq command:

sysadmin@localhost:~$ cut -f1 -d',' Documents/os.csv | sort -n | uniq


1970
1987
1991

10.6 tee Command


A server administrator works like a plumber, using pipes, and the occasional tee command. The tee command
splits the output of a command into two streams: one directed to standard output, which displays in the terminal,
and the other into a file.

The tee command can be very useful to create a log of a command or a script. For instance, to record the runtime
of a process, start with the date command and make a copy of the output into the timer.txt file:
sysadmin@localhost:~$ date | tee timer.txt
Fri Nov 7 02:21:24 UTC 2020

The timer.txt file now contains a copy of the date, the same output displayed in the preceding example:

sysadmin@localhost:~$ cat timer.txt


Fri Nov 7 02:21:24 UTC 2020

Run the process that needs to be timed. The sleep command is being substituted for a timed process; it pauses for
a given number of seconds:

sysadmin@localhost:~$ sleep 15

Then run the date command again. This time, append the time to the end of the timer.txt file by using the -a
option:

sysadmin@localhost:~$ date | tee -a timer.txt


Fri Nov 7 02:28:43 UTC 2020

Both times will then be recorded in the file.

sysadmin@localhost:~$ cat timer.txt


Fri Nov 7 02:21:24 UTC 2020
Fri Nov 7 02:28:43 UTC 2020

To run all of the above commands as a single command, use a semicolon ; character as a separator:

sysadmin@localhost:~$ date | tee timer.txt; sleep 15; date | tee -a timer.txt


Fri Nov 7 02:35:47 UTC 2020
Fri Nov 7 02:36:02 UTC 2020

The command above will display and record the first output of the date command, pause for 15 seconds, then
display and record the output of the second date command. The timer.txt file now contains a permanent log of
the runtime.

⁠ 
sysadmin@localhost:~$ cat timer.txt
Fri Nov 7 02:35:47 UTC 2020
Fri Nov 7 02:36:02 UTC 2020

10.7 xargs Command


A command’s options and parameters are usually specified on the command line, as command line arguments.
Alternatively, we can use the xargs command to gather arguments from another input source (such as a file or
standard input) and then pass those arguments to a command. The xargs command can be called directly and will
accept any input:

sysadmin@localhost:~$ xargs
Hello
There

To exit the xargs command, press Ctrl+C.


The default action of the xargs command is to pass the input to echo command when another command does not
explicitly follow it. Upon pressing Ctrl+D, the xargs command will send the input to the echo command:

Hello There
sysadmin@localhost:~$

Important

Pressing Ctrl+D after exiting the xargs command by using Ctrl+C will log you out of the current shell. To send
the input of the xargs command to the echo command without logging out of the shell, press Ctrl+D while you
are still running the xargs command.

The xargs command is most useful when it is called in a pipe. In the next example, four files will be created using
the touch command. The files will be named 1a, 1b, 1c, and 1d based on the output of the echo command.

sysadmin@localhost:~$$ echo '1a 1b 1c 1d' | xargs touch


sysadmin@localhost:~$ ls
1a 1c Desktop Downloads Pictures Templates timer.txt
1b 1d Documents Music Public Videos

These four files can be removed just as easily by changing the touch command to the rm command:

sysadmin@localhost:~$ echo '1a 1b 1c 1d' | xargs rm


sysadmin@localhost:~$ ls
Desktop Downloads Pictures Templates timer.txt
Documents Music Public Videos

A delimiter can be set using the -d option with the xargs command. To view the contents of the ~/Documents
directory containing the word alpha with all instances of the dash - character replaced with a space, type the
following:

sysadmin@localhost:~$ cd Documents/
sysadmin@localhost:~/Documents$ ls | grep alpha | xargs -d '-'
alpha first.txt
alpha second.txt
alpha third.txt
alpha.txt

The double pipe as the output of the ls command became the input of the grep command, and finally the xargs
command.

In the following example, the red.txt file will be used as the input of the xargs command:

sysadmin@localhost:~/Documents$ cat red.txt


red
reef
rot
reeed
rd
rod
roof
reed
root
reel
read

Before running the xargs command, the contents of the ~/Documents directory are:
sysadmin@localhost:~/Documents$ ls
School alpha-third.txt hidden.txt numbers.txt spelling.txt
Work alpha.txt letters.txt os.csv words
adjectives.txt animals.txt linux.txt people.csv
alpha-first.txt food.txt longfile.txt profile.txt
alpha-second.txt hello.sh newhome.txt red.txt

After running the xargs command with the touch command, eleven new files appear:

sysadmin@localhost:~/Documents$ cat red.txt | xargs touch


sysadmin@localhost:~/Documents$ ls
School alpha.txt linux.txt profile.txt reeed rot
Work animals.txt longfile.txt rd reef spelling.txt
adjectives.txt food.txt newhome.txt read reel words
alpha-first.txt hello.sh numbers.txt red rod
alpha-second.txt hidden.txt os.csv red.txt roof
alpha-third.txt letters.txt people.csv reed root

In the previous example, the output of the cat command was used as input to the touch command using xargs and
a command-line pipe. The xargs command can also be used with pipes to send the output of a command as an
argument to another command:

sysadmin@localhost:~$ find ~ -maxdepth 1 -name 'D*' | xargs du -sh


4.0K /home/sysadmin/Downloads
1.2M /home/sysadmin/Documents
4.0K /home/sysadmin/Desktop

In the example above, the find command output is used as an argument to the du disk usage command using the
xargs command. The first command preceding the pipe finds all file names that match the D* pattern. The output
of the find command is then passed to the du command as an argument to display the disk usage of the files.

Consider This

The xargs command has many, many more options that can be studied using the corresponding man page.
Key Terms
tee
Command used to read from standard input and write to standard output and files.
Section 10.6
xargs
Command used to build and execute command lines from standard input.
Section 10.7
LAB 10
10.1 Introduction
Filters are commands that read in text as input, alter it and then produce text as output. Standard input, output, error
redirection, and pipes are used to apply filter commands and to work with text streams.

10.2 Step 1
Standard output is redirected using the ">" symbol followed by the name of the file to which it will be written. To
redirect the output of the ls command to the ls_output.txt file, execute the following command:

ls > ls_output.txt

10.3 Step 2
To append the output of the date command to the file created in the previous step, execute the following
command:

date >> ls_output.txt

The number 1 is associated with the standard output file descriptor when used with the ">" and ">>" operators. The
number is implied in the examples shown above; the example can also be written as date 1 >> ls_output.txt.

10.4 Step 3
Similar to standard output, standard error can also be redirected to files. The number 2 is associated with the
standard error file descriptor. To redirect the standard error while executing the find command, execute the
following commands:

find /etc . -name hostname


find /etc . –name hostname 2> error.txt
Note: The output of the find command shown above shows the difference when the error stream is redirected to a
file. In the first instance of the find command, the "Permission denied" error is shown on the terminal while in the
second instance of the find command this error is redirected to a file.

10.5 Step 4
To redirect both standard output and standard error of the find command, execute the following command:

find /etc –name hostname > find_output.txt 2> find_error.txt

Note: To discard the output of any stream instead of redirecting it to any file, redirect it to the /dev/null file.

10.6 Step 5
To redirect both standard output and standard error of the find command to the same file, execute the following
command:

find /etc –name hostname > find_output.txt 2>&1


10.7 Step 6
An alternative command to redirect both standard output and standard error:

find /etc –name hostname &> find_output.txt

Note: The notation "2>&1" means send stderr to where stdout is going and the notation "&>" means redirect all
output.

10.8 Step 7
The "<" symbol is used for input redirection and used to pass the contents of a file as input to a command. To
translate all the lower-case characters to upper-case in the /etc/hosts file, execute the following command:

tr 'a-z' 'A-Z' < /etc/hosts

10.9 Step 8
Both input as well as output redirection can be used together in the same command. To translate all the lower-case
characters to upper-case in the /etc/hosts file and save the output in the ~/myhosts file, execute the following
command:

tr 'a-z' 'A-Z' < /etc/hosts > ~/myhosts


10.10 Step 9
The command pipeline is used to send the output of one command as input to another. To view the output of the ls
command one page at a time, execute the following command:

ls -l /etc | more

10.11 Step 10
The "|" symbol can be used multiple times within a command. To extract some fields from the /etc/passwd file,
sort them and finally eliminate duplicate lines, execute the following command:

cut –f7 –d: /etc/passwd | sort | uniq –c

10.12 Step 11
The "|" symbol can also be combined with redirection. To count the number of occurrences of "man" in the
command history and redirect the result to the count.txt file, execute the following command:

history | grep man | wc –l > count.txt


NDG Introduction to Linux I - Chapter 11: Managing
Processes

11.1 Introduction
In this chapter, you will learn how to run processes in the background or foreground, as well as how to make a
process switch between the background and foreground. You will also be taught how to control processes by
sending them signals using the kill command. In addition, different techniques for monitoring the resources that a
process is using will be presented. You will see how to control the priority of processes to affect how much
computing resources the processes will use. Finally, you will become familiar with utilities that allow multiple
processes inside a single shell.

11.2 Process Control


As mentioned in a previous chapter, running a command results in something called a process. In the Linux
operating system, processes are executed with the privileges of the user who executes the command. This allows
for processes to be limited to certain capabilities based upon the user identity. For example, typically a regular user
cannot control another user's processes.

Although there are exceptions, generally the operating system will differentiate users based upon whether they are
the administrator (also called the root user) or not. Non-root users are referred to as regular users. Users who have
logged into the root account can control any user processes, including stopping any user process.

11.2.1 Listing Processes


The ps command can be used to list processes.

ps [OPTION]...

The ps command supports three styles of options:

 Traditional UNIX style short options that use a single hyphen in front of a character
 GNU style long options that use two hyphens in front of a word
 BSD style options that use no hyphens and single character options

The ps command will display the processes that are running in the current terminal by default:

sysadmin@localhost:~$ ps
PID TTY TIME CMD
80 ? 00:00:00 bash
94 ? 00:00:00 ps

The output of the ps command includes the following columns of information:


Column Description
PID
The process identifier, which is unique to the process. This information is useful to control the process by
its ID number.
TTY
The name of the terminal or pseudo-terminal where the process is running. This information is useful to
distinguish between different processes that have the same name.
TIME
The total amount of processor time used by the process. Typically, this information isn't used by regular
users.
CMD The command that started the process.

When the ps command is run with a BSD style option, the CMD column is replaced with the COMMAND column,
which shows not just the command, but also its options and arguments. An additional column called STAT is also
displayed, which conveys the state of the processes.

For example, to see all of the current user's processes, use the x BSD option:

sysadmin@localhost:~$ ps x
PID TTY STAT TIME COMMAND
80 ? S 0:00 -bash
95 ? R+ 0:00 ps x

There are several states that a process can be in:

State Description
D Uninterruptible Sleep
R Running
S Interruptible Sleep
T Stopped
Z Zombie

⁠ Note

The Process ID in our virtual machine environment will likely be different than the one in the example.

To see all processes (processes belonging to all users and not limited to the current shell) as well as display the user
owners of the processes, use the aux BSD option:

sysadmin@localhost:~$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 18376 2968 ? Ss 16:41 0:00 /bin/bash /init
syslog 9 0.0 0.0 191328 3808 ? Ssl 16:41 0:00 /usr/sbin/rsysl
root 13 0.0 0.0 28356 2656 ? Ss 16:41 0:00 /usr/sbin/cron
root 15 0.0 0.0 72296 3272 ? Ss 16:41 0:00 /usr/sbin/sshd
bind 24 0.0 0.0 1141532 39364 ? Ssl 16:41 0:00 /usr/sbin/named
root 43 0.0 0.0 78636 3624 ? S 16:41 0:00 /bin/login -f
sysadmin 56 0.0 0.0 18508 3436 ? S 16:41 0:00 -bash
sysadmin 99 0.0 0.0 34400 2848 ? R+ 16:53 0:00 ps aux

In the example above, the aux option is actually a combination of three options:
Option Meaning
a Allows the ps command to show all processes.
u Show processes by all users and ignore restrictions to only list the current user’s processes.
x
List all processes and remove the restriction to only display the processes that are running in the current
terminal.

Instead of viewing just the processes running in the current terminal, users may want to view every process running
on the system. With traditional (non-BSD) options, the -e option will display every process. Typically, the -f
option is also used as it provides full details of the command, including options and arguments:

sysadmin@localhost:~$ ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 17:16 ? 00:00:00 /sbin??? /init
syslog 33 1 0 17:16 ? 00:00:00 /usr/sbin/rsyslogd
root 38 1 0 17:16 ? 00:00:00 /usr/sbin/cron
root 40 1 0 17:16 ? 00:00:00 /usr/sbin/sshd
bind 57 1 0 17:16 ? 00:00:00 /usr/sbin/named -u bind
root 70 1 0 17:16 ? 00:00:00 /bin/login -f
sysadmin 80 70 0 17:16 ? 00:00:00 -bash
sysadmin 96 80 0 17:26 ? 00:00:00 ps -ef

The ps command can be used along with the grep command to search for a specific process by name. To find all
processes that match the sshd string, you would type:

sysadmin@localhost:~$ ps aux | grep -i sshd


root 15 0.0 0.0 72296 3272 ? Ss 16:41 0:00 /usr/sbin/sshd
sysadmin 108 0.0 0.0 11464 1032 ? S+ 17:53 0:00 grep --color=auto -i sshd

The command above uses the pipe | character to send the ps aux command to the grep command and the -i
option to perform a case insensitive search for the sshd process

11.2.2 Searching For Processes


Since we have just shown how to find processes using the ps command, and how a user can use the ps command
and the grep command to find certain named processes, it follows logically that we cover the pgrep command;
effectively marrying the ps and grep commands together.

The pgrep command parses through the running processes and looks for the specified names or other criteria of
processes, rather than having to run the ps command, pipe its output to the grep command and then look at the
results. Users can simply use the pgrep command and various options to return what they need to find. For
example, recall that the -i option makes the grep command case insensitive. This option can also be used with the
pgrep command.

If you wanted to find all instances of the sshd command running on the system, you could use the following
command:

sysadmin@localhost:~$ pgrep -i sshd


15

The output shows the process IDs (PID) of the processes running that match the sshd string. Additionally, the -l
option can be used with the pgrep command to list the process name along with the PID:
sysadmin@localhost:~$ pgrep -li sshd
15 sshd

It is also possible to search for processes owned by a specific user by using the -u option:

sysadmin@localhost:~$ pgrep -u sysadmin -l


56 bash

In the example above, the -u and -l options displayed the bash process which has the PID 56 and is owned by the
sysadmin user.

11.2.3 Watching Processes


There are many times when it’s advantageous or informative to see a process execute over and over again. In those
cases, the watch command can be used to monitor recurring processes by using the following syntax:

watch [OPTION]... COMMAND

A command that would normally execute and exit could be used with the watch command to execute repeatedly. A
good visual example would be to run the watch command with the date command to view the date command
running repeatedly:

sysadmin@localhost:~$ watch date


Every 2.0s: date localhost: Fri Mar 27 18:30:55 2019

Fri Mar 27 18:30:55 UTC 2020

In the example above, the watch command will run the date command repeatedly and display the updated output.
By default, the watch command runs the given command every two seconds so the output of the date command
will change to show a two-second difference.

Important

To fully exit the watch command, press Ctrl+C.

The watch command can also be used with the ps command to monitor running processes in the shell:

sysadmin@localhost:~$ watch ps aux


Every 2.0s: ps aux localhost: Fri Mar 29 17:47:56 2019

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 18376 3048 ? Ss 17:44 0:00 /bin/bash /init
syslog 9 0.0 0.0 191328 3760 ? Ssl 17:44 0:00 /usr/sbin/rsysl
ogd
root 13 0.0 0.0 28356 2512 ? Ss 17:44 0:00 /usr/sbin/cron
root 15 0.0 0.0 72296 3216 ? Ss 17:44 0:00 /usr/sbin/sshd
bind 24 0.3 0.0 813852 39648 ? Ssl 17:44 0:00 /usr/sbin/named
-u bind
root 43 0.0 0.0 78636 3704 ? S 17:44 0:00 /bin/login -f
sysadmin 60 0.0 0.0 18508 3444 ? S 17:44 0:00 -bash
sysadmin 75 0.0 0.0 11180 2328 ? S+ 17:47 0:00 watch ps aux
sysadmin 136 0.0 0.0 11180 344 ? S+ 17:47 0:00 watch ps aux
sysadmin 137 0.0 0.0 4628 920 ? S+ 17:47 0:00 sh -c ps aux
sysadmin 138 0.0 0.0 34400 2952 ? R+ 17:47 0:00 ps aux
In the example above, the watch command executes the ps aux command, which displays all running processes in
the shell, repeatedly. If a new program was executed in the shell, the output of the ps aux command would update
to show the new process.

Recall that the watch command’s default interval is two seconds. Therefore, to change the interval, use the -n
option followed by the specific interval desired (in seconds) after, and then specify the command to monitor.

watch -n # [COMMAND...]

The watch command will re-execute that command on a consistent basis at the specified interval until you quit that
command or Ctrl+C to stop the watch command itself.

The watch command can also be used to keep track of changes in a configuration file, log files or anything that
changes over time. For example, the watch command can be used with the tail command to monitor the log file
/var/log/ndg/web.log.

Note

To execute the next example, first use the command below to generate new log entries in the
/var/log/ndg/web.log file:

sysadmin@localhost:~$ start_log
Starting log...

To monitor changes to the last twenty lines of the /var/log/ndg/web.log log file and execute the tail command
every fifteen seconds, use the following command:

sysadmin@localhost:~$ watch -n 15 tail -n 20 /var/log/ndg/web.log


Every 15.0s: tail -n 20 /var/log/ndg/web.log localhost: Thu Apr 4 03:20:22 2019

192.0.2.225 [2019-04-04T03:20:14] 200 "GET /news/?search=cats"


192.0.2.15 [2019-04-04T03:20:16] 500 "GET /news/puppy-and-cat"
192.0.2.143 [2019-04-04T03:20:17] 301 "GET /news/?search=cats"
192.0.2.60 [2019-04-04T03:20:18] 403 "POST /news/"
192.0.2.194 [2019-04-04T03:20:19] 301 "GET /news/puppy-and-cat"
192.0.2.59 [2019-04-04T03:20:20] 500 "GET /news/puppy-and-cat"
192.0.2.23 [2019-04-04T03:20:21] 301 "GET /news/?search=cats"
192.0.2.129 [2019-04-04T03:20:21] 403 "GET /login/?redirect_to=/news"

You can also highlight any differences between each successive execution of the program that is being watched by
specifying the -d option. In the example below, the watch command is used with the -d option to run the free
command, used to display memory on the system, repeatedly:

sysadmin@localhost:~$ watch -d free


Every 2.0s: free localhost: Wed Apr 3 16:28:21 2019

total used free shared buff/cache available


Mem: 132014640 28609416 96251712 5916 7153512 102777272
Swap: 134196220 0 134196220

The output above will show the amount of used, free, and available memory in the Mem: row updating every two
seconds, and the differences in the memory will be highlighted in each new refresh of the screen.
11.2.4 Foreground Processes
So far, the commands that have been presented in this course have been executing in what is known as the
foreground. For simple commands that run quickly and then exit, using foreground execution is appropriate. A
foreground process is one that prevents the user from using the shell until the process is complete.

When one process starts another, the first process is referred to as the parent process, and the new process is called
a child process. So, another way of thinking of a foreground process is that when running in the foreground, a child
process doesn't allow any further commands to be executed in the parent process until the child process ends.

You do not need to add anything to a command in order to make that command execute in the foreground, as that
is the default behavior.

11.2.5 Executing Multiple Commands


Before discussing background processes, consider how multiple commands can be executed on a single command
line.

Normally, users only type one command per command line, but by using the semicolon ; character as a delimiter
between commands, a user can type multiple commands on one command line. Rarely is it really necessary to run
two or more commands from one command line, but sometimes it can be useful.

When commands are separated by the semicolon, the command to the left of the semicolon executes; when it
finishes, the command to the right of the semicolon executes. Another way of describing this is to say that the
commands execute in sequence.

COMMAND;COMMAND[;COMMAND]...
COMMAND; COMMAND[; COMMAND]...

The sleep command will pause for a specified number of seconds before continuing to the next command. The
following example will print Hello, pause for 5 seconds, then print World:

sysadmin@localhost:~$ echo Hello; sleep 5; echo World


Hello
World

Recall that an alias is a feature that allows a user to create nicknames for commands or command lines. An alias
that runs multiple commands can be very useful; to accomplish this, the user would use the ; character between
each of the commands when creating the alias. For example, to create an alias called welcome which outputs the
current user, the date, and the current directory listing, execute the following command:

sysadmin@localhost:~$ alias welcome="whoami;date;ls"

Now the alias welcome will execute the whoami, date, and ls commands in series like so:

sysadmin@localhost:~$ welcome
sysadmin
Tue Mar 26 21:07:10 UTC 2019
Desktop Documents Downloads Music Pictures Public Templates Videos
A real-life scenario involving multiple commands occurs when an administrator needs to take down and restart the
network connection remotely. If the user typed the one command to bring down the network and then executed it,
then the network connection would be terminated, and the user wouldn't be able to bring the network back up
again. Instead, the user could type the command to take down the network, followed by a semicolon, then the
command to bring up the network. After pressing the Enter key, both commands would execute, one right after the
other.

11.2.6 Background Processes


When a command may take some time to execute, it may be better to have that command execute in the
background. When executed in the background, a child process releases control back to the parent process (the
shell, in this case) immediately, allowing the user to execute other commands. To have a command execute as a
background process, add the ampersand & character after the command.

COMMAND &

For example, the following executes the sleep command for three seconds in the background. Pressing Enter after
the sleep command runs will display information about the background process:

sysadmin@localhost:~$ sleep 3 &


[1] 87
sysadmin@localhost:~$
[1]+ Done sleep 3

As shown in the output, when executing commands in the background; after each command starts executing, it
outputs a job number followed by a space and then the process identification number (PID). These numbers are
used for controlling the process. The sleep command in the preceding example has a job number of 1 and a PID of
87.

While there are still background processes being run in the terminal, they can be displayed by using the jobs
command. It is important to point out that the jobs command will only show background processes in the current
terminal. If background processes are running in another terminal, they will not be shown by running the jobs
command in the current terminal. The following is an example of using the jobs command:

sysadmin@localhost:~$ sleep 1000 &


[1] 106
sysadmin@localhost:~$ sleep 2000 &
[2] 107
sysadmin@localhost:~$ jobs
[1]- Running sleep 1000 &
[2]+ Running sleep 2000 &

In the example above, the jobs command shows the two sleep processes running in the background. The job
number of a process is sometimes followed by a minus - or a plus + character. The plus + character denotes the last
process that was started, while the minus - character denotes a process started previous to the latest one. Once a
third job is created, only the most recent job will have the + next to it and the next-most recent, or previous, job
will have the - next to it. All other jobs will have a blank in that space. This allows you to see what the most recent
and next-most recent jobs are very quickly.

To terminate the processes, send them to the foreground by using the fg command with the job number of the
process to terminate, and while the process is running in the foreground, use Ctrl+C, a signal which stops the
process:
sysadmin@localhost:~$ fg 1
sleep 1000
^C
sysadmin@localhost:~$ fg 2
sleep 2000
^C
sysadmin@localhost:~$ jobs
sysadmin@localhost:~$

Note

The fg command, as well as a more efficient method for terminating processes, will be covered in greater detail
later in this chapter.

To have multiple commands run in the background on one command line, place an ampersand & character after
each command on the command line. In the next example, all three commands execute at the same time and release
control back to the shell, so a user does not have to wait for any of the commands to finish before executing
another command (although the user may need to press Enter again to get a prompt):

sysadmin@localhost:~$ echo Hello & echo World & echo '!' &
[1] 94
[2] 95
Hello
[3] 96
sysadmin@localhost:~$ World
!

[1] Done echo Hello


[2]- Done echo World
[3]+ Done echo '!'

11.2.7 Moving Processes


If the following sleep command is run without an ampersand character to send it to the background, the terminal
would not be available for 1000 seconds:

sysadmin@localhost:~$ sleep 1000


_

To make the terminal available again, the user would have to use Ctrl+Z, a signal which pauses the process:

^Z
[1]+ Stopped sleep 1000

Now the terminal is back, but the sleep command has been paused. To put the paused command in the
background, execute the bg command.

bg [JOB_ID]...

The bg command resumes jobs without bringing them to the foreground. If no argument is provided, it will use the
most recently suspended job.

sysadmin@localhost:~$ bg
[1]+ sleep 1000 &
A command that has been paused or sent to the background can then be returned to the foreground using the fg
command.

fg [JOB_ID]...

Similar to the bg command, if no argument is provided, the job that was most recently suspended or placed in the
background will be used. To bring the sleep command back to the foreground, locking up the terminal again, use
the fg command:

sysadmin@localhost:~$ fg
sleep 1000
_
^C
sysadmin@localhost:~$

Suppose we have two paused processes:

sysadmin@localhost:~$ sleep 1000


^Z
[1]+ Stopped sleep 1000
sysadmin@localhost:~$ sleep 2000
^Z
[2]+ Stopped sleep 2000
sysadmin@localhost:~$ jobs
[1] Running sleep 1000 &
[2]- Running sleep 2000 &

Both bg and fg can take the job number as an argument to specify which process should be resumed. The
following commands will resume sleep 1000 in the background and resume sleep 2000 in the foreground
respectively:

sysadmin@localhost:~$ bg 1
[1]- sleep 1000 &
sysadmin@localhost:~$ fg 2
sleep 2000
^Z
[2]+ Stopped sleep 2000

It is also possible to use the name of the command as an argument to the bg and fg commands:

sysadmin@localhost:~$ sleep 1000


_
^Z
[1]+ Stopped sleep 1000
sysadmin@localhost:~$ bg sleep
[1]+ sleep 1000 &

Given multiple tasks and only one terminal to use with them, the fg and bg commands provide an administrator
with the ability to manually multi-task.

11.2.8 Sending a Signal


A signal is a message that is sent to a process to tell the process to take some sort of action, such as stop, restart, or
pause. Signals are very useful in controlling the actions of a process.
Some signals can be sent to processes by simple keyboard combinations. For example, to have a foreground
process paused, send a Terminal Stop signal by pressing Ctrl+Z. A Terminal Stop pauses the program but does not
completely stop the program. To completely stop a foreground process, send the Interrupt signal by pressing
Ctrl+C.

There are many different signals; each of them has a symbolic name and a numeric identifier. For example, Ctrl+C
is assigned the symbolic name SIGINT and the numeric identifier of 2.

To see a list of all of the signals available for your system, execute the kill -l command:

sysadmin@localhost:~$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX

These signals can have unique meanings that are specific to a certain command (as the programmer who created
the command can adjust the behavior of the program), but generally they allow for processes to be stopped and
resumed, for processes to reconfigure themselves, or to end a process. All the signals with a number greater than 31
are for controlling real-time processes, a topic which is beyond the scope of this course. Some of the more
common signals are summarized in the following table:

Number Full Name Short Name Purpose


1 SIGHUP HUP Hang up, usually ends a process
2 SIGINT INT Interrupt, usually ends a process
3 SIGQUIT QUIT Quit, usually ends a process
9 SIGKILL KILL Kill, forcefully ends a process
15 SIGTERM TERM Terminate, usually ends a process
18 SIGCONT CONT Continue, resumes a stopped process
19 SIGSTOP STOP Stop, forcefully stops a process
20 SIGTSTP TSTP Terminal Stop, usually stops a process

There are several commands that will allow you to specify a signal to send to a process; the kill command is the
most commonly used. The syntax for the kill command looks like the following:

kill [OPTIONS]... <pid>

The kill command specifies which signal to be sent using options. It accepts three different ways to specify the
signal:

-<signal>
-s <signal>
--signal <signal>
The signal can be specified by using the number, the short name, or the full name. For example, to specify the
Interrupt signal, any of the following options could be used:

-2
-INT
-SIGINT

If the user doesn't specify a signal with an option, then the kill command defaults to sending the Terminate
SIGTERM signal.

When sending a signal, specify one or more processes to send the signal to. There are numerous techniques to
specify the process or processes. The more common techniques include:

 Specifying the process identifier (PID)


 Using the % (percent sign) prefix to the job number

For example, imagine a scenario where a user is running some process in the background and that user wants to
send a signal to the process. For this demonstration, the sleep command is run in the background:

sysadmin@localhost:~$ sleep 5000&


[1] 2901

A couple of items are noteworthy from the output of starting this process in the background. First, notice the job
number in square brackets [1]. Second, notice the process identifier (PID) which is 2901. To send the Terminate
signal, to this process, you can use either of the following commands:

sysadmin@localhost:~$ kill 2901


sysadmin@localhost:~$ kill %1

As indicated earlier, the Terminate signal normally will end a process. Sometimes a process will trap the
Terminate signal so it may not end that process. Trapping occurs when a process behaves differently from the norm
when it receives a signal; this can be the result of how the programmer created the code for the command.

A user could try to use other signals, like SIGQUIT or SIGINT, to try to end a process, but these signals can also be
trapped. The only signal that will end a process and can't be trapped is a SIGKILL signal. So, if other signals have
failed to end a process, use the SIGKILL signal to force the process to end.

Users should not normally use the SIGKILL signal as the initial attempt to try to end a process because this forces
the process to end immediately and will not allow the process the opportunity to "clean up" after itself. Processes
often perform critical operations, such as deleting temporary files, when they exit naturally.

The following examples show two ways to send the Kill signal to a process:

sysadmin@localhost:~$ kill -9 2901


sysadmin@localhost:~$ kill -KILL %1

There are other commands that send processes signals, such as the killall and pkill commands, which are
useful to stop many processes at once; whereas the kill command is a good choice for sending signals to a single
process. The pkill command can be used to terminate one or more processes by name and other criteria such as
the terminal and UID. Similar to how the pgrep command searches for a process by matching its name or pattern,
the pkill command allows users to specify a pattern that matches a process name and then sends signals to that
process. The following is a commonly used syntax for the pkill command:

pkill [OPTIONS]... PATTERN


The killall command can also be used to terminate one or more processes by name and other criteria such as the
user owner of the process and system processes. The following demonstrates syntax that can be used for the
killall command:

killall [OPTIONS]... NAME

Like the kill command, signals can be specified using either the number or signal name for both the killall and
pkill commands. Unlike the kill command, these other commands can be used to terminate all processes of a
particular user with the -u option. For example, killall -u bob would stop all of the process owned by the bob
user.

The killall and pkill commands also accept the name of the process instead of a process or job number. Just be
careful as this may end up stopping more processes than you had expected. An example of stopping a process using
the process name:

sysadmin@localhost:~$ kill sleep


-bash: kill: sleep: arguments must be process or job IDs
sysadmin@localhost:~$ killall sleep
[1]+ Terminated sleep 5000

Consider This

You could very easily feed the output of the pgrep command to the kill command to terminate a process. For
example, by using the xargs command to help feed the lines of the output to the kill command one at a time, so it
works properly:

sysadmin@localhost:~$ pgrep -i nano | xargs kill -9

This will result in the kill -9 command being run on each of the PIDs that pgrep brought back for the nano
query.

11.2.9 HUP Signal


When a user logs off the system, all processes that are owned by that user are automatically sent the Hang Up
SIGHUP signal. Typically, this signal causes those processes to end.

In some cases, a user may want to execute a command that won't automatically exit when it is sent a HUP signal. To
have a process ignore a Hang Up signal, start the process with the nohup command.

nohup COMMAND [ARG]...

For example, consider a scenario where a user has a script named myjob.sh that needs continue to run all night
long. The user should start that script in the background of the terminal by executing:

sysadmin@localhost:~$ nohup myjob.sh &

After executing the script, the user could proceed to log out. The next time the user logs in, the output of the script,
if any, would be contained in the nohup.out file in that user's home directory.
1.2.10 Process Priority
When a process runs, it needs to have access to the CPU to perform actions. Not all processes have the same access
to the CPU. For example, system processes typically have a higher priority when accessing the CPU.

The Linux kernel dynamically adjusts the priority of processes to try to make the operating system seem responsive
to the user and efficient at performing tasks. A user can influence the priority that will be assigned to a process by
setting a value of something called niceness.

The higher you set the niceness value, the lower the priority that will be assigned to a process. The default value of
niceness for processes is zero; most user processes run at this nice value. Only a user with administrative (root)
access can set negative niceness values or alter the niceness of an existing process to be a lower niceness value.

To set the initial niceness of a command, use the nice command as a prefix to the command to execute.

nice [OPTION] [COMMAND [ARG]...]

The -n option indicates the desired niceness value. For example, to execute a command at the lowest priority
possible, execute the following command:

sysadmin@localhost:~$ nice -n 19 cat /dev/zero > /dev/null


^Z
[1]+ Stopped nice -n 19 cat /dev/zero > /dev/null

If a user logs in as the root user, they could also execute a command with the highest priority possible by executing
the following command:

Note

The su command used below allows a regular user to become the root user temporarily. The user is required to
enter the root account password, when prompted. To use the su command in our virtual environment, enter the
root password netlab123.

sysadmin@localhost:~$ su -
Password:
root@localhost:~# nice -n -20 cat /dev/zero > /dev/null
^Z
[1]+ Stopped nice -n -20 cat /dev/zero > /dev/null
root@localhost:~# nice -n 19 cat /dev/zero > /dev/null
^Z
[2]+ Stopped nice -n 19 cat /dev/zero > /dev/null

To adjust the niceness of an existing process, use the renice command. This can be useful when the system
becomes less responsive after running a CPU intensive command. A user could make the system more responsive
again by making that process run "nicer".
To accomplish this, the user would need to discover the process identifier for the process by using the ps
command. For example:

⁠ Note

The Process ID in our virtual machine environment will likely be different than the one in the example.

root@localhost:~# nice -n -20 cat /dev/zero > /dev/null &


[1] 121
root@localhost:~# ps
PID TTY TIME CMD
1 ? 00:00:00 init
70 ? 00:00:00 login
108 ? 00:00:00 su
109 ? 00:00:00 bash
121 ? 00:00:04 cat
122 ? 00:00:00 ps

Next, use the renice command to adjust the priority back to normal. Like the nice command, the -n option
indicates the niceness value. The -p option indicates the process ID to operate on.

root@localhost:~# renice -n 0 -p 121


121 (process ID) old priority -20, new priority 0

11.2.11 Monitoring Processes


While the ps command can display active processes, the top command provides the ability to monitor processes in
real-time, as well as manage the processes. By default, the output of the top command will update every three
seconds. For example, the following output demonstrates how the top command can be used to monitor processes
currently running in the terminal, such as the three cat commands executed in the previous section:

sysadmin@localhost:~$ top
top - 16:47:34 up 51 days, 2:12, 1 user, load average: 1.37, 1.56, 1.49
Tasks: 13 total, 4 running, 9 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.3 us, 37.2 sy, 0.2 ni, 62.1 id, 0.0 wa, 0.1 hi, 0.0 si, 0.0 st
KiB Mem: 16438128 total, 13108516 used, 3329612 free, 4276 buffers
KiB Swap: 0 total, 0 used, 0 free. 9808716 cached Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND


164 root 20 0 4364 696 616 R 87.4 0.1 1:23.32 cat
165 root 30 10 4364 696 620 T 9.3 0.1 0:49.13 cat
166 root 39 19 4364 772 696 T 1.7 0.1 0:41.75 cat
1 root 20 0 17960 2972 2724 S 0.0 0.0 0:00.02 init
33 syslog 20 0 255844 2728 2296 S 0.0 0.0 0:00.03 rsyslogd
38 root 20 0 23656 2288 2076 S 0.0 0.0 0:00.00 cron
40 root 20 0 61364 3124 2444 S 0.0 0.0 0:00.00 sshd
57 bind 20 0 689640 29580 5328 S 0.0 0.2 0:00.13 named
70 root 20 0 63132 2900 2452 S 0.0 0.0 0:00.00 login
80 sysadmin 20 0 18176 3384 2896 S 0.0 0.0 0:00.04 bash
151 root 20 0 46628 2708 2360 S 0.0 0.0 0:00.01 su
152 root 20 0 18180 3388 2896 S 0.0 0.0 0:00.01 bash
167 root 20 0 19860 2452 2124 R 0.0 0.0 0:00.00 top

Upon closer investigation of the niceness column NI and the CPU usage percentage column %CPU in the output
above, we can see that the cat command with the lowest niceness (0) is using the highest percentage CPU (87.4),
while the cat command with the highest niceness (19) is using the lowest percentage CPU (1.7).
The top command has numerous features; for example, it can be manipulated in an interactive manner. Pressing
the H key while the top command is running will result in it displaying a help screen:

Help for Interactive Commands - procps-ng version 3.3.9


Window 1:Def: Cumulative mode Off. System: Delay 3.0 secs; Secure mode Off.

Z,B,E,e Global: 'Z' colors; 'B' bold; 'E'/'e' summary/task memory scale
l,t,m Toggle Summary: 'l' load avg; 't' task/cpu stats; 'm' memory info
0,1,2,3,I Toggle: '0' zeros; '1/2/3' cpus or numa node views; 'I' Irix mode
f,F,X Fields: 'f'/'F' add/remove/order/sort; 'X' increase fixed-width

L,&,<,> . Locate: 'L'/'&' find/again; Move sort column: '<'/'>' left/right


R,H,V,J . Toggle: 'R' Sort; 'H' Threads; 'V' Forest view; 'J' Num justify
c,i,S,j . Toggle: 'c' Cmd name/line; 'i' Idle; 'S' Time; 'j' Str justify
x,y . Toggle highlights: 'x' sort field; 'y' running tasks
z,b . Toggle: 'z' color/mono; 'b' bold/reverse (only if 'x' or 'y')

u,U,o,O . Filter by: 'u'/'U' effective/any user; 'o'/'O' other criteria


n,#,^O . Set: 'n'/'#' max tasks displayed; Show: Ctrl+'O' other filter(s)
C,... . Toggle scroll coordinates msg for: up,down,left,right,home,end

k,r Manipulate tasks: 'k' kill; 'r' renice


d or s Set update interval
W,Y Write configuration file 'W'; Inspect other output 'Y'
q Quit
( commands shown with '.' require a visible task display window )
Press 'h' or '?' for help with Windows,
Type 'q' or <Esc> to continue

The K and R keys are used to manage tasks or processes within the top program.

Pressing the K key will allow a user to kill or send a signal to a process. After pressing the K key, the top
command will prompt for a PID and then for a signal to send to that process.

Pressing the R key will allow a user to renice a process by prompting for the PID and then the new niceness value.

Press the Q key to quit the top command

11.3 Monitoring the System


There are also a couple of commands that can be used to monitor the overall state of the system: the uptime and
free commands.

The uptime command shows the current time and the amount of time the system has been running, followed by the
number of users who are currently logged in and the load averages during the past one, five, and fifteen-minute
intervals.

To get a good idea of how busy a system is, use the uptime command:

sysadmin@localhost:~$ uptime
18:24:58 up 5 days, 10:43, 1 user, load average: 0.08, 0.03, 0.05

The numbers reported for the load averages are based upon how many CPU cores are available. Think of each
processor as having 100% resources (CPU time) available. One processor = 100%, four processors = 400%. The
uptime command is reporting the amount of resources used, but it is dividing by 100. So, 1.00 is actually 100% of
the CPU time being used, 2.00 is 200% and so on.

If a system has only one CPU core, then a value of 1.00 indicates that the system was fully loaded with tasks. If the
system has two CPU cores, then a value of 1.00 would indicate a 50% load (1.00/2.00). An uptime reading of 1.00
(or 100%) usage on a 4 core CPU would imply that 1.00/4.00 (1/4 or 25%) of the CPU's total computational
resources are being used.

Consider This

If you don’t know how many CPU cores are available on a Linux system, there is a way to obtain this information
on the command line. The lscpu command can be used to see how many CPU cores are available on the system:

sysadmin@localhost:~$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 16
On-line CPU(s) list: 0-15
Thread(s) per core: 2
Core(s) per socket: 4
Socket(s): 2
Output Omitted...

In the example above, the output indicates that there are eight total CPU cores. Two sockets and four cores per
socket totals eight CPU cores.

Although the lscpu command is beyond the scope of this course, it is covered in further detail in NDG Linux
Essentials, where you can learn about understanding system hardware.

To get an idea of how your system is using memory, the free command is helpful. This command displays not
only the values for the random-access memory (RAM) but also for swap, which is space on the hard disk that is
used as memory for idle processes when the random-access memory starts to become scarce.

The free command reports the total amount of memory, as well as how much is currently being used and how
much is free (available) for use. The output also breaks down the use of memory for buffers and caches:

sysadmin@localhost:~$ free
total used free shared buffers cached
Mem: 16438128 13106024 3332104 3200 4276 9808896

-/+ buffers/cache: 3292852 13145276


Swap: 0 0 0

If logged into the Gnome desktop environment, the user can use the gnome-system-monitor program. This tool
(pictured below) is analogous to the Task Manager in Microsoft Windows. It provides four tabs to view
information about the System, Processes, Resources, and File Systems.

This graphical tool allows users to select a process and send a signal to it to terminate it, as well as view all current
processes updated in real-time.
Consider This

The K desktop environment (KDE) has a similar program, the ksysguard command. The Gnome desktop
environment is not available in the virtual environment for this chapter.
11.4 Multi-Session Command Line Utilities
Now that we have discussed process creation and management, we can talk about a related topic, which is how you
can manage multiple processes inside a single Bash shell environment.

The need for multiple processes inside a single shell is not very important to a console user, who can simply switch
to another TTY (terminal session accessible via hardware means) and run another shell, or open another instance of
the graphical terminal app on a desktop session. However, imagine the user is connected via the ssh command to
another system that does not have those multiple terminal capabilities but needs to accomplish several tasks inside
their one connected shell session on that remote system.

Such a user might need to run a command to monitor CPU usage, edit a configuration file, and possibly execute a
command to initiate a system update. However, without special program assistance, they would only be able to do
one at a time, or would have to use the jobs command method of putting each command into the background and
having little more than the ability to switch between the jobs.

There are a couple of options to accomplish true multiple terminal session productivity when limited to a single
Bash shell connection on a system. We will focus on the screen and tmux commands, both of which allow the user
to start processes in a session that can be detached while still running, then re-attached and managed by various
methods.

11.4.1 screen Command


The screen command also allows you to run commands and control the command’s environment from within a
screen session. The screen command is the simpler, and much older of the two multi-session utilities previously
mentioned. It is not as dynamic, but it is consistent and dependable; two traits that inspire true loyalty from system
operators and system administrators.

Normally, when using a terminal, running a process will cause the terminal to be occupied until that process
finishes executing, is stopped or terminated, or is placed in the background. However, the screen command allows
for multiple processes to run within separate sessions under a single terminal. This is possible because, by default,
the screen command provides a new session with a shell in it where a command can be executed with the ability
to detach from that session and return the shell to start new sessions.

To start the screen command by itself, type the command at the prompt:

sysadmin@localhost:~$ screen
GNU Screen version 4.06.02 (GNU) 23-Oct-17

Copyright (c) 2015-2017 Juergen Weigert, Alexander Naumov, Amadeusz Slawinski


Copyright (c) 2010-2014 Juergen Weigert, Sadrul Habib Chowdhury
Copyright (c) 2008-2009 Juergen Weigert, Michael Schroeder, Micah Cowan,
Sadrul Habib Chowdhury
Copyright (c) 1993-2007 Juergen Weigert, Michael Schroeder
Copyright (c) 1987 Oliver Laumann

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program (see the file COPYING); if not, see http://www.gnu.org/licenses/,
or contact Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,

[Press Space for next page; Return to end.]

To get rid of the message and return to the command line, press Enter. When the screen command returns to the
command line, the user is in a screen session. This is an instance of the Bash shell that is contained by the screen
command; like a container or box that you can use as a full Bash shell, only it is controlled by the screen
command.

sysadmin@localhost:~$

To verify that there is a screen session running, use the -list option to the screen command:

sysadmin@localhost:~$ screen -list


There is a screen on:
85.console.localhost (03/30/19 14:33:05) (Attached)
1 Socket in /run/screen/S-sysadmin.

Notice the text (Attached) in the output of the previous command, which indicates that the session is the one the
user is currently attached to; in other words, the user is in that screen session.

Note

Typing the screen command inside an existing screen session does not start a new screen session.

When using the screen command to run multiple commands in a single shell instance, it may be useful to create a
session that monitors the system as well. The screen command can be used with commands that monitor system
processes or system status, such as the top or ps commands. To demonstrate, run the top command in this screen
session:

sysadmin@localhost:~$ top
top - 21:45:00 up 11 days, 23:28, 2 users, load average: 0.33, 0.38, 0.34
Tasks: 12 total, 1 running, 11 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.7 us, 1.4 sy, 0.0 ni, 97.9 id, 0.0 wa, 0.0 hi, 0.1 si, 0.0 st
KiB Mem : 13201464+total, 10386072+free, 21642984 used, 6510928 buff/cache
KiB Swap: 13419622+total, 13419622+free, 0 used. 10974582+avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND


25 bind 20 0 944924 39472 7148 S 3.6 0.0 0:00.59 named
9 syslog 20 0 191328 5820 3272 S 0.3 0.0 0:00.04 rsyslogd
1 root 20 0 18376 2976 2700 S 0.0 0.0 0:00.03 init
12 root 20 0 28356 2744 2476 S 0.0 0.0 0:00.00 cron
15 root 20 0 72296 3296 2548 S 0.0 0.0 0:00.00 sshd
44 root 20 0 78636 3636 3084 S 0.0 0.0 0:00.00 login
61 root 20 0 170204 32564 11760 S 0.0 0.0 0:01.69 check-new-+
62 sysadmin 20 0 19220 4116 2912 S 0.0 0.0 0:00.03 bash
81 sysadmin 20 0 28492 2624 2368 S 0.0 0.0 0:00.00 screen
82 sysadmin 20 0 28640 2900 2372 S 0.0 0.0 0:00.00 screen
83 sysadmin 20 0 19300 4172 2992 S 0.0 0.0 0:00.01 bash
100 sysadmin 20 0 38696 3192 2748 R 0.0 0.0 0:00.00 top
A useful feature of the screen command is the ability to detach a session, then re-attach it later. While detached,
the user returns to the prompt they were using before running the screen command and the processes running in
the screen session will continue to run, even if the user is not able to see them in the terminal. To attach and
detach a screen session, as well as perform other actions in the screen program, you will need to use the screen
command keys.

All screen commands start with a prefix key, the keystrokes Ctrl+A (denoted as C-a in the man pages) and then
are followed by a single other character, or command key, to make an action happen.

Note

To view a list of the screen commands, type Ctrl+A and then a question mark ? while in a screen session:

Screen key bindings, page 1 of 2.

Command key: ^A Literal ^A: a

break ^B b license , removebuf =


clear C lockscreen ^X x reset Z
colon : log H screen ^C c
copy ^[ [ login L select '
detach ^D d meta a silence _
digraph ^V monitor M split S
displays * next ^@ ^N sp n suspend ^Z z
dumptermcap . number N time ^T t
fit F only Q title A
flow ^F f other ^A vbell ^G
focus ^I pow_break B version v
hardcopy h pow_detach D width W
help ? prev ^H ^P p ^? windows ^W w
history { } quit \ wrap ^R r
info i readbuf < writebuf >
kill K k redisplay ^L l xoff ^S s
lastmsg ^M m remove X xon ^Q q

[Press Space for next page; Return to end.]

Note

No text will appear at the prompt when typing the screen command keys. Press Enter to return to the prompt
within the screen session.

In the next example, pressing the prefix key Ctrl+A gets the attention of the screen command, and then the
command key D issues the detach command, which detaches the screen command from the current terminal and
returns the user to the original shell prompt.

For example, detach from the current screen session (and leave the top command running) by pressing the
keystrokes:

Ctrl+A
D
[detached from 85.console.localhost]
sysadmin@localhost:~$

In the example output above, a message appears stating the user has been detached from 85.console.localhost
and the user will return to a Bash prompt. However, the user is still using the screen environment.
The format of identification for a screen process is the following:

PID.TTY.HOST

The first set of characters PID indicates the PID of the process, TTY means the terminal type the process is running
in, and HOST is the hostname, or process name if changed using the -S option. The Process ID in our virtual
machine environment will likely be different than the one in the example.

It is also possible to run a command at the shell prompt in a screen session and then immediately detach that
session in order to continue conducting other operations at the prompt. For example, start the nano text editor in a
screen session and detach it with the following command:

sysadmin@localhost:~$ screen -S nano_edit -d -m nano

The command above will start the nano text editor in a detached screen session named nano_edit and drop the
user back to a shell prompt. The session is named using the session name -S option, which is followed by the
desired session name as an argument. The -d -m option specifies to start the session in detached mode.

Note

In this instance, the -d -m option is considered to be a single option by the screen command, not two separate
options.

To see that there is an additional screen session, run the screen command with the -list option again:

sysadmin@localhost:~$ screen -list


There are screens on:
128.nano_edit (03/31/19 18:39:24) (Detached)
85.console.localhost (03/31/19 18:18:43) (Detached)
2 Sockets in /run/screen/S-sysadmin.

The output shows that there are two sessions running; one of which is named nano_edit. Once a session is started,
a user cannot rename it in the screen -list command output, so it is recommended to name all screen sessions
as they are created.

The user can now re-attach to either of the sessions by using the resume -r option with either the PID of the
session or by the name of the session. For example, the example below will re-attach the user to the session
containing the top command:

Note

In order to execute this command, use the PID associated with the top command, which may differ from the PID
in the example.

sysadmin@localhost:~$ screen -r 85
top - 21:49:24 up 11 days, 23:32, 2 users, load average: 0.64, 0.40, 0.35
Tasks: 13 total, 1 running, 12 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.9 us, 1.6 sy, 0.0 ni, 96.5 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 13201464+total, 10381150+free, 21690320 used, 6512812 buff/cache
KiB Swap: 13419622+total, 13419622+free, 0 used. 10969848+avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND


1 root 20 0 18376 2976 2700 S 0.0 0.0 0:00.03 init
9 syslog 20 0 191328 5820 3272 S 0.0 0.0 0:00.04 rsyslogd
12 root 20 0 28356 2744 2476 S 0.0 0.0 0:00.00 cron
15 root 20 0 72296 3296 2548 S 0.0 0.0 0:00.00 sshd
25 bind 20 0 1077296 40844 7212 S 0.0 0.0 0:01.29 named
44 root 20 0 78636 3636 3084 S 0.0 0.0 0:00.00 login
62 sysadmin 20 0 19220 4116 2912 S 0.0 0.0 0:00.04 bash
82 sysadmin 20 0 28752 2940 2372 S 0.0 0.0 0:00.01 screen
83 sysadmin 20 0 19300 4172 2992 S 0.0 0.0 0:00.01 bash
100 sysadmin 20 0 38696 3192 2748 R 0.0 0.0 0:00.09 top
106 sysadmin 20 0 28624 2708 2384 S 0.0 0.0 0:00.00 screen
107 sysadmin 20 0 11800 2976 2176 S 0.0 0.0 0:00.01 nano
109 sysadmin 20 0 28492 2688 2432 S 0.0 0.0 0:00.00 screen

To detach from the top command in the screen session and return to the shell, press Ctrl+A, then D:

[detached from 106.console.localhost]


sysadmin@localhost:~$

At this point, the top command is running in a screen session, the nano editor is being used to run and possibly
editing files in another session, and it is still possible to create more sessions as well as type commands at the shell.

To get rid of a screen session, attach to each session, and quit the program that is running. For example, the nano
session can be re-attached using the screen command below:

sysadmin@localhost:~$ screen -r nano_edit

Press Ctrl+X to exit the nano command and follow the prompts. When the nano process has exited, there will be
no nano_edit screen session in the -list output:

sysadmin@localhost:~$ screen -list


There is a screen on:
85.console.localhost (03/30/19 14:55:05) (Attached)
1 Socket in /run/screen/S-sysadmin.

To exit the screen command, use the exit command:

sysadmin@localhost:~$ exit
[screen is terminating]
sysadmin@localhost:~$

Important

Using the exit command more than once when exiting the screen command will result in being logged out of the
current Bash shell and will open a new Bash shell.
11.4.2 tmux Command
The tmux command, short for terminal multiplexer, allows for multiple terminals to be opened and viewed on the
same screen. Fundamentally, the tmux command is similar to the screen command, but layers on more visual
aspects. For example, the tmux command includes a status bar at the bottom of the terminal the user is running
tmux in that shows various items of information.

To start using the tmux command, execute the command at the prompt:

sysadmin@localhost:~$ tmux

The shell session will appear, showing the usual green last-row indicator bar, which contains session and other
information about the tmux command.

sysadmin@localhost:~$

[0] 0:bash* "localhost" 05:24 01-Apr-19

It is now possible to run a command in the current tmux session. For example, run the top command in the current
session:

sysadmin@localhost:~$ top
top - 23:06:02 up 15 days, 45 min, 2 users, load average: 2.86, 2.73, 2.18
Tasks: 11 total, 1 running, 10 sleeping, 0 stopped, 0 zombie
%Cpu(s): 6.2 us, 4.2 sy, 0.0 ni, 89.3 id, 0.1 wa, 0.0 hi, 0.2 si, 0.0 st
KiB Mem : 13201464+total, 58008456 free, 29883988 used, 44122196 buff/cache
KiB Swap: 13419622+total, 13419622+free, 0 used. 10150048+avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND


1 root 20 0 18376 3172 2900 S 0.0 0.0 0:00.07 init
9 syslog 20 0 191328 3772 3272 S 0.0 0.0 0:00.04 rsyslogd
12 root 20 0 28356 2756 2488 S 0.0 0.0 0:00.00 cron
15 root 20 0 72296 3244 2496 S 0.0 0.0 0:00.00 sshd
25 bind 20 0 1141792 39948 7088 S 0.0 0.0 0:01.05 named
44 root 20 0 78636 3708 3156 S 0.0 0.0 0:00.00 login
62 sysadmin 20 0 19220 4172 2968 S 0.0 0.0 0:00.04 bash
87 sysadmin 20 0 27096 3688 3100 S 0.0 0.0 0:00.11 tmux: serv+
88 sysadmin 20 0 19300 4196 2948 S 0.0 0.0 0:00.03 bash
97 sysadmin 20 0 38692 3120 2676 R 0.0 0.0 0:00.36 top
105 sysadmin 20 0 18460 2996 2676 S 0.0 0.0 0:00.00 tmux: clie+

[0] 0:top* "localhost" 23:05 03-Apr-19

To detach from the running command, in this case, the top command, press Ctrl+B, then the D command key. The
action should be executed as Ctrl and lowercase b at the same time, then release and press d. This will return the
user to a shell session as well as indicate that the user is detached (from session 0) and is back at the shell
prompt:

[detached (from session 0)]]


sysadmin@localhost:~$

Similar to the screen command, the tmux command uses a prefix key, the combination of the Control key plus a
letter key, in this case, the B key. The Ctrl+B key sequence prefixes all tmux in-session commands, similar to the
prefix key Ctrl+A used by the screen command.

Consider This

To learn more about tmux in-session commands, refer to the man pages of the tmux command where you will find
the commands explained in complete detail.

sysadmin@localhost:~$ man man

To find out what tmux sessions currently exist, use either of the commands below:

tmux list-sessions
tmux ls
sysadmin@localhost:~$ tmux list-sessions
0: 1 windows (created Wed Apr 3 22:49:41 2019) [80x23]
sysadmin@localhost:~$ tmux ls
0: 1 windows (created Wed Apr 3 22:49:41 2019) [80x23]

To create a new tmux session and run a new command in it, use the tmux new-session command:

sysadmin@localhost:~$ tmux new-session 'less /etc/passwd'


root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd/netif:/usr/
sbin/nologin
/etc/passwd
[1] 0:less* "localhost" 23:10 03-Apr-19

Then, to detach from the tmux session running the less command, press the Ctrl+B key sequence and then the D
key, to be returned to the shell prompt again:

[detached (from session 1)]


sysadmin@localhost:~$
Confirm that another session now exists with the tmux ls command:

sysadmin@localhost:~$ tmux ls
0: 1 windows (created Wed Apr 3 22:49:41 2019) [80x23]
1: 1 windows (created Wed Apr 3 23:09:57 2019) [80x23]

To re-attach to a running tmux session, such as session 0, use the tmux attach command with the target-session
-t flag which specifies the session to act upon:

Note

The -t option used in this example is specific to the attach command, not the tmux command itself. For more
information, consult the man page of the tmux command.

sysadmin@localhost:~$ tmux attach -t 0


top - 23:46:09 up 15 days, 1:25, 3 users, load average: 2.86, 1.70, 1.42
Tasks: 12 total, 1 running, 11 sleeping, 0 stopped, 0 zombie
%Cpu(s): 2.3 us, 2.7 sy, 0.0 ni, 95.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 13201464+total, 78182592 free, 30386524 used, 23445524 buff/cache
KiB Swap: 13419622+total, 13419622+free, 0 used. 10099883+avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND


1 root 20 0 18376 3172 2900 S 0.0 0.0 0:00.07 init
9 syslog 20 0 191328 3772 3272 S 0.0 0.0 0:00.04 rsyslogd
12 root 20 0 28356 2756 2488 S 0.0 0.0 0:00.00 cron
15 root 20 0 72296 3244 2496 S 0.0 0.0 0:00.00 sshd
25 bind 20 0 1207588 40208 7088 S 0.0 0.0 0:01.57 named
44 root 20 0 78636 3708 3156 S 0.0 0.0 0:00.00 login
62 sysadmin 20 0 19220 4172 2968 S 0.0 0.0 0:00.04 bash
87 sysadmin 20 0 27096 3764 3164 S 0.0 0.0 0:00.42 tmux: serv+
88 sysadmin 20 0 19300 4196 2948 S 0.0 0.0 0:00.03 bash
97 sysadmin 20 0 38692 3120 2676 R 0.0 0.0 0:01.31 top
101 sysadmin 20 0 6912 1020 916 S 0.0 0.0 0:00.00 less
123 sysadmin 20 0 18460 3096 2776 S 0.0 0.0 0:00.00 tmux: clie+

[0] 0:top* "localhost" 23:46 03-Apr-19

This will re-attach the user to the tmux session 0 and the top command will reappear on the screen.

Another major difference between the tmux and screen commands is that the screen command only allows for the
use of full terminal sessions. Whereas the tmux command allows sessions to be viewed in multiple on-screen
windows. To enable two tmux sessions in side-by-side vertical windows, press Ctrl+B then the % key (Shift+5):
The new session can now be viewed along-side the first tmux session (session 0) running the top command. To
run a process in the new session, simply type the command or process to run at the prompt. For example, to view
the last five lines of the /etc/passwd file using the tail command in the new session:
To create a new session in a horizontal window, type Ctrl+B and the “ key (Shift+’):
Once again, the new session can be viewed along-side the other sessions. In the new session we will use the pgrep
command to search for the less command running in the previously created tmux session (session 1):
Notice in the example above, the PID in the output of the pgrep command (101) matches a PID in the top
command running in the vertical window on the left-hand side of the terminal. To exit out of a window, use the
exit command. Use the exit command in the two windows on the right-hand side of the terminal until only the
top command remains:
It is now possible to quit the top command by pressing the Q key.

To leave the tmux session and go back to the shell prompt, use the exit command:

Output Omitted...

sysadmin@localhost:~$ exit
[0] 0:bash* "localhost" 23:46 03-Apr-19

The other tmux session is still active, which can be confirmed with the tmux ls command again:

sysadmin@localhost:~$ tmux ls
1: 1 windows (created Wed Apr 3 23:09:57 2019) [80x23]
sysadmin@localhost:~$

To kill the other session without returning to it (which should be used carefully, so as not to corrupt any data), use
the following command with the target-session -t flag and the number of the session to be killed:

tmux kill-session
sysadmin@localhost:~$ tmux kill-session -t 1

The session or window indicator numeral should correspond to the session or window that is desired to be ended;
in this case it is the indicator numeral 1.
To verify that there are no longer any tmux sessions running, use the tmux ls command:

sysadmin@localhost:~$ tmux ls
no server running on /tmp/tmux-1001/default
sysadmin@localhost:~$

Although it is beyond the scope of this course, the tmux command can be almost infinitely modified to execute
more complex and interesting actions.
Key of Terms
&
When used with a process will immediately background the process or task in a terminal. This will allow
the terminal to be freed up for additional tasks.
Section 11.2.6
bg
A job control command that resumes the execution of a suspended process without bringing it to the
foreground.
Section 11.2.7
fg
A job control command that resumes execution of a suspended process by bringing it to the foreground.
Section 11.2.7
free
Command used to display the amount of free and used memory in the system. This utility will display both
the physical and swap memore on the system as well as the buffers used by the kernel.
Section 11.2.3 | Section 11.3
jobs
Command that lists all active jobs in the current terminal or shell.
Section 11.2.6
kill
Command used to terminate a process. There are specific signals that can terminate a process in different
ways. If no signal is provided the TERM signal will be sent to the process.
Section 11.2.8
killall
Command similar to kill, but killall will allow a user to terminate a process by name as opposed to ID.
Section 11.2.8
nice
Command used to change the priority of a process. The higher the nice value the lower the priority of a
process. Nice values range from -20 to 20.
Section 11.2.10
nohup
Command used to run a command immune to hangups, with output to a non-tty. If standard input is a
terminal, it can be redirected from /dev/null. If standard output is the terminal, append the ouptput to
nohup.out. This should be located in the user's home directory.
Section 11.2.9
pgrep
Command that parses through the running processes and looks for the specified names or other criteria of
processes.
Section 11.2.2
pkill
Sends a specified signal (SIGTERM by default) to each process instead of listing them on stdout.
Section 11.2.8
ps
Command used to report a snapshot of the current processes. Different options are available with ps to
report more specific information.
Section 11.2.1
renice
Command used to change the priority of a process while that process is running. The higher the value the
lower the priority.
Section 11.2.10
screen
A full-screen software program that can be used to multiplex a physical console between several processes
(typically interactive shells). It offers a user to open several separate terminal instances inside a one single
terminal window manager. The screen application is very useful, if you are dealing with multiple programs
from a command line interface and for separating programs from the terminal shell. It also allows you to
share your sessions with others users and detach/attach terminal sessions.
Section 11.4.1
tmux

Section 11.4.2
top
Command similar to ps, however top will display the curent real-time view of all running tasks and
processes.
Section 11.2.11
uptime
Command that will display how long a system has been running. uptime gives a one line display showing
the current time, how long ths system has been running, how many users are logged in, and the system load
averages for the pas 1, 5 and 15 minutes.
Section 11.3
watch

Section 11.2.3
LAB 11
11.0 Introduction
During this lab, you will learn how to manage processes. A process is a program that is running. As a regular user,
you should know how to start, pause, restart, and stop (kill) your own processes. You should also know how to list
processes and start processes with different priorities. Additionally, you will practice using utilities that allow
multiple processes inside a single shell.

As the administrator, you should also know how to monitor a system to determine which processes are using the
most CPU time and RAM

11.1 Step 1
The ps command can be used to list processes.

ps [OPTION]...

The ps command supports three styles of options:

 Traditional UNIX style short options that use a single hyphen in front of a character
 GNU style long options that use two hyphens in front of a word
 BSD style options that use no hyphens and single character options

Execute the ps command to display the commands that are running in your current shell:

ps
sysadmin@localhost:~$ ps
PID TTY TIME CMD
62 ? 00:00:00 bash
84 ? 00:00:00 ps
The Process ID in our virtual machine environment will likely be different than the one in the example.

11.2 Step 2
To view all of the processes on the system using non-BSD options, execute the following command:

ps -ef
sysadmin@localhost:~$ ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 18:38 ? 00:00:00 /bin/bash /init
syslog 9 1 0 18:38 ? 00:00:00 /usr/sbin/rsyslogd
root 13 1 0 18:38 ? 00:00:00 /usr/sbin/cron
root 15 1 0 18:38 ? 00:00:00 /usr/sbin/sshd
bind 25 1 0 18:38 ? 00:00:01 /usr/sbin/named -u bind
root 44 1 0 18:38 ? 00:00:00 /bin/login -f
sysadmin 62 44 0 18:38 ? 00:00:00 -bash
sysadmin 85 62 0 18:44 ? 00:00:00 ps -ef
Typically, there would be much more output from this command. The Linux environment provided for this lab
doesn't provide a full list of processes. Also, the processes and process numbers may vary, depending on what
programs have been executed previously

11.3 Step 3
To see all processes (processes belonging to all users and not limited to the current shell) as well as display the user
owners of the processes, using BSD options, execute the following command:

ps aux

sysadmin@localhost:~$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 4376 796 ? Ss 19:57 0:00 /sbin/init
root 7 0.0 0.0 78636 3748 ? S 19:58 0:00 /bin/login -f
syslog 10 0.0 0.0 191328 3828 ? Ssl 19:58 0:00 /usr/sbin/rsysl
root 14 0.0 0.0 28356 2696 ? Ss 19:58 0:00 /usr/sbin/cron
root 16 0.0 0.0 72296 3292 ? Ss 19:58 0:00 /usr/sbin/sshd
bind 26 0.0 0.0 1208108 40812 ? Ssl 19:58 0:01 /usr/sbin/named
sysadmin 62 0.0 0.0 19216 4256 ? S 19:58 0:00 -bash
sysadmin 89 0.0 0.0 34400 2828 ? R+ 20:29 0

11.4 Step 4
The watch command can be used to monitor recurring processes by using the following syntax:

watch [OPTION]... COMMAND

Use the watch command with the ps command to monitor running processes in the shell:

watch ps
sysadmin@localhost:~$ watch ps
Every 2.0s: ps localhost: Fri May 10 21:13:55 2019

PID TTY TIME CMD


62 ? 00:00:00 bash
91 ? 00:00:00 watch
182 ? 00:00:00 watch
183 ? 00:00:00 sh
184 ? 00:00:00 ps

Press Ctrl+C to stop the watch command:

CTRL+C
sysadmin@localhost:~$
11.5 Step 5
By default, the watch command executes commands every two seconds. To change the interval at which the watch
command will execute commands, use the -n option, followed by the specific interval desired.

watch -n # [COMMAND...]

Monitor changes in the /var/log/ndg/web.log log file, using the watch command to execute the tail command
every fifteen seconds:

Follow Along

To generate new log entries in the /var/log/ndg/web.log file, use the following command:

sysadmin@localhost:~$ start_log
Starting log...
watch -n 15 tail /var/log/ndg/web.log
sysadmin@localhost:~$ watch -n 15 tail /var/log/ndg/web.log
Every 15.0s: tail -20 /var/log/ndg/web.log localhost: Fri May 10 00:49:57 2019

192.0.2.91 [2019-05-13T00:49:51] 201 "GET /news/?search=cats"


192.0.2.52 [2019-05-13T00:49:52] 301 "GET /news/"
192.0.2.81 [2019-05-13T00:49:54] 200 "GET /news/?search=cats"
192.0.2.192 [2019-05-13T00:49:55] 301 "POST /news/"
192.0.2.96 [2019-05-13T00:49:56] 404 "POST /news/"

Press Ctrl+C to stop the watch command:

CTRL+C
sysadmin@localhost:~$

11.6 Step 6
The watch command can be used with the -d option to highlight the differences in the successive updates of a
command. To monitor the /var/log/ndg/web.log file, update the display of the log file’s contents in five seconds
increments, and highlight changes between each update, execute the following command:

watch -n 5 -d tail /var/log/ndg/web.log


sysadmin@localhost:~$ watch -n 5 -d tail /var/log/ndg/web.log
Every 5.0s: tail /var/log/ndg/web.log localhost: Fri May 10 18:46:37 2019

192.0.2.142 [2019-05-13T18:46:26] 404 "GET /news/"


192.0.2.22 [2019-05-13T18:46:27] 404 "GET /login/?redirect_to=/news"
192.0.2.73 [2019-05-13T18:46:28] 200 "POST /news/"
192.0.2.100 [2019-05-13T18:46:30] 301 "GET /news/puppy-and-cat"
192.0.2.243 [2019-05-13T18:46:31] 200 "GET /news/?search=cats"
192.0.2.46 [2019-05-13T18:46:32] 500 "GET /news/?search=puppies"
192.0.2.37 [2019-05-13T18:46:33] 404 "GET /news/puppy-and-cat"
192.0.2.92 [2019-05-13T18:46:35] 200 "GET /login/?redirect_to=/news"
192.0.2.51 [2019-05-13T18:46:36] 500 "GET /login/?redirect_to=/news"
192.0.2.43 [2019-05-13T18:46:36] 201 "POST /news/"
Press Ctrl+C to stop the watch command:

CTRL+C
sysadmin@localhost:~$

11.7 Step 7
Recall that scripts are plain text files which are interpreted by the shell and invoked at the prompt using the ./
syntax. The shell will run all commands in the script file and return the result to the terminal window.

Create a simple shell script called test.sh using redirection, which will display the string hello on the screen,
then pause for 100 seconds and then display goodbye on the screen by executing the following commands:

echo 'echo hello' > test.sh


echo 'sleep 100' >> test.sh
echo 'echo goodbye' >> test.sh
chmod a+x test.sh
sysadmin@localhost:~$ echo 'echo hello' > test.sh
sysadmin@localhost:~$ echo 'sleep 100' >> test.sh
sysadmin@localhost:~$ echo 'echo goodbye' >> test.sh
sysadmin@localhost:~$ chmod a+x test.sh

Use the nano text editor to view the newly created test.sh script file:

sysadmin@localhost:~$ nano test.sh


nano test.sh
GNU nano 2.9.3 test.sh

echo hello
sleep 100
echo goodbye

[ Constant cursor position display enabled ]


^G Get Help ^O Write Out ^W Where Is ^K Cut Text ^J Justify ^C Cur Pos
^X Exit ^R Read File ^\ Replace ^U Uncut Text^T To Linter ^_ Go To Line

Press Ctrl+X to exit the nano editor and return to the prompt:

CTRL+X
sysadmin@localhost:~$
11.8 Step 8
Execute the test.sh script created in the previous step:

./test.sh
sysadmin@localhost:~$ ./test.sh
hello
goodbye

11.9 Step 9
When one process starts another, the first process is referred to as the parent process, and the new process is called
a child process. So, another way of thinking of a foreground process is that when running in the foreground, a child
process doesn't allow any further commands to be executed in the parent process until the child process ends.

This process is running in the foreground, which means that no work can be done until the script is complete. To
cancel the script, press Ctrl+C:

CTRL+C
^C
sysadmin@localhost:~$

11.10 Step 10
When a command may take some time to execute, it may be better to have that command execute in the
background. When executed in the background, a child process releases control back to the parent process (the
shell, in this case) immediately, allowing the user to execute other commands.

To execute the script in the background, add an ampersand & character at the end of the command:

./test.sh &
sysadmin@localhost:~$ ./test.sh &
[4] 98
sysadmin@localhost:~$ hello

sysadmin@localhost:~$
You may need to press the Enter key to display the prompt.

As shown in the output, when executing commands in the background, after each command starts executing, it
outputs a job number, followed by a space, and then the process identification number (PID). These numbers are
used for controlling the process. The ./test.sh process in the example above has a job number of 4 and a PID of
98.

The Process ID in our virtual machine environment will likely be different than the one in the example.

The test.sh program is still running in the background and, in 100 seconds, the second echo command will
display the string goodbye:

sysadmin@localhost:~$ goodbye
[1]+ Done ./test.sh
sysadmin@localhost:~$
You may need to press the Enter key to display the prompt.
The job number of a process is sometimes followed by a minus - or a plus + character. The plus + character
denotes the last process that was started, while the minus - character denotes a process started prior to the latest
one.

11.11 Step 11
While there are still background processes being run in the terminal, they can be displayed by using the jobs
command. Execute the test.sh script file and use the jobs command to show the process running in the
background:

./test.sh &
jobs
sysadmin@localhost:~$ ./test.sh &
[1] 100
sysadmin@localhost:~$ hello
sysadmin@localhost:~$ jobs
[1]+ Running ./test.sh &
sysadmin@localhost:~$

11.12 Step 12
A command that has been paused or sent to the background can then be returned to the foreground using the fg
command. Use the fg command to send the ./test.sh process to the foreground:

fg
sysadmin@localhost:~$ fg
./test.sh
_

Note that the terminal is now occupied by the ./test.sh process. To put the process in the background again, use
Ctrl+Z to stop the ./text.sh process, then execute the bg command:

bg
Enter
^Z
[1]+ Stopped ./test.sh
sysadmin@localhost:~$ bg
[1]+ ./test.sh &
sysadmin@localhost:~$ goodbye
[1]+ Done ./test.sh
11.13 Step 13
A signal is a message that is sent to a process to tell the process to take some sort of action, such as stop, restart, or
pause. There are several commands that will allow you to specify a signal to send to a process; the kill command
is the most commonly used. The syntax for the kill command looks like the following:

kill [OPTIONS]... <PID>

When sending a signal, specify one or more processes to send the signal to. There are numerous techniques to
specify the process or processes. The more common techniques include:

 Specifying the process identifier (PID)


 Using the % (percent sign) prefix to the job number

Execute the ./test.sh script file in the background, then execute the following command to stop the background
process:

./test.sh &
Enter
kill %1
jobs
sysadmin@localhost:~$ ./test.sh &
sysadmin@localhost:~$ kill %1
sysadmin@localhost:~$ jobs
[1]+ Terminated ./test.sh
sysadmin@localhost:~$

11.14 Step 14
The killall command can also be used to terminate one or more processes. The following demonstrates syntax
that can be used for the killall command:

killall [OPTIONS]... NAME

Start five sleep processes and then stop them all with a single command, as shown below:

sleep 100 &


sleep 100 &
sleep 100 &
sleep 100 &
sleep 100 &
jobs
killall sleep
sysadmin@localhost:~$ sleep 100 &
[1] 106
sysadmin@localhost:~$ sleep 100 &
[2] 107
sysadmin@localhost:~$ sleep 100 &
[3] 108
sysadmin@localhost:~$ sleep 100 &
[4] 109
sysadmin@localhost:~$ sleep 100 &
[5] 110
sysadmin@localhost:~$ jobs
[1] Running sleep 100 &
[2] Running sleep 100 &
[3] Running sleep 100 &
[4]- Running sleep 100 &
[5]+ Running sleep 100 &
sysadmin@localhost:~$ killall sleep
[1] Terminated sleep 100
[2] Terminated sleep 100
[3] Terminated sleep 100
[4]- Terminated sleep 100
[5]+ Terminated sleep 100
sysadmin@localhost:~$

11.15 Step 15
A user can influence the priority that will be assigned to a process by setting a value of something called niceness.
The higher the niceness value, the lower the priority that will be assigned to a process.

To set the initial niceness of a command, use the nice command as a prefix to the command to execute. The -n
option indicates the desired niceness value.

In order to demonstrate the nice and renice commands in our virtual environment, you must switch to the root
account.

The su command used below allows a regular user to become the root user temporarily. The user is required to
enter the root account password when prompted. To use the su command in our virtual environment, enter the
root password netlab123.

Start the sleep command with a lower priority and then confirm with the -l option to the ps command:

su - root
nice -n 10 sleep 200 &
ps -l
sysadmin@localhost:~$ su - root
Password:
root@localhost:~# nice -n 10 sleep 200 &
[1] 127
root@localhost:~# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 1 0 0 80 0 - 4594 wait ? 00:00:00 init
4 S 0 44 1 0 80 0 - 19659 - ? 00:00:00 login
4 S 0 112 62 0 80 0 - 15021 - ? 00:00:00 su
4 S 0 113 112 0 80 0 - 4805 wait ? 00:00:00 bash
0 S 0 127 113 0 90 10 - 1133 hrtime ? 00:00:00 sleep
0 R 0 128 113 0 80 0 - 6486 - ? 00:0
11.16 Step 16
You can use the renice command to change an existing process priority. Enter the commands below, using the
PID assigned to your sleep process.

renice -n 15 -p PID
ps -l
root@localhost:~# renice -n 15 -p 138
138 (process ID) old priority 10, new priority 15
root@localhost:~# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 1 0 0 80 0 - 4594 wait ? 00:00:00 init
4 S 0 44 1 0 80 0 - 19659 - ? 00:00:00 login
4 S 0 112 62 0 80 0 - 15021 - ? 00:00:00 su
4 S 0 113 112 0 80 0 - 4805 wait ? 00:00:00 bash
0 S 0 138 113 0 95 15 - 1133 hrtime ? 00:00:00 sleep
0 R 0 141 113 0 80 0 - 6486 - ? 00:00:00 ps

Notice that following the renice, the process priority has been changed from 10 to 15.

You must enter the renice command using your sleep process's PID number, which will likely be different than
the example above.

11.17 Step 17
The remaining steps of this lab may be performed from the sysadmin account. Execute the exit command to
switch back to the sysadmin account. Next, enter the uptime command to display basic process information,
including the load average of the system:

exit
uptime
root@localhost:~# exit
logout
sysadmin@localhost:~$ uptime
19:20:26 up 28 days, 21:00, 1 user, load average: 0.46, 0.68, 0.65
Your output will likely be different than above for this command and the next few steps since the values represent
a dynamic running system.

11.18 Step 18
Execute the following command to display basic system memory statistics:

free
sysadmin@localhost:~$ free
total used free shared buff/cache available
Mem: 132014640 45424376 70450804 6916 16139460 85961324
Swap: 134196220 0 134196220
11.19 Step 19
To display a real-time view of running processes, execute the following command:

top
top - 19:23:25 up 28 days, 21:03, 1 user, load average: 0.27, 0.52, 0.60
Tasks: 8 total, 1 running, 7 sleeping, 0 stopped, 0 zombie
%Cpu(s): 3.1 us, 1.3 sy, 0.0 ni, 95.4 id, 0.0 wa, 0.0 hi, 0.2 si, 0.0 st
KiB Mem : 13201464+total, 70451344 free, 45423848 used, 16139452 buff/cache
KiB Swap: 13419622+total, 13419622+free, 0 used. 85961848 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND


1 root 20 0 18376 2900 2628 S 0.0 0.0 0:00.09 init
9 syslog 20 0 191328 5876 3324 S 0.0 0.0 0:00.04 rsyslogd
13 root 20 0 28356 2668 2400 S 0.0 0.0 0:00.00 cron
15 root 20 0 72296 3244 2500 S 0.0 0.0 0:00.00 sshd
25 bind 20 0 1076256 39948 7088 S 0.0 0.0 0:01.40 named
44 root 20 0 78636 3592 3040 S 0.0 0.0 0:00.00 login
62 sysadmin 20 0 19356 4200 2968 S 0.0 0.0 0:00.06 bash
144 sysadmin 20 0 38696 3168 2724 R 0.0 0.0 0:00.00 top

Type Q to exit the top command and return to the prompt:

q
sysadmin@localhost:~$

11.20 Step 20
Multi-session command line utilities allow users to manage multiple processes inside a single Bash shell
environment. The screen and tmux commands allow the user to start processes in a session that can be detached
while still running, then re-attached and managed by various methods.

The screen command allows for multiple processes to run within separate sessions under a single terminal. Start a
screen session by executing the following command:

screen
Enter
sysadmin@localhost:~$ screen
GNU Screen version 4.06.02 (GNU) 23-Oct-17

Copyright (c) 2015-2017 Juergen Weigert, Alexander Naumov, Amadeusz Slawinski


Copyright (c) 2010-2014 Juergen Weigert, Sadrul Habib Chowdhury
Copyright (c) 2008-2009 Juergen Weigert, Michael Schroeder, Micah Cowan,
Sadrul Habib Chowdhury
Copyright (c) 1993-2007 Juergen Weigert, Michael Schroeder
Copyright (c) 1987 Oliver Laumann

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program (see the file COPYING); if not, see http://www.gnu.org/licenses/,
or contact Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,

[Press Space for next page; Return to end.]

11.21 Step 21
Now, let’s run the top command in the current screen session:

top
sysadmin@localhost:~$ top
top - 05:27:00 up 122 days, 6:24, 2 users, load average: 2.38, 2.60, 2.38
Tasks: 11 total, 1 running, 10 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.8 us, 7.5 sy, 0.0 ni, 89.9 id, 0.0 wa, 0.0 hi, 1.7 si, 0.0 st
KiB Mem : 98991216 total, 35472596 free, 41509716 used, 22008908 buff/cache
KiB Swap: 10064691+total, 10062806+free, 18844 used. 56920812 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND


1 root 20 0 4376 720 660 S 0.0 0.0 0:00.14 init
7 root 20 0 78636 3756 3208 S 0.0 0.0 0:00.00 login
10 syslog 20 0 191328 3668 3168 S 0.0 0.0 0:00.15 rsyslogd
14 root 20 0 28356 2660 2396 S 0.0 0.0 0:00.00 cron
16 root 20 0 72296 3280 2532 S 0.0 0.0 0:00.00 sshd
26 bind 20 0 1274684 42484 7332 S 0.0 0.0 0:03.47 named
62 sysadmin 20 0 19216 4232 3028 S 0.0 0.0 0:00.03 bash
112 sysadmin 20 0 28752 3016 2444 S 0.0 0.0 0:00.02 screen
113 sysadmin 20 0 19300 4180 3064 S 0.0 0.0 0:00.01 bash
123 sysadmin 20 0 38696 3228 2788 R 0.0 0.0 0:00.28 top
129 sysadmin 20 0 28492 2692 2440 S 0.0 0.0 0:00.00 screen

11.22 Step 22
A useful feature of the screen command is the ability to detach a session, then re-attach it later. To attach and
detach a screen session, you will need to use the screen command keys. All screen commands start with a prefix
key, the keystrokes Ctrl+A, followed by a command key to make an action happen.

Press the prefix key Ctrl+A and then the detach D command key, which detaches the current screen session and
returns the user to the shell prompt.

CTRL+a
d
[detached from 112.console.localhost]
sysadmin@localhost:~$
11.23 Step 23
To list currently running screen sessions, run the screen command with the list -l option:

screen -list
sysadmin@localhost:~$ screen -list
There is a screen on:
112.console.localhost (05/14/19 05:14:50) (Detached)
1 Socket in /run/screen/S-sysadmin.

In the output above, the status of the screen session that is running the top command is (Detached).

11.24 Step 24
You can now re-attach the session by using the resume -r option with either the PID of the session or by the name
of the session:

screen -r PID
sysadmin@localhost:~$ screen -r 112

top - 07:12:23 up 122 days, 8:09, 2 users, load average: 1.54, 1.78, 1.72
Tasks: 11 total, 1 running, 10 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.2 us, 3.2 sy, 0.0 ni, 95.6 id, 0.0 wa, 0.0 hi, 0.1 si, 0.0 st
KiB Mem : 98991216 total, 36477672 free, 40637988 used, 21875560 buff/cache
KiB Swap: 10064691+total, 10062806+free, 18844 used. 57793424 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND


1 root 20 0 4376 720 660 S 0.0 0.0 0:00.14 init
7 root 20 0 78636 3756 3208 S 0.0 0.0 0:00.00 login
10 syslog 20 0 191328 3668 3168 S 0.0 0.0 0:00.16 rsyslogd
14 root 20 0 28356 2660 2396 S 0.0 0.0 0:00.00 cron
16 root 20 0 72296 3280 2532 S 0.0 0.0 0:00.00 sshd
26 bind 20 0 1274684 42528 7332 S 0.0 0.0 0:04.13 named
62 sysadmin 20 0 19216 4232 3028 S 0.0 0.0 0:00.03 bash
112 sysadmin 20 0 28752 3016 2444 S 0.0 0.0 0:00.35 screen
113 sysadmin 20 0 19300 4180 3064 S 0.0 0.0 0:00.01 bash
123 sysadmin 20 0 38696 3228 2788 R 0.0 0.0 0:02.92 top
139 sysadmin 20 0 28492 2704 2448 S 0.0 0.0 0:00.00 screen

Type Q to exit the top command:

11.25 Step 25
To exit the screen command, use the exit command:

exit
sysadmin@localhost:~$ exit
[screen is terminating]
11.26 Step 26
The tmux command, short for terminal multiplexer, allows for multiple terminals to be opened and viewed on the
same screen.

In this step, you will start a tmux session, using the new-session option, and run the top command in the current
tmux session:

tmux new-session 'top'


sysadmin@localhost:~$ tmux new-session 'top'
top - 14:31:46 up 122 days, 15:29, 2 users, load average: 1.45, 1.95, 1.78
Tasks: 10 total, 1 running, 9 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.2 us, 4.6 sy, 0.0 ni, 95.2 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 98991216 total, 36744576 free, 40583028 used, 21663616 buff/cache
KiB Swap: 10064691+total, 10062806+free, 18844 used. 57847800 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND


1 root 20 0 4376 740 680 S 0.0 0.0 0:00.14 init
7 root 20 0 78636 3636 3084 S 0.0 0.0 0:00.00 login
10 syslog 20 0 191328 3696 3192 S 0.0 0.0 0:00.16 rsyslogd
14 root 20 0 28356 2832 2568 S 0.0 0.0 0:00.00 cron
16 root 20 0 72296 3304 2556 S 0.0 0.0 0:00.00 sshd
26 bind 20 0 1208628 41252 7084 S 0.0 0.0 0:02.18 named
62 sysadmin 20 0 19216 4260 3060 S 0.0 0.0 0:00.03 bash
82 sysadmin 20 0 18460 3020 2700 S 0.0 0.0 0:00.00 tmux: clie+
84 sysadmin 20 0 27096 3700 3108 S 0.0 0.0 0:00.00 tmux: serv+
85 sysadmin 20 0 38692 3128 2680 R 0.0 0.0 0:00.02 top

[0] 0:top* "localhost" 14:31 14-May-19

11.27 Step 27
Detach from the current tmux session, which is running the top command, by pressing the Ctrl+B key sequence
and then the D key to return to the shell prompt again:

CTRL+b
d
[detached (from session 0)]
sysadmin@localhost:~$
11.28 Step 28
Confirm that tmux session 0 still exists by executing the following command:

tmux ls
sysadmin@localhost:~$ tmux ls
0: 1 windows (created Tue May 14 14:31:03 2019) [80x23]

11.29 Step 29
To re-attach the running tmux session 0, use the tmux attach command with the target-session -t flag:

tmux attach -t 0
sysadmin@localhost:~$ tmux attach -t 0
top - 15:53:17 up 122 days, 16:50, 2 users, load average: 2.49, 2.17, 1.87
Tasks: 10 total, 1 running, 9 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.8 us, 4.2 sy, 0.0 ni, 93.1 id, 0.0 wa, 0.0 hi, 1.9 si, 0.0 st
KiB Mem : 98991216 total, 35068960 free, 42218736 used, 21703524 buff/cache
KiB Swap: 10064691+total, 10062806+free, 18844 used. 56211032 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND


1 root 20 0 4376 740 680 S 0.0 0.0 0:00.14 init
7 root 20 0 78636 3636 3084 S 0.0 0.0 0:00.00 login
10 syslog 20 0 191328 3696 3192 S 0.0 0.0 0:00.16 rsyslogd
14 root 20 0 28356 2832 2568 S 0.0 0.0 0:00.00 cron
16 root 20 0 72296 3304 2556 S 0.0 0.0 0:00.00 sshd
26 bind 20 0 1208628 41344 7084 S 0.0 0.0 0:02.88 named
62 sysadmin 20 0 19216 4260 3060 S 0.0 0.0 0:00.04 bash
84 sysadmin 20 0 27096 3700 3108 S 0.0 0.0 0:00.71 tmux: serv+
85 sysadmin 20 0 38692 3128 2680 R 0.0 0.0 0:01.94 top
89 sysadmin 20 0 18460 3028 2708 S 0.0 0.0 0:00.00 tmux: clie+

[0] 0:top* "localhost" 15:53 14-May-19


11.30 Step 30
To enable a new terminal in the tmux session running in a side-by-side vertical window, press Ctrl+B then %
(Ctrl and b, then Shift+5):

Ctrl+b
%
top - 06:22:29 up 99 days, 8:05, 3 use│sysadmin@localhost:~$
Tasks: 11 total, 1 running, 10 sleep│
%Cpu(s): 0.3 us, 0.3 sy, 0.0 ni, 99.4│
KiB Mem : 13201464+total, 10099014+free,│
KiB Swap: 13419622+total, 13417832+free,│

PID USER PR NI VIRT RES │
1 root 20 0 4376 744 │
7 root 20 0 78636 3656 │
10 syslog 20 0 191328 3864 │
14 root 20 0 28356 2792 │
16 root 20 0 72296 3268 │
26 bind 20 0 944924 39572 │
69 sysadmin 20 0 19216 4152 │
94 sysadmin 20 0 27096 3724 │
95 sysadmin 20 0 38692 3216 │
99 sysadmin 20 0 18460 3040 │
100 sysadmin 20 0 19300 4244 │





[0] 0:bash* "localhost" 06:22 27-Jun-19
11.31 Step 31
In the new session, we will use the following command to see the top process running in the previously created
tmux session (session 0):

ps a
top - 06:23:26 up 99 days, 8:06, 3 use│sysadmin@localhost:~$ ps a
Tasks: 11 total, 1 running, 10 sleep│ PID TTY STAT TIME COMMAND
%Cpu(s): 0.2 us, 0.2 sy, 0.0 ni, 99.6│ 1 ? Ss 0:00 /sbin/init
KiB Mem : 13201464+total, 10099204+free,│ 7 ? S 0:00 /bin/login -
KiB Swap: 13419622+total, 13417832+free,│ 69 ? S 0:00 -bash
│ 95 pts/0 Ss+ 0:00 top
PID USER PR NI VIRT RES │ 99 ? S+ 0:00 tmux attach
1 root 20 0 4376 744 │ 100 pts/1 Ss 0:00 -bash
7 root 20 0 78636 3656 │ 112 pts/1 R+ 0:00 ps a
10 syslog 20 0 191328 3864 │sysadmin@localhost:~$
14 root 20 0 28356 2792 │
16 root 20 0 72296 3268 │
26 bind 20 0 944924 39572 │
69 sysadmin 20 0 19216 4152 │
94 sysadmin 20 0 27096 3724 │
95 sysadmin 20 0 38692 3216 │
99 sysadmin 20 0 18460 3040 │
100 sysadmin 20 0 19300 4244 │





[0] 0:bash* "localhost" 06:23 27-Jun-19

Notice in the output of the ps a command, the PID for the top process (85) matches the same process in the top
command running in the vertical window on the left.
11.32 Step 32
To exit out of a window, use the exit command. Use the following command to exit out of the terminal in the
window on the right:

exit
top - 06:23:26 up 99 days, 8:06, 3 use│sysadmin@localhost:~$ ps a
Tasks: 11 total, 1 running, 10 sleep│ PID TTY STAT TIME COMMAND
%Cpu(s): 0.2 us, 0.2 sy, 0.0 ni, 99.6│ 1 ? Ss 0:00 /sbin/init
KiB Mem : 13201464+total, 10099204+free,│ 7 ? S 0:00 /bin/login -
KiB Swap: 13419622+total, 13417832+free,│ 69 ? S 0:00 -bash
│ 95 pts/0 Ss+ 0:00 top
PID USER PR NI VIRT RES │ 99 ? S+ 0:00 tmux attach
1 root 20 0 4376 744 │ 100 pts/1 Ss 0:00 -bash
7 root 20 0 78636 3656 │ 112 pts/1 R+ 0:00 ps a
10 syslog 20 0 191328 3864 │sysadmin@localhost:~$ exit
14 root 20 0 28356 2792 │
16 root 20 0 72296 3268 │
26 bind 20 0 944924 39572 │
69 sysadmin 20 0 19216 4152 │
94 sysadmin 20 0 27096 3724 │
95 sysadmin 20 0 38692 3216 │
99 sysadmin 20 0 18460 3040 │
100 sysadmin 20 0 19300 4244 │





[0] 0:bash* "localhost" 06:23 27-Jun-19

Quit the top command by pressing the Q key:

q
sysadmin@localhost:~$

11.33 Step 33
Use the exit command to leave the tmux session and go back to the original shell prompt:

exit
sysadmin@localhost:~$ exit
logout

Verify that there are no tmux sessions running:

tmux ls
sysadmin@localhost:~$ tmux ls
no server running on /tmp/tmux-1001/default
NDG Introduction to Linux I - Chapter 12: Archive
Commands

12.1 Introduction
Linux distributions provide several different sets of commands for compressing and archiving files and directories.
This chapter will describe their advantages and disadvantages as well as their usefulness in making backup copies
of files and directories efficiently.

File archiving is used when one or more files need to be transmitted or stored as efficiently as possible. There are
two fundamental aspects which this chapter explores:

 Archiving: Combines multiple files into one, which eliminates the overhead in individual files and makes it
easier to transmit.
 Compression: Makes the files smaller by removing redundant information.

Consider This

Files can be compressed individually, or multiple files can be combined into a single archive and then subsequently
compressed. The latter is still referred to as archiving.

When an archive is decompressed, and one or more files are extracted, this is called un-archiving.
More sophisticated types of copying, using the dd and cpio commands, will also be covered. These commands,
while more complex, offer powerful features.

12.2 The gzip and gunzip Commands


Compression reduces the amount of data needed to store or transmit a file while storing it in such a way that the
file can be restored. A file with human-readable text might have frequently used words replaced by something
smaller, or an image with a solid background might represent patches of that color by a code. The compressed
version of the file is not typically viewed or utilized; instead, it is uncompressed before use.

The gzip command is used to create a compressed file. Likewise, the gunzip command is used to view the
contents of a compressed file, as well as extract those contents.

gzip [OPTION]... [FILE]...


gunzip [OPTION]... [FILE]...

Important

The gzip command should be used with caution since its default behavior is to replace the original file specified
with a compressed version.

In the following example, the red.txt file is replaced with the compressed red.txt.gz file after using the gzip
command:

sysadmin@localhost:~$ cd Documents/
sysadmin@localhost:~/Documents$ ls red*
red.txt
sysadmin@localhost:~/Documents$ gzip red.txt
sysadmin@localhost:~/Documents$ ls red*
red.txt.gz

To avoid replacing the original version of a file when using the gzip command, use the -c option. This causes the
gzip command to send the compressed data to standard output, and given that the output of the gzip command is
binary data, it will need to be redirected into a file. Capture the output of the gzip command and redirect it into a
file, using the greater-than > character:
sysadmin@localhost:~/Documents$ gzip -c numbers.txt > numbers.txt.gz
sysadmin@localhost:~/Documents$ ls numbers*
numbers.txt numbers.txt.gz

Using the gzip command with the -c option and redirection created a gzipped file while leaving the original file
intact. This can be useful as the gzipped file can be moved to an archive directory location while preserving the
original file in its original location.

The gunzip command reverses what gzip does, so files will be uncompressed, and the gzipped file will be
replaced with the uncompressed file:

sysadmin@localhost:~/Documents$ gunzip red.txt


sysadmin@localhost:~/Documents$ ls red*
red.txt

To list the amount of compression of an existing file, use the -l option with the gunzip command:

sysadmin@localhost:~/Documents$ gunzip -l numbers.txt.gz


compressed uncompressed ratio uncompressed_name
42 10 -20.0% numbers.txt

Consider This

The gunzip command is just a script that calls gzip with different parameters.

While the gzip command supports recursion with the -r option, by default, it attempts to replace the original file
with the gzipped file. This leads to errors when the files being compressed are not owned by the user that tries to
gzip them:

sysadmin@localhost:~/Documents$ gzip -r /run


gzip: /run/mount/utab.gz: Permission denied
gzip: /run/utmp.gz: Permission denied
gzip: /run/sshd.pid.gz: Permission denied
gzip: /run/crond.pid.gz: Permission denied
gzip: /run/named/session.key: Permission denied
gzip: /run/named/named.pid.gz: Permission denied
gzip: /run/motd.dynamic.gz: Permission denied
gzip: /run/crond.reboot: Permission denied
gzip: /run/rsyslogd.pid.gz: Permission denied
gzip: /run/systemd/container.gz: Permission denied
gzip: /run/systemd/resolve/stub-resolv.conf.gz: Permission denied
gzip: /run/shm: Too many levels of symbolic links
gzip: /run/initctl: Too many levels of symbolic links
gzip: /run/init.upgraded.gz: Permission denied

In order to be able to compress files with the gzip command recursively, a user needs to have the correct
permissions on the directories the files are in. Typically, this is limited to directories within the user's own home
directory.

For example, using the gzip command recursively on the ~/example directory, it would be successful in replacing
regular files with gzip archive files:

sysadmin@localhost:~/Documents$ cd
sysadmin@localhost:~$ mkdir example
sysadmin@localhost:~$ touch example/one example/two example/three
sysadmin@localhost:~$ ls example/
one three two
sysadmin@localhost:~$ gzip -r example
sysadmin@localhost:~$ ls example/
one.gz three.gz two.gz

The gunzip command can also work recursively, assuming the user has the correct permissions. As it works, it
removes the .gz extension from each file:

sysadmin@localhost:~$ gunzip -r example/


sysadmin@localhost:~$ ls example/
one three two

Note

Permissions can have an impact on file management commands, such as the gzip and gunzip commands. To gzip
or gunzip a file within a directory, a user must have the write and execute permissions on a directory as well as the
read permission on the file. Regular users typically only have this type of permission in their home directory and
its subdirectories.

The ls command can be used to view the permissions of a directory prior to compressing files. For example, to
view the permissions of the /run directory, use the ls command with the -l and -d options:

sysadmin@localhost:~$ ls -ld /run


drwxr-xr-x 1 root root 4096 Mar 26 21:22 /run

The output above shows that the /run directory is owned by the user root and the group root. The permissions
for others are read and execute, but not write:

drwxr-xr-x 1 root root 4096 Mar 26 21:22 /run

The absence of the write permission for all users aside from the root user prevents regular users from compressing
files within this directory.

Permissions will be covered in greater detail later in the course.

12.3 The zcat Command


The zcat command is used to display the contents of a compressed file without actually uncompressing it. It does
this by expanding the file contents to standard output rather than creating a new uncompressed file from a
compressed archive created by the tar or gzip commands. Its effect is identical to running the gzip -c command:

zcat [OPTION]... [FILE]...

First, create a compressed file with the gzip command, then view its contents with the zcat command:

sysadmin@localhost:~$ cd Documents
sysadmin@localhost:~/Documents$ gzip red.txt
sysadmin@localhost:~/Documents$ ls
School alpha-third.txt hidden.txt numbers.txt spelling.txt
Work alpha.txt letters.txt os.csv words
adjectives.txt animals.txt linux.txt people.csv
alpha-first.txt food.txt longfile.txt profile.txt
alpha-second.txt hello.sh newhome.txt red.txt.gz
sysadmin@localhost:~/Documents$ zcat red.txt.gz
red
reef
rot
reeed
rd
rod
roof
reed
root
reel
read

The zcat command can also be used to view the contents of multiple compressed files:

sysadmin@localhost:~/Documents$ gzip letters.txt


sysadmin@localhost:~/Documents$ zcat red.txt.gz letters.txt.gz
red
reef
rot
reeed
rd
rod
roof
reed
root
reel
read
a
b
c
d
e

Using the -f option with the zcat command will enable viewing of normal uncompressed files:

sysadmin@localhost:~/Documents$ zcat -f newhome.txt


Thanks for purchasing your new home!!

**Warning** it may be haunted.

There are three bathrooms.

**Beware** of the ghost in the bedroom.

The kitchen is open for entertaining.

**Caution** the spirits don't like guests.

Good luck!!!

File properties can be displayed with the -l option:

sysadmin@localhost:~/Documents$ zcat -l red.txt.gz


compressed uncompressed ratio uncompressed_name
60 51 33.3% red.txt
12.4 The bzip2 and bunzip2 Commands
The bzip2 and bunzip2 commands work in a nearly identical fashion to the gzip and gunzip commands.
However, while the gzip command uses the Lempel-Ziv data compression algorithm, the bzip utilities use a
different compression algorithm called Burrows-Wheeler block sorting, that can compress files smaller than gzip at
the expense of more CPU time. These files can be recognized because they have a .bz or .bz2 extension instead of
a .gz extension.

bzip2 [OPTION]... [FILE]...


bunzip2 [OPTION]... [FILE]...

When a new compressed file is created from an existing file with the bzip2 command, the .bz2 extension is added
to the file name. Using the verbose -v option will cause bzip2 to report the compression ratio after it has finished.
The gzip command also supports the -v option, so a file can be compressed using both commands and the
compression ratio compared to determine which command uses a better compression technique for that specific
file.

sysadmin@localhost:~/Documents$ cd
sysadmin@localhost:~$ ls example/
one three two
sysadmin@localhost:~$ bzip2 -v example/*
example/one: no data compressed.
example/three: no data compressed.
example/two: no data compressed.
sysadmin@localhost:~$ ls example/
one.bz2 three.bz2 two.bz2

Important

The bzip2 command should be used with caution since its default behavior is to replace the original file specified
with a compressed version.

Note that there was no data to compress in the empty one, two, and three files.

One way to demonstrate the difference in compression between gzip and bzip2 is to compress the same file using
both commands with the verbose -v option. The -v option gives a verbose output so you can see how the file was
processed:

sysadmin@localhost:~/Documents$ ls -l words
-rw-r--r-- 1 sysadmin sysadmin 971578 Apr 24 16:24 words
sysadmin@localhost:~/Documents$ gzip -v words
words: 73.2% -- replaced with words.gz
sysadmin@localhost:~/Documents$ ls -l words.gz
-rw-r--r-- 1 sysadmin sysadmin 259983 Apr 24 16:24 words.gz
sysadmin@localhost:~/Documents$ gunzip words.gz
sysadmin@localhost:~/Documents$ bzip2 -v words
words: 2.812:1, 2.845 bits/byte, 64.43% saved, 971578 in, 345560 out.
sysadmin@localhost:~/Documents$ ls -l words.bz2
-rw-r--r-- 1 sysadmin sysadmin 345560 Apr 24 16:24 words.bz2
sysadmin@localhost:~/Documents$ bunzip words.bz2

Just like gunzip, the bunzip2 command uncompresses the file and removes the .bz2 extension. For example, the
command below will uncompress the example directory and its contents previously compressed using the bunzip2
command:

sysadmin@localhost:~$ bunzip2 -v example/*


example/one.bz2: done
example/three.bz2: done
example/two.bz2: done
sysadmin@localhost:~$ ls example/
one three two

The bzip2 command doesn't have an option -r to do recursion, so a wildcard can be used to match multiple files,
as demonstrated in the examples above. The bzip2 command does have the -c option available to send the data to
standard output, so it can be redirected to a new file:

sysadmin@localhost:~$ cd Documents
sysadmin@localhost:~/Documents$ bzip2 -cv alpha.txt > alpha.txt.bz2
alpha.txt: 1.781:1, 4.492 bits/byte, 43.85% saved, 390 in, 219 out.
sysadmin@localhost:~/Documents$ ls -l alpha.*
-rw-r--r-- 1 sysadmin sysadmin 390 Apr 24 16:24 alpha.txt
-rw-rw-r-- 1 sysadmin sysadmin 219 May 9 18:07 alpha.txt.bz2

12.5 The bzcat Command


The bzcat command prints the content of specified files compressed with the bzip2 command to the standard
output.

bzcat [OPTION]... [FILE]...

In the example below, the bzip2 command is used to compress the profile.txt file, and the bzcat command is
used to view the compressed file:

sysadmin@localhost:~/Documents$ bzip2 profile.txt


sysadmin@localhost:~/Documents$ bzcat profile.txt.bz2
Hello my name is Joe.
I am 37 years old.
3121991
My favorite food is avocados.
I have 2 dogs.
123456789101112
12.6 The xz and unxz Commands
Another archival tool similar to gzip and bzip2 is the xz command.

xz [OPTION]... [FILE]...

To compress a group of files individually, use the xz command with the -z option. Compression is the default
operation mode, and therefore if the xz command is run with no options, the -z option is implied.

In the example below, the glob asterisk * character is used to compress all files, with the exception of directories,
in the current directory:

sysadmin@localhost:~/Documents$ xz -z *
xz: School: Is a directory, skipping
xz: Work: Is a directory, skipping
xz: words.xz: Cannot set the file group: Operation not permitted
sysadmin@localhost:~/Documents$ ls
School alpha.txt.xz longfile.txt.xz red.txt.bz.xz
Work animals.txt.xz newhome.txt.xz red.txt.gz.xz
adjectives.txt.xz food.txt.xz numbers.txt.gz.xz spelling.txt.xz
alpha-first.txt.xz hello.sh.xz numbers.txt.xz words.xz
alpha-second.txt.xz hidden.txt.xz os.csv.xz
alpha-third.txt.xz letters.txt.gz.xz people.csv.xz
alpha.txt.bz2.xz linux.txt.xz profile.txt.bz2.xz

The -d option can be used with the xz command to uncompress the files just as easily:

sysadmin@localhost:~/Documents$ xz -d *
sysadmin@localhost:~/Documents$ ls
School alpha-third.txt hidden.txt numbers.txt spelling.txt
Work alpha.txt letters.txt os.csv words
adjectives.txt animals.txt linux.txt people.csv
alpha-first.txt food.txt longfile.txt profile.txt
alpha-second.txt hello.sh newhome.txt red.txt

Another method of uncompressing files compressed using the xz command is to use the unxz command. Using
unxz to uncompress a file is very similar to using gunzip because it uses similar syntax. When a file is
uncompressed using the unxz command, the extension .xz is removed. To demonstrate, the xz command is used to
compress a copy of the words file:

sysadmin@localhost:~/Documents$ xz words
sysadmin@localhost:~/Documents$ ls -l words.xz
-rw-r--r-- 1 sysadmin sysadmin 198756 Dec 9 23:35 words.xz

Next, the unxz command is used to uncompress the words.xz file:

sysadmin@localhost:~/Documents$ unxz words.xz


sysadmin@localhost:~/Documents$ ls -l words
-rw-r--r-- 1 sysadmin sysadmin 971578 Dec 9 23:35 words

There are a huge number of options for the xz command, some relating to the compression ratio. Keep in mind
when using xz that the more aggressive the compression, the harder the processor will have to work.
12.7 The xzcat Command
The xzcat command is used to print the contents of files compressed with the xz command to standard output on
the terminal without uncompressing the target file.

xzcat [FILE]...

In the following example, the xz command is used to compress the animals.txt file, and then the xzcat
command is used to view the file:

sysadmin@localhost:~/Documents$ xz animals.txt
sysadmin@localhost:~/Documents$ ls
School alpha-third.txt hidden.txt numbers.txt words
Work alpha.txt letters.txt.gz os.csv
adjectives.txt animals.txt.xz linux.txt people.csv
alpha-first.txt food.txt longfile.txt red.txt.gz
alpha-second.txt hello.sh newhome.txt spelling.txt
sysadmin@localhost:~/Documents$ xzcat animals.txt.xz
1 retriever
2 badger
3 bat
4 wolf
5 eagle

As demonstrated in the output above, when a new compressed file is created, the .xz extension is added to the file
name.

12.8 The tar Command


An archive is a single file, which consists of many files, though not necessarily compressed. The tar command is
typically used to make archives within Linux. These tar archive files, sometimes called tarballs, were originally
used to backup data onto magnetic tape. Tar is derived from the words "tape archive".

While the primary purpose of the tar command is to merge multiple files into a single file, it is capable of many
different operations, and there are numerous options. The functionality of the tar command can be broken down
into three basic functions: creating, viewing, and extracting archives.
 Create: Make a new archive out of a series of files.
 Extract: Pull one or more files out of an archive.
 List: Show the contents of the archive without extracting.

The tar command accepts all three styles of options, (x -x --extract) as parameters. Do not be surprised to see it
used with options that have no hyphens (BSD style), a single hyphen (UNIX style) or two hyphens (GNU style).

Create Mode
tar -c [-f ARCHIVE] [OPTIONS] [FILE...]

Creating an archive with the tar command requires two named options:

-c Create an archive.

-f ARCHIVE Use the ARCHIVE file. The argument ARCHIVE will be the name of the resulting archive file.

All the remaining arguments, [FILE…], are considered as input file names either as a list of files, as a wildcard, or
both.

To create an archive of the Documents directory, use the create -c option and file -f option to specify a new file,
followed by the directory to archive. Note that the -f option must be specified last since it is indicating a file name:

sysadmin@localhost:~$ tar -cf mydocuments.tar ~/Documents


tar: Removing leading `/' from member names
sysadmin@localhost:~$ ls
Desktop Downloads Pictures Templates mydocuments.tar
Documents Music Public Videos

The verbose -v option will cause the tar command to display the files that are being included in the archive. If
compression is going to be used, then the appropriate option needs to be specified. For the gzip command, the -z
option needs to be added.

-v Verbosely list the files processed.

-z Compress (or decompress) the archive using the gzip command.

File extensions are not relevant to Linux; however, it is customary to add .tar.gz to the name of the compressed
archive. The next example shows the same command as the prior example, but with the addition of the .gz
extension to the original file name and the -z and -v options:

sysadmin@localhost:~$ tar -cvzf mydocuments.tar.gz ~/Documents


tar: Removing leading `/' from member names
/home/sysadmin/Documents/
/home/sysadmin/Documents/animals.txt
/home/sysadmin/Documents/alpha-third.txt
/home/sysadmin/Documents/longfile.txt
/home/sysadmin/Documents/red.txt
/home/sysadmin/Documents/alpha.txt
/home/sysadmin/Documents/hidden.txt
/home/sysadmin/Documents/food.txt
/home/sysadmin/Documents/adjectives.txt
/home/sysadmin/Documents/spelling.txt
/home/sysadmin/Documents/os.csv
/home/sysadmin/Documents/letters.txt
Output Omitted...
sysadmin@localhost:~$ ls
Desktop Downloads Pictures Templates mydocuments.tar
Documents Music Public Videos mydocuments.tar.gz

It is often preferable to archive files before zipping them in any format, whether bzip, gzip, or xz. The following
example archives the test directory using the tar command before compressing it with the xz command:

sysadmin@localhost:~$ mkdir test


sysadmin@localhost:~$ tar -cf testdirectory.tar test
sysadmin@localhost:~$ ls
Desktop Music Templates mydocuments.tar
Documents Pictures Videos test
Downloads Public mydocuments.tar.gz testdirectory.tar
sysadmin@localhost:~$ xz -z testdirectory.tar
sysadmin@localhost:~$ ls
Desktop Music Templates mydocuments.tar
Documents Pictures Videos test
Downloads Public mydocuments.tar.gz testdirectory.tar.xz

The tar command originally did not support compression, but a newer version that was developed by the GNU
project supports gzip, bzip2, and xz compression. To compress (or decompress) an archive with the tar
command, choose the appropriate option:

-z Filter the archive through the gzip command.

-j Filter the archive through the bzip2 command.

-J Filter the archive through the xz command.

If a version of the tar command does not support these compression utilities, the commands can be used
separately on the tar file.

Remove the testdirectory.tar.xz file created in the previous example. Then, to compress the test directory
once again using the xz compression directly with the tar command, use the -J option:

sysadmin@localhost:~$ rm *.xz
sysadmin@localhost:~$ ls
Desktop Downloads Pictures Templates mydocuments.tar.gz test
Documents Music Public Videos mydocuments.tar
sysadmin@localhost:~$ tar -cJf testdirectory.tar.xz test
sysadmin@localhost:~$ ls
Desktop Music Templates mydocuments.tar
Documents Pictures Videos test
Downloads Public mydocuments.tar.gz testdirectory.tar.xz

List Mode
tar -t [-f ARCHIVE] [OPTIONS]

Use the -t option to the tar command to view a list (table of contents) of a tar file.

-t List the files in the archive.

-f ARCHIVE Operate on the given archive.


Even if the archive file is compressed, the correct compression option does not need to be specified to view a tar
archive file. Only the file -f option and the list -t option are required to view the table of contents. Once again,
note that the -f option is used last so that the file name can be specified as an argument to this option:

sysadmin@localhost:~$ tar -tf mydocuments.tar.gz


home/sysadmin/Documents/
home/sysadmin/Documents/animals.txt
home/sysadmin/Documents/alpha-third.txt
home/sysadmin/Documents/longfile.txt
home/sysadmin/Documents/red.txt
home/sysadmin/Documents/alpha.txt
home/sysadmin/Documents/hidden.txt
home/sysadmin/Documents/food.txt
home/sysadmin/Documents/adjectives.txt
home/sysadmin/Documents/spelling.txt
home/sysadmin/Documents/os.csv
home/sysadmin/Documents/letters.txt
Output Omitted...

To view the table of contents of the archive in a format similar to a long listing (like the ls -l command), add the
verbose -v option:

sysadmin@localhost:~$ tar -vtf mydocuments.tar.gz


-drwxr-xr-x sysadmin/sysadmin 0 2019-04-24 16:24 home/sysadmin/Documents/
-rw-r--r-- sysadmin/sysadmin 42 2019-04-24 16:24 home/sysadmin/Documents/animals.txt
-rw-r--r-- sysadmin/sysadmin 195 2019-04-24 16:24 home/sysadmin/Documents/alpha-third.txt
-rw-r--r-- sysadmin/sysadmin 66540 2019-04-24 16:24 home/sysadmin/Documents/longfile.txt
-rw-r--r-- sysadmin/sysadmin 51 2019-04-24 16:24 home/sysadmin/Documents/red.txt
-rw-r--r-- sysadmin/sysadmin 390 2019-04-24 16:24 home/sysadmin/Documents/alpha.txt
-rw-r--r-- sysadmin/sysadmin 67 2019-04-24 16:24 home/sysadmin/Documents/hidden.txt
-rw-r--r-- sysadmin/sysadmin 14 2019-04-24 16:24 home/sysadmin/Documents/food.txt
Output Omitted...

Extract Mode
tar -x [-f ARCHIVE] [OPTIONS]

To extract the files from the tar file, use the -x option.

-x Extract files from an archive.

-f ARCHIVE Operate on the given archive.

If a version of the tar command does not support these compression utilities, the commands can still be used
separately on the tar file.
12.9 The zip and unzip Commands
Of the many commands available in Linux that take multiple files and combine them into one, the zip command
might be most familiar. The functionality of zip compressed file management has been available in the personal
computing world prior to Windows and is now included within the file management graphical utilities found within
Microsoft's Windows and Apple's MacOS.

The zip command is very useful for creating archives that can easily be shared across multiple operating systems.
The basic form of a zip command is:

zip [OPTIONS]... [FILE]...

The destination file will automatically have a .zip extension added to it if an extension is not specified. Also, the
original files will not be replaced.

sysadmin@localhost:~/Documents$ cd
sysadmin@localhost:~$ zip ./example/package ./example/*
adding: example/one (stored 0%)
adding: example/three (stored 0%)
adding: example/two (stored 0%)
sysadmin@localhost:~$ ls ./example/
one package.zip three two

One especially useful option for the zip command is the -r option, which allows the zip command to recursively
compress multiple directories into a single file. For example, to back up the files stored in the /var/log/apt
directory, execute the following command:

sysadmin@localhost:~$ zip -r ./example/logfiles /var/log/apt/


adding: var/log/apt/ (stored 0%)
adding: var/log/apt/eipp.log.xz (stored 0%)
adding: var/log/apt/history.log (deflated 77%)
adding: var/log/apt/term.log (deflated 91%)
sysadmin@localhost:~$ ls ./example/
logfiles.zip one package.zip three two

Note

The log files had been compressed using the gzip command prior to the use of the zip command.
The unzip command is used to extract the files from the zip archive file. Use the unzip command without options
to extract a zip archive:

sysadmin@localhost:~$ cd ./example/
sysadmin@localhost:~/example$ unzip ./logfiles.zip
Archive: ./logfiles.zip
creating: var/log/journal/
creating: var/log/apt/
extracting: var/log/apt/eipp.log.xz
inflating: var/log/apt/history.log
inflating: var/log/apt/term.log
sysadmin@localhost:~/example$ ls ~/example/var/log/apt
eipp.log.xz history.log term.log

A new directory tree is created ~/example/var/log/apt that contains the files that were contained inside of the
zip archive file.

To view the contents of a zip file without unpacking it, use the unzip command with the list -l option:

sysadmin@localhost:~/example$ unzip -l ./package.zip


Archive: ./package.zip
Archive: ./package.zip
Length Date Time Name
--------- ---------- ----- ----
0 2019-03-22 00:14 example/one
0 2019-03-22 00:14 example/three
0 2019-03-22 00:14 example/two
--------- -------
0 3 files

12.10 The cpio Command


Another type of archive command that can merge many files into a single file is the cpio command. This
command gets its name from two of its modes: copy-in mode and copy-out mode. The cpio command works with
the original POSIX specification and should be available on all Linux and Unix systems. It is considered a legacy
application, that although administrators need to be aware of it, most systems provide better alternatives for
archiving directories.

In copy-out mode, the cpio command will copy files from a directory into an archive. In copy-in mode, the cpio
command will either list the archive file contents or copy files from an archive into a directory. It is easy to reverse
these statements and get confused. Just remember that the archive is ”outside” of the operating system.

There is a third mode called the copy-pass mode. In this mode, the cpio command copies files from one directory
to another, which combines the copy-out and copy-in modes without creating an archive file.

To create a new archive file, the cpio command will run in copy-out mode taking a list of files from standard input
and producing a file stream that can be redirected into a new archive file. Standard input, in this case, refers to the
keyboard input by default, but this input could also come from the output of other commands.
Copy-Out Mode

The -o option puts the cpio command into copy-out mode. Using the verbose -v option will cause the cpio
command to list the files that it processes. So, to archive the current directory, execute the ls command, and then
send a list of the files into the cpio command as input by using the pipe | character. The > character will capture
the output of the cpio command and put it into a file):

sysadmin@localhost:~$ ls | cpio -ov > archive.cpio


Desktop
Documents
Downloads
Music
Pictures
Public
Templates
Videos
example
1 block

The find command is a good way to generate the list of files to be sent to the cpio command. The find command
is automatically recursive, so it can be used to create a list of all files starting at a particular directory. For example,
to archive the home directory and all of its subdirectories and files, execute the following command:

sysadmin@localhost:~$ find . -depth -print | cpio -vo > /tmp/ar.cpio


./Public
./Downloads
./Pictures
./Videos
./.selected_editor
./.profile
./.bash_logout
./Templates
./.bashrc
./Desktop
./Music
./Documents/animals.txt
./Documents/alpha-third.txt
./Documents/longfile.txt
./Documents/red.txt
Output Omitted...

The verbose -v option is used to show the activity of the cpio command in the terminal.

Copy-In Mode

To extract the files that are in a cpio archive, use the -i option with the cpio command to specify copy-in mode.
By default, cpio will not overwrite existing files unless the -u option is used. The cpio command will not create
directories unless the -d option is used.

The cpio command also makes use of standard input to determine the name of the file that will be extracted from
the archive. Therefore, to extract files and directories, as well as overwriting existing files, execute the following:

sysadmin@localhost:~$ cpio -idv /tmp/test < /tmp/ar.cpio


2048 blocks
To specify the pass-through mode of the cpio command, specify the -p option. Again, if any directories are
included, the -d option needs to be specified. To copy all the files from the home directory to a directory called
/tmp/destination, use the following command line:

sysadmin@localhost:~$ find ~ | cpio -pd /tmp/destination


2044 blocks

To prevent problems with files that have white space characters (like the spacebar character) embedded in them,
specify the -print0 option to the find command. This causes the list of files to be separated by the null character,
instead of a new line character, which allows for file names with spaces in them to be treated as a single file name
(otherwise a file named hello there would be considered two files, one named hello and the other named
there).

For the cpio command to process the list of null separated files, add the --null option. This results in a more
robust version of the previous pass-through command that looks like this:

sysadmin@localhost:~$ find . -print0 | cpio --null -pvd /tmp/destination


/tmp/destination/./.selected_editor
/tmp/destination/./Videos
/tmp/destination/./.bashrc
/tmp/destination/./Documents
/tmp/destination/./Documents/Work
/tmp/destination/./Documents/Work/.emptydir
/tmp/destination/./Documents/linux.txt
/tmp/destination/./Documents/hello.sh
/tmp/destination/./Documents/animals.txt
/tmp/destination/./Documents/people.csv
/tmp/destination/./Documents/profile.txt
/tmp/destination/./Documents/alpha-first.txt
/tmp/destination/./Documents/adjectives.txt
/tmp/destination/./Documents/longfile.txt
/tmp/destination/./Documents/os.csv
/tmp/destination/./Documents/alpha.txt
/tmp/destination/./Documents/alpha-third.txt
/tmp/destination/./Documents/School

Consider This

To understand why the cpio command might be used for copying files from one directory to another instead of
using the cp command recursively, consider the following advantages:

 The cpio command automatically preserves file attributes (metadata) like links, permissions, timestamps, and
ownerships. These attributes are not preserved with using the cp command.
 The cpio command also works with special files better than the cp command.

12.11 The dd Command


The dd command is a utility for copying files or entire partitions at the bit level. This command has several useful
features, including:

 It can be used to clone or delete (wipe) entire disks or partitions.


 It can be used to copy raw data to removable devices, such as USB drives and CDROMs.
 It can backup and restore the MBR (Master Boot Record), a critical software component that is used to boot
the system.
 It can be used to create a file of a specific size that is filled with binary zeros, which can then be used as a
swap file (virtual memory).

The dd command uses special arguments to specify how it will work. The following illustrates some of the more
commonly used arguments:

if=FILE The input file to be read.


of=FILE The output file to be written.
The block size to be used. By default, the value is considered to be in bytes. Use the following
bs=SIZE suffixes to specify other units: K, M, G, and T for kilobytes, megabytes, gigabytes, and terabytes
respectively.
count=NUMBER The number of blocks to read from the input file.

In the following example, a file named /tmp/swapex is created with 500 "one-megabyte" size blocks of zeros:

sysadmin@localhost:~$ dd if=/dev/zero of=/tmp/swapex bs=1M count=500


500+0 records in
500+0 records out
524288000 bytes (524 MB) copied, 0.825745 s, 635 MB/s

No block size or count needs to be specified when copying over entire devices. For example, to clone from one
hard drive /dev/sda to another /dev/sdb, execute the following command:

Note

The examples below are designed to demonstrate how device files can be used to copy and backup devices. The
files in the examples below are not available in our virtual machine environment.

sysadmin@localhost:~$ dd if=/dev/sda of=/dev/sdb

The dd command can even be used to make an .iso image backup of your CDROM or DVD device. The
following will take all of the data from the DVD /dev/dvd and stores the data into a local file called dvd.iso:

sysadmin@localhost:~$ dd if=/dev/dvd of=dvd.iso

Consider This

Device files are files used to refer to devices on the system, such as hard drives, CD-ROMS, and partitions. Device
files are associated with file names that are stored in the /dev directory.

The following information is provided to add clarity to the examples shown with the dd command:

/dev/sda A device file that typically refers to the first hard drive on the system.
/dev/sdb A device file that typically refers to the second hard drive on the system.
/dev/dvd A device file that typically refers to the first DVD drive on the system.
Key Term
A method of uncompressing files compressed using the <command>xz</command> command.
Section 12.6
xz
Command that can compress or decompress .zx or .lzma files. xz is a general-purpose data compression
tool with command line syntax similar to gzip(1) and bzip2(1). The native file format is the .xz format, but
also the legacy .lzma format and raw compressed streams with no container format headers are supported.
Section 12.6
xzcat
Command used to print the contents of files compressed with the <command>xz</command> command to
standard output on the terminal without uncompressing the target file.
Section 12.7
zcat
Command used to display the contents of a compressed file from a compressed archive created by the
<command>tar</command> or <command>gzip</command> commands without uncompressing it. Its
effect is identical to running the <command>gzip -c</command> command:
Section 12.3
LAB 12
12.0 Introduction
Linux distributions provide several different sets of commands for compressing and archiving files and directories.
Archiving combines multiple files into one, which eliminates the overhead in individual files and makes it easier to
transmit. Compression makes the files smaller by removing redundant information.

12.1 Step 1
The gzip and gunzip commands are used to compress and uncompress a file, respectively. The gzip command
replaces the original file with the compressed .gz file.

gzip [OPTION]... [FILE]...

In the following example, the longfile.txt file is replaced with the compressed longfile.txt.gz file after
using the gzip command:

cd Documents/
ls longfile.txt
gzip longfile.txt
ls longfile*
sysadmin@localhost:~$ cd Documents/
sysadmin@localhost:~/Documents$ ls longfile.txt
longfile.txt
sysadmin@localhost:~/Documents$ gzip longfile.txt
sysadmin@localhost:~/Documents$ ls longfile*
longfile.txt.gz
The gzip command should be used with caution since its default behavior is to replace the original file specified
with a compressed version.

12.2 Step 2
The gunzip command reverses the action of gzip, so the .gz file is uncompressed and replaced by the original
file.

gunzip [OPTION]... [FILE]...

Use the -l option with gunzip to list the amount of compression of an existing file and then use the gunzip
command alone to decompress the longfile.txt.gz file:

gunzip -l longfile.txt.gz
gunzip longfile.txt.gz
ls longfile*
sysadmin@localhost:~/Documents$ gunzip -l longfile.txt.gz
compressed uncompressed ratio uncompressed_name
341 66540 99.5% longfile.txt
sysadmin@localhost:~/Documents$ gunzip longfile.txt.gz
sysadmin@localhost:~/Documents$ ls longfile*
longfile.txt
12.3 Step 3
To retain the original file while compressing using the gzip command, use the -c option. To do this with the
animals.txt file, execute the following commands:

gzip –c animals.txt > animals.txt.gz


ls –l animals*
sysadmin@localhost:~/Documents$ gzip -c animals.txt > animals.txt.gz
sysadmin@localhost:~/Documents$ ls -l animals*
-rw-r--r-- 1 sysadmin sysadmin 42 Apr 24 16:24 animals.txt
-rw-rw-r-- 1 sysadmin sysadmin 71 May 21 03:14 animals.txt.gz

12.4 Step 4
The zcat command is used to display the contents of a compressed file without actually uncompressing it. Use the
following command to view the contents of the compressed words.gz file:

zcat animals.txt.gz
sysadmin@localhost:~/Documents$ zcat animals.txt.gz
sysadmin@localhost:~/Documents$ zcat animals.txt.gz
1 retriever
2 badger
3 bat
4 wolf
5 eagle

12.5 Step 5
The gzip and gunzip commands support recursion with the -r option. In order to be able to compress files with
the gzip command recursively, a user needs to have the correct permissions on the directories the files are in.
Typically, this is limited to directories within the user's own home directory.

Create a directory called my_directory, which contains three files: file1, file2, and file3.

To avoid having to repeatedly type the same file or directory name, type the first few characters of the file name
and press the Tab key. Alternatively, you can use the Esc+. (the Escape Key and the period . character) shortcut to
recall the last file name used.
mkdir mydirectory
touch mydirectory/file1 mydirectory/file2 mydirectory/file3
ls mydirectory/
sysadmin@localhost:~/Documents$ mkdir mydirectory
sysadmin@localhost:~/Documents$ touch mydirectory/file1 mydirectory/file2 mydirectory/file3
sysadmin@localhost:~/Documents$ ls mydirectory/
file1 file2 file3

Now, use the gzip command recursively on the my_directory directory by executing the following commands:

gzip -r mydirectory/
ls mydirectory/
sysadmin@localhost:~/Documents$ gzip -r mydirectory/
sysadmin@localhost:~/Documents$ ls mydirectory/
file1.gz file2.gz file3.gz

Use the gunzip command to recursively uncompress the files in the mydirectory directory:

gunzip –r mydirectory/
sysadmin@localhost:~/Documents$ gunzip -r mydirectory/
sysadmin@localhost:~/Documents$ ls mydirectory/
file1 file2 file3
Permissions can have an impact on file management commands, such as the gzip and gunzip commands. To gzip
or gunzip a file within a directory, a user must have the write and execute permission on a directory as well as the
read permission on the file.

12.6 Step 6
The bzip2 and bunzip2 commands work in a nearly identical fashion to the gzip and gunzip commands:

bzip2 [OPTION]... [FILE]...


bunzip2 [OPTION]... [FILE]...

To compress the longfile.txt file in the current directory using the bzip2 command, execute the following
commands:

bzip2 longfile.txt
ls –l longfile*
sysadmin@localhost:~/Documents$ bzip2 longfile.txt
sysadmin@localhost:~/Documents$ ls -l longfile*
-rw-r--r-- 1 sysadmin sysadmin 188 Apr 24 16:24 longfile.txt.bz2

Similar to the gzip and gunzip commands, the bzip2 and bunzip2 commands are also used to compress and
uncompress a file. The compression algorithm used by both commands is different, but the usage is very similar.
The extension of the files created by bzip2 command is .bz2.

12.7 Step 7
The bzcat command prints the content of specified files compressed with the bzip2 command to the standard
output.

bzcat [OPTION]... [FILE]...

To view the compressed lonfile.txt.bz2 file, use the following command:

sysadmin@localhost:~/Documents$ bzcat longfile.txt.bz2


hello
inkling
jogger
apple
banana
cat
dog
elephant
flower
grapes
hello
inkling
jogger
apple
banana
cat
dog
elephant
flower
grapes
hello
inkling
jogger
sysadmin@localhost:~/Documents$

12.8 Step 8
To extract the compressed longfile.txt.bz2 file created in the example above, execute the following
commands:

bunzip2 longfile.txt.bz2
ls –l longfile*
sysadmin@localhost:~/Documents$ bunzip2 longfile.txt.bz2
sysadmin@localhost:~/Documents$ ls -l longfile*
-rw-r--r-- 1 sysadmin sysadmin 66540 Apr 24 16:24 longfile.txt
While the gzip command supports recursion with the -r option, the bzip2 command does not support a separate
option for recursion. So, bzip2 cannot be used to compress a nested directory structure.

12.9 Step 9
Another compression tool similar to gzip and bzip2 is the xz command.

xz [OPTION]... [FILE]...

To compress the longfile.txt file in the current directory using the bzip2 command, execute the following
commands:

sysadmin@localhost:~/Documents$ xz longfile.txt
sysadmin@localhost:~/Documents$ ls -l longfile*
-rw-r--r-- 1 sysadmin sysadmin 220 Apr 24 16:24 longfile.txt.xz

As demonstrated in the output above, when a new compressed file is created, the .xz extension is added to the file
name.

12.10 Step 10
The xzcat command is used to print the contents of files compressed with the xz command to standard output on
the terminal without uncompressing the target file.

xzcat [FILE]...

To view the compressed longfile.txt.gz file, use the following command:

xzcat longfile.txt
sysadmin@localhost:~/Documents$ xzcat longfile.txt.xz
hello
inkling
jogger
apple
banana
cat
dog
elephant
flower
grapes
hello
inkling
jogger
apple
banana
cat
dog
elephant
flower
grapes
hello
inkling
jogger
sysadmin@localhost:~/Documents$

12.11 Step 11
Next, use the unxz command to uncompress the longfile.txt.xz file:

sysadmin@localhost:~/Documents$ unxz longfile.txt.xz


sysadmin@localhost:~/Documents$ ls -l longfile*
-rw-r--r-- 1 sysadmin sysadmin 66540 Apr 24 16:24 longfile.tx
12.12 Step 12
An archive is a single file, which consists of many files, though not necessarily compressed. The tar command is
typically used to make archives within Linux. The tar command provides three main functions: creating, viewing,
and extracting archives:

 Create: Make a new archive out of a series of files.


 Extract: Pull one or more files out of an archive.
 List: Show the contents of the archive without extracting.

Creating an archive with the tar command requires two named options:

-c Create an archive.
-f ARCHIVE Use the ARCHIVE file. The argument ARCHIVE will be the name of the resulting archive file.

To create a tar archive of the /etc/vim directory and place the tar file in the current directory, execute the
following commands:

tar –cf vim.tar /etc/vim


ls –l *.tar
sysadmin@localhost:~$ tar -cf vim.tar /etc/vim
tar: Removing leading `/' from member names
sysadmin@localhost:~$ ls -l *.tar
-rw-rw-r-- 1 sysadmin sysadmin 10240 Apr 18 17:26 vim.tar

12.13 Step 13
Use the -t option to the tar command to view a list (table of contents) of a tar file.

-t List the files in the archive.


-f ARCHIVE Operate on the given archive.

To view the contents of the vim.tar file, execute the following command:

tar –tf vim.tar


sysadmin@localhost:~$ tar -tf vim.tar
etc/vim/
etc/vim/vimrc
etc/vim/vimrc.tiny
12.14 Step 14
The verbose -v option can be used with the tar command to view the table of contents of the archive. To view the
detailed listing of the contents of the vim.tar file, execute the following command:

tar –tvf vim.tar


sysadmin@localhost:~$ tar -tvf vim.tar
drwxr-xr-x root/root 0 2019-03-22 17:41 etc/vim/
-rw-r--r-- root/root 2469 2018-04-10 21:31 etc/vim/vimrc
-rw-r--r-- root/root 662 2018-04-10 21:31 etc/vim/vimrc.

12.15 Step 15
To extract the files from the tar file, use the -x option.

-x Extract files from an archive.


-f ARCHIVE Operate on the given archive.

To extract the files from the vim.tar into the current directory, execute the following commands:

tar –xf vim.tar


ls etc/vim
sysadmin@localhost:~$ tar -xf vim.tar
sysadmin@localhost:~$ ls etc/vim
vimrc vimrc.tiny

12.16 Step 16
To extract the files from the vim.tar into another directory, use the -C option to the tar command. For example,
execute the following commands:

tar –xvf vim.tar -C /tmp


ls –R /tmp/etc
sysadmin@localhost:~$ tar -xvf vim.tar -C /tmp
etc/vim/
etc/vim/vimrc
etc/vim/vimrc.tiny
sysadmin@localhost:~$ ls -R /tmp/etc
/tmp/etc:
vim

/tmp/etc/vim:
vimrc vimrc.tiny
12.17 Step 17
Archiving files is an efficient way of making backups and transferring large files. The most commonly used
compression utilities are zip and unzip. The zip command is very useful for creating archives that can easily be
shared across multiple operating systems.

zip [OPTIONS]... [FILE]...

The -r option allows the zip command to compress multiple directories into a single file recursively. To archive
all the files and directories in the /etc/perl directory to the myperl.zip file, execute the following command:

zip –r myperl.zip /etc/perl


sysadmin@localhost:~$ zip -r myperl.zip /etc/perl
adding: etc/perl/ (stored 0%)
adding: etc/perl/CPAN/ (stored 0%)
adding: etc/perl/Net/ (stored 0%)
adding: etc/perl/Net/libnet.cfg (deflated 52%)

The zip command will add the .zip extension to files by default, as you can see by executing the following
command:

ls -l m*
sysadmin@localhost:~/Documents$ ls -l myperl*
-rw-rw-r-- 1 sysadmin sysadmin 947 May 21 03:34 myperl.zip

12.18 Step 18
To view the contents of a zip file without unpacking it, use the unzip command with the list -l option. To list the
contents of the myperl.zip file without unzipping it, execute the following command:

unzip –l myperl.zip
sysadmin@localhost:~$ unzip -l myperl.zip
Archive: myperl.zip
Length Date Time Name
--------- ---------- ----- ----
0 2019-04-17 20:09 etc/perl/
0 2018-11-19 15:54 etc/perl/CPAN/
0 2019-04-17 20:09 etc/perl/Net/
611 2018-11-19 15:54 etc/perl/Net/libnet.cfg
--------- -------
611 4 files
12.19 Step 19
The unzip command is used to extract the files from the zip archive file. To extract the contents of the
myperl.zip file, execute the following command:

unzip myperl.zip
sysadmin@localhost:~$ unzip myperl.zip
Archive: myperl.zip
creating: etc/perl/
creating: etc/perl/CPAN/
creating: etc/perl/Net/
inflating: etc/perl/Net/libnet.cfg

12.20 Step 20
The cpio command is another archival command, which can merge multiple files into a single file.

The cpio command works with the original POSIX specification and should be available on all Linux and Unix
systems. It is considered a legacy application, and although administrators need to be aware of it, most systems
provide better alternatives for archiving directories.

The cpio command operates in two modes: copy-in mode and copy-out mode. The copy-out mode is used to create
a new archive file. The -o option puts the cpio command into copy-out mode. The files can be provided via
standard input or redirected from the output of another command to produce a file stream which will be archived.

To archive all the *.conf files in the current directory, use the following command:

cp /etc/*.conf .
ls *.conf | cpio -ov > conf.cpio
ls *.cpio
sysadmin@localhost:~$ cp /etc/*.conf .
sysadmin@localhost:~$ ls *.conf | cpio -ov > conf.cpio
adduser.conf
ca-certificates.conf
debconf.conf
deluser.conf
fuse.conf
gai.conf
hdparm.conf
host.conf
ld.so.conf
libaudit.conf
logrotate.conf
ltrace.conf
mke2fs.conf
nsswitch.conf
pam.conf
popularity-contest.conf
resolv.conf
rsyslog.conf
sysctl.conf
ucf.conf
updatedb.conf
88 blocks
sysadmin@localhost:~$ ls *.cpio
conf.cpio

In the example above, the verbose -v option is used to list the files that the cpio command processes.

12.21 Step 21
The copy-in mode is used to extract files from a cpio archive file. The -i option enables copy-in mode. In addition,
the -u option can be used to overwrite existing files and the -d option is used to indicated that directories should be
created. To extract the files from the conf.cpio file into the current directory, first delete the original files and
then use the cat command to send the data into the cpio command:

rm *.conf
cat conf.cpio | cpio -iud
ls *.conf
sysadmin@localhost:~$ rm *.conf
sysadmin@localhost:~$ cat conf.cpio | cpio -iud
88 blocks
sysadmin@localhost:~$ ls *.conf
adduser.conf hdparm.conf mke2fs.conf sysctl.conf
ca-certificates.conf host.conf nsswitch.conf ucf.conf
debconf.conf ld.so.conf pam.conf updatedb.conf
deluser.conf libaudit.conf popularity-contest.conf
fuse.conf logrotate.conf resolv.conf
gai.conf ltrace.conf rsyslog.conf

12.22 Step 22
The dd command is a utility for copying files or entire partitions at the bit level. It can be used to clone or delete
entire disks or partitions, creating large "empty" files to be used as swap files and copy raw data to removable
devices. The dd command uses special arguments to specify how it will work. The following illustrates some of the
more commonly used arguments:

if=FILE The input file to be read.


of=FILE The output file to be written.
The block size to be used. By default, the value is considered to be in bytes. Use the following
bs=SIZE
suffixes to specify other units: K, M, G, and T for kilobytes, megabytes, gigabytes, and terabytes.
count=NUMBER The number of blocks to read from the input file.

To create a file named /tmp/swapex with 500 "one megabyte" size blocks of zeroes, execute the following
command:

dd if=/dev/zero of=/tmp/swapex bs=1M count=500


sysadmin@localhost:~$ dd if=/dev/zero of=/tmp/swapex bs=1M count=500
500+0 records in
500+0 records out
524288000 bytes (524 MB, 500 MiB) copied, 8.80912 s, 59.5 MB/s
To verify that the swapex file was created in the /tmp directory, execute the following command:

ls -lh /tmp
sysadmin@localhost:~$ ls -lh /tmp
total 501M
drwxrwxr-x 3 sysadmin sysadmin 4.0K Apr 18 17:31 etc
-rw-rw-r-- 1 root root 2.2K Apr 17 22:31 inside_setup.sh
-rw-rw-r-- 1 sysadmin sysadmin 500M Apr 18 17:39 swapex
NDG Introduction to Linux I - Chapter 13: File
Permissions

13.1 Introduction
In order to access or modify a file or directory, the correct permissions must be set. There are three different
permissions that can be placed on a file or directory: read, write, and execute.

When listing a file with the ls -l command, the output includes permission and ownership information:

sysadmin@localhost:~$ ls -l /bin/ls
-rwxr-xr-x 1 root root 133792 Jan 18 2018 /bin/ls

Below is a refresher on the fields relevant to permissions.

File Type Field


-rwxr-xr-x. 1 root root 133792 Jan 18 2018 /bin/ls

The first character of this output indicates the type of a file. Recall if the first character is a dash - character, as in
the previous example, this is a regular file. If the character was a letter d, it would be a directory.

If the first character of the output of the ls -l command is a letter l, then the file is a symbolic link. A symbolic
link file "points to" another file in the file system.

Note

To access a file that a symbolic link points to, you need to have the appropriate permissions on both the symbolic
link file and the file that it points to.

Permissions Field
-rwxr-xr-x. 1 root root 133792 Jan 18 2018 /bin/ls

After the file type character, the permissions are displayed.

User Owner Field


-rwxr-xr-x. 1 root root 133792 Jan 18 2018 /bin/ls

After the link count, the file's user owner is displayed.

Group Owner Field


-rwxr-xr-x. 1 root root 133792 Jan 18 2018 /bin/ls

After the user owner field, the file group owner is displayed.
13.2 File Ownership
By default, users own the files that they create. While this ownership can be changed, this function requires
administrative privileges. Although most commands usually show the user owner as a name, the operating system
is associating the user ownership with the UID for that username.

Every file also has a group owner. By default, the primary group of the user who creates the file is the group owner
of any new files. Users are allowed to change the group owner of files they own to any group that they belong to.
Similar to user ownership, the association of a file with a group is not done internally by the operating system by
name, but by the GID of the group.

The id command can be useful for verifying which user account you are using and which groups you have
available to use. By viewing the output of this command, you can see the user's identity information expressed both
as a number and as a name.

The output of the id command displays the UID and user account name of the current user followed by the GID
and group name of the primary group and the GIDs and group names of all group memberships:

sysadmin@localhost:~/Documents$ id
uid=1001(sysadmin) gid=1001(sysadmin) groups=1001(sysadmin),4(adm),27(sudo)

The above example shows that the user has a UID of 1001 for the sysadmin user account. It also shows that the
primary group for this user has a GID of 1001 for the sysadmin group. In addition, the user in this example
belongs to two supplemental groups: the adm group with a GID of 4, and the sudo group with a GID of 27

13.2.1 Switching Users


There are many different ways to execute a command that requires administrative or root privileges. Logging in to
the system as the root user allows you to execute commands as the administrator. This access is potentially
dangerous because you may forget that you are logged in as root and might run a command that could cause
problems on the system. As a result, it is not recommended to log in as the root user directly.

The su command allows you to run a shell as a different user. While switching to the root user is what the su
command is used for most frequently, it can also switch to other users as well.

su [OPTIONS] [USERNAME]

When switching users, utilizing the login shell option is recommended as the login shell fully configures the new
shell with the settings of the new user, ensuring any commands executed run correctly. If this option is omitted, the
new shell changes the UID but doesn't fully log in as the user. The login shell option can be specified one of three
ways:

su -
su -l
su --login

By default, if a username is not specified, the su command opens a new shell as the root user. The following two
commands are equivalent ways to start a shell as the root user:
su - root
su -

After pressing Enter to execute either one of these commands, the user must provide the password of the root user
to start the new shell. If you don't know the password of the account that you are shifting to, then the su command
will fail.

Note

The password of the root user in our virtual machine environment is netlab123.

sysadmin@localhost:~$ su -
Password:
root@localhost:~# id
uid=0(root) gid=0(root) groups=0(root)

After using the shell started by the su command to perform the necessary administrative tasks, return to your
original shell (and original user account) by using the exit command.

root@localhost:~# exit
logout
sysadmin@localhost:~$ id
uid=1001(sysadmin) gid=1001(sysadmin) groups=1001(sysadmin),4(adm),27(sudo)

The sudo command allows users to execute commands as another user. Similar to the su command, the root user
is assumed by default.

sudo [OPTIONS] COMMAND

In distributions that do not allow the root user to login directly or via the su command, the installation process
automatically configures one user account to be able to use the sudo command to execute commands as if the root
user executed them.

When using the sudo command to execute a command as the root user, the command prompts for the user's own
password, not that of the root user. This security feature could prevent unauthorized root access if the user were
to leave their computer unattended.

Note

The password of the sysadmin user in our virtual machine environment is netlab123.

Consider that administrative privileges are necessary to view the /etc/shadow file, therefore, use the sudo
command to execute the head command on the /etc/shadow file as the root user:

sysadmin@localhost:~$ sudo head -3 /etc/shadow


[sudo] password for sysadmin:
root:$6$gWn1b01z$/awsehiCL9PPBmlYgEbtpeSXkafiLZPcugO5VjU.R5bjhGlg8IoTOLVmkBoXlqObOBUQ0lCkVHm
g2ucnoHpsY0:18010:0:99999:7:::
daemon:*:17962:0:99999:7:::
bin:*:17962:0:99999:7:::
13.2.2 Changing File User Owner
Initially, the owner of a file is the user who creates it. The user owner can only be changed by a user with root
privileges using the chown command. Using the syntax below, the root user can change the owner of the FILE to
the OWNER account.

chown [OPTION]... [OWNER] FILE...

For instance, a new file called nullfile will be created in the Documents directory:

sysadmin@localhost:~$ cd Documents
sysadmin@localhost:~/Documents$ touch nullfile

Using the ls -l command, we can see that the owner of this file is the sysadmin user:

sysadmin@localhost:~/Documents$ ls -l nullfile
-rw-rw-r-- 1 sysadmin sysadmin 0 Mar 21 17:30 nullfile

Next, the sudo command can be used with the chown command to change the ownership of the new file to the root
user, and the ls -l command is used to verify the change:

Note

The password of the sysadmin user in our virtual machine environment is netlab123.

sysadmin@localhost:~/Documents$ sudo chown root


nullfile
[sudo] password for sysadmin:
sysadmin@localhost:~/Documents$ ls -l nullfile
-rw-rw-r-- 1 root sysadmin 0 Mar 21 17:30 nullfile

The information displayed in the output of the ls -l command about the nullfile file indicates that the user
owner of the file is now the root user.

13.2.3 Switching Groups


When a user creates a file or directory, their primary group will normally be the group owner. The id command
lists your identity information, including your group memberships. If you are only interested in knowing what
groups you belong to, then you can execute the groups command:

sysadmin@localhost:~$ groups
sysadmin adm sudo

To create a file or directory that will be owned by a group different from your current primary group, one option is
to change your current primary group to another group you belong to by using the newgrp command.

newgrp [GROUP]

For example, to change the current primary group from sysadmin to the secondary group called adm, execute the
following command:

sysadmin@localhost:~/Documents$ newgrp adm


The result of the newgrp command in the example above is that any new files or directories created will be group
owned by the adm group:

sysadmin@localhost:~$ touch newfile.txt


sysadmin@localhost:~$ ls -l newfile.txt
-rw-rw-r-- 1 sysadmin adm 0 Mar 21 20:00 newfile.txt
sysadmin@localhost:~$ exit
exit
sysadmin@localhost:~/Documents$

The newgrp command opens a new shell and assigns the primary group for that shell to the specified group. So, in
other words, the newgrp command places you in another shell in a different primary group. Once in the new shell,
any file created, in this case, newfile.txt, will belong to the new primary group, which is adm in the example
above. To go back to the default primary group, use the exit command to close the new shell that was started by
the newgrp command.

Note

You must be a member of the group that you want to change to. Additionally, administrators can password protect
groups.

13.2.4 Changing File Group Owner


Another option is for the user owner of the file to change the group owner by using the chgrp command. For
example, if you forgot to use the newgrp command to switch to the user’s primary group before creating the file,
you can execute the following commands instead:

sysadmin@localhost:~/Documents$ touch newfile2.txt


sysadmin@localhost:~/Documents$ ls -l newfile2.txt
-rw-rw-r-- 1 sysadmin sysadmin 0 Mar 21 18:03 newfile2.txt
sysadmin@localhost:~/Documents$ sudo chgrp nogroup
newfile2.txt
sysadmin@localhost:~/Documents$ ls -l newfile2.txt
-rw-rw-r-- 1 sysadmin nogroup 0 Mar 21 18:03 newfile2.txt
sysadmin@localhost:~/Documents$ cd
sysadmin@localhost:~$

In the example above, a file called newfile.txt was created, then the chgrp command was used to change the
group owner of the file from the default primary group sysadmin to the group nogroup.

The chgrp command does not change your current primary group, so when creating many files, it is more efficient
just to use the newgrp command instead of executing the chgrp command for each file.

Note

Only the owner of the file and the root user can change the group ownership of a file.

13.3 Understanding Permissions


User and group owner information are important considerations when determining what permissions will be
effective for a particular user. To determine which set applies to a particular user, first examine the user's identity.
By using the whoami command or the id command, you can display your user identity.

The whoami command prints the user name associated with the current user ID:

sysadmin@localhost:~$ whoami
sysadmin

The id command displays the user ID and user name of the current user followed by the group ID and group name
of the primary group, and the GIDs and group names of all group memberships:

sysadmin@localhost:~$ id
uid=1001(sysadmin) gid=1001(sysadmin) groups=1001(sysadmin),4(adm),27(sudo)

Permission Groups

When viewing the long listing of a file, the permissions are broken into three sets of three characters:

-rwxr-xr-x. 1 root root 133792 Jan 18 2018 /bin/ls

User Owner

-rwxr-xr-x. 1 root root 133792 Jan 18 2018 /bin/ls

Characters 2-4 indicate the permissions for the user that owns the file. If you are the owner of the file, then only the
user owner permissions are used to determine access to that file.

Group Owner

-rwxr-xr-x. 1 root root 133792 Jan 18 2018 /bin/ls

Characters 5-7 indicate the permissions for the group that owns the file. If you are not the owner but are a member
of the group that owns the file, then only group owner permissions are used to determine access to that file.

Other Permissions

-rwxr-xr-x. 1 root root 133792 Jan 18 2018 /bin/ls

Characters 8-10 indicate the permissions for others or what is sometimes referred to as the world's permissions.
This group includes all users who are not the file owner or a member of the file's group.

Permission Types

Each permission group is granted three basic types of permissions: read, write, and execute.

User Owner Group Owner Other


Read Write Execute Read Write Execute Read Write Execute
r w - r - - r - -

The permissions themselves are deceptively simple and have a different meaning depending on whether they are
applied to a file or a directory.
Read

The first character of each group represents the read permission. There is an r character if the group has the read
permission, or a - character if the group does not.

 On a file, this allows processes to read the contents of the file, meaning the contents can be viewed and
copied.
 On a directory, file names in the directory can be listed, but other details are not available.

Write

The second character of each group represents the write permission. There is a w character if the group has the
write permission, or a - character if the group does not.

 A file can be written to by the process, so changes to a file can be saved. Note that w permission really
requires r permission on the file to work correctly.
 On a directory, files can be added to or removed from the directory. Note that w permission requires x
permission on the directory to work correctly.

Execute

The third character of each group represents the execute permission. There is an x character if the group has the
execute permission, or a - character if the group does not.

 A file can be executed or run as a process.


 On a directory, the user can use the cd command to "get into" the directory and use the directory in a
pathname to access files and, potentially, subdirectories under this directory.

For example, use the following command in the virtual terminal and examine the permissions displayed.

sysadmin@localhost:~$ ls -l /etc

Answer the following questions:

 Who owns the files in the /etc directory?


 Can members of the root group modify (write to) these files?
 Can users who are not the root user, nor members of the root group modify these files?

Consider This

Understanding which permissions apply is an important skill in Linux. For example, consider the output of the ls
-l command for the following file:

-r--rw-rwx. 1 bob staff 999 Apr 10 2013 /home/bob/test

In this scenario, the user bob ends up having less access to this file than members of the staff group or everyone
else. The user bob only has the r-- permissions. It doesn't matter if bob is a member of the staff group; once user
ownership has been established, only the user owner permissions apply.
13.4 Changing Basic File Permissions
The chmod command is used to change the permissions of a file or directory. Only the root user or the user who
owns the file is able to change the permissions of a file.

chmod MODE FILE…

Consider This

Why is the command called chmod instead of chperm? Permissions used to be referred to as modes of access, so
the command chmod really means "change the modes of access".

There are two techniques of changing permissions with the chmod command: symbolic and octal. The symbolic
method is good for changing one set of permissions at a time. The octal method (also called the numeric method)
requires knowledge of the octal value of each of the permissions and requires all three sets of permissions (user,
group, other) to be specified every time. When changing more than one permission set, the octal method is
probably the more efficient method.

13.4.1 Symbolic Method


To use the symbolic method of the chmod command, use the symbols summarized in the tables below to specify the
MODE argument, which represents which changes to make to the permissions.

chmod MODE FILE...

First indicate which permission group (or groups) to apply the changes to:

⁠ 
Symbol Group
u user owner
g group owner
o others
a all (user owner, group owner, and others)

Next, use one of the following operators to indicate how to modify the permissions:

Symbol Operation
+ add the permission, if necessary
= specify the exact permission
- remove the permission, if necessary

Next, use the following characters to specify the permissions type to change:

Symbol Permission
r read
w write
x execute
Finally, add a space followed by the path names for the files to assign those permissions.

To add the execute permission for the user owner:

sysadmin@localhost:~$ chmod u+x newfile.txt


sysadmin@localhost:~$ ls -l newfile.txt
-rwxrw-r-- 1 sysadmin adm 0 Mar 21 18:10 newfile.txt

To remove the write permission from the group owner:

sysadmin@localhost:~$ chmod g-w newfile.txt


sysadmin@localhost:~$ ls -l newfile.txt
-rwxr--r-- 1 sysadmin adm 0 Mar 21 18:10 newfile.txt

To specify permissions for more than one set, use commas (and no spaces) between each set.

chmod MODE[,MODE]... FILE...

To assign others to have only the read permission, remove the write permission from the group owner, and add the
execute permission for the user owner:

sysadmin@localhost:~$ chmod o=r,g-w,u+x newfile.txt


sysadmin@localhost:~$ ls -l newfile.txt
-rwxr--r-- 1 sysadmin nogroup 0 Mar 21 18:10 newfile.txt

You also can combine either the group or permissions symbols to make multiple changes to the file's permissions.
For example, consider the following command which adds the execute permission to the user owner and group
owner, and removes the read permission for others:

sysadmin@localhost:~$ chmod ug+x,o-r newfile.txt


sysadmin@localhost:~$ ls -l newfile.txt
-rwxr-x--- 1 sysadmin adm 0 May 3 22:26 newfile.txt

Using the = character adds the specified permissions and causes unmentioned ones to be removed. For example, to
give the user owner only read and execute permissions, and remove the write permission:

sysadmin@localhost:~$ chmod u=rx newfile.txt


sysadmin@localhost:~$ ls -l newfile.txt
-r-xr-x--- 1 sysadmin adm 0 May 3 22:26 newfile.txt

Assign everyone no permissions:

sysadmin@localhost:~$ chmod a=- fakefile

In the following example, the file sample is created with the touch command, and then its permissions are
modified using the symbolic method:

sysadmin@localhost:~/Documents$ touch sample


sysadmin@localhost:~/Documents$ ls -l sample
-rw-rw-r-- 1 sysadmin sysadmin 0 Mar 21 18:17 sample
sysadmin@localhost:~/Documents$ chmod g-w,o-r sample
sysadmin@localhost:~/Documents$ ls -l sample
-rw-r----- 1 sysadmin sysadmin 0 Mar 21 18:17 sample
13.4.2 Octal Method
Using the octal method requires that the permissions for all three sets be specified. It is based on the octal
numbering system in which each permission type is assigned a numeric value:

Octal Value Permission


4 read
2 write
1 execute
0 none

By adding together the combination of numbers from 0 to 7, any possible combination of read, write, and execute
permissions can be specified for a single permission group set. For example:

Octal Value Permission Set


7 rwx
6 rw-
5 r-x
4 r--
3 -wx
2 -w-
1 --x
0 ---

These numbers are easy to derive by just adding together the octal value for the permissions shown. So, for read,
write, and execute: add 4 + 2 + 1 to get 7. Or, for read, not write, and execute: add 4 + 0 + 1 to get 5.

Follow Along

To execute the following examples, create a file called sample.txt in your home directory. You will use this file
to practice the octal method technique for changing permissions:

sysadmin@localhost:~$ touch sample.txt


sysadmin@localhost:~$ ls -l sample.txt
-rw-rw-r-- 1 sysadmin sysadmin 0 May 3 23:41 sample.txt

To demonstrate, set the permissions of a file to rwxr-xr-x. Using the values found in the previous table, this
would calculate as 7 for the user owner's permission, 5 for the group owner's permissions, and 5 for others:

sysadmin@localhost:~$ chmod 764 sample.txt


sysadmin@localhost:~$ ls -l sample.txt
-rwxrw-r-- 1 sysadmin sysadmin 0 May 3 23:41 sample.txt

Note

It’s good practice to specify the octal value for all three permission groups, like we’ve done in our examples.
However, if any digits are left off, they are assumed to be leading zeros.

To change permissions to rwxrw-r--:


sysadmin@localhost:~$ chmod 764 sample.txt
sysadmin@localhost:~$ ls -l sample.txt
-rwxrw-r-- 1 sysadmin sysadmin 0 May 3 23:41 sample.txt

To change permissions to rw-r--r--:

sysadmin@localhost:~$ chmod 644 sample.txt


sysadmin@localhost:~$ ls -l sample.txt
-rw-r--r-- 1 sysadmin sysadmin 0 May 3 23:41 sample.txt

To change permissions to rwxr--r--:

sysadmin@localhost:~$ chmod 744 sample.txt


sysadmin@localhost:~$ ls -l sample.txt
-rwxr--r-- 1 sysadmin sysadmin 0 May 3 23:41 sample.txt

To change permissions to ---------:

sysadmin@localhost:~$ chmod 000 sample.txt


sysadmin@localhost:~$ ls -l sample
---------- 1 sysadmin sysadmin 0 Mar 21 18:17 sample.txt

Considering the last example, what can be done with a file if there are no permissions for anyone on the file? The
owner of the file can always use the chmod command at some point in the future to grant permissions on the file.
Also, with the write and execute permissions -wx on the directory that contains this file, a user can also remove it
with the rm command.

In the following example, the permissions of the sample file that were created previously are modified using the
octal method:

sysadmin@localhost:~/Documents$ ls -l sample.txt
---------- 1 sysadmin sysadmin 0 Mar 21 18:17 sample.txt
sysadmin@localhost:~/Documents$ chmod 754 sample.txt
sysadmin@localhost:~/Documents$ ls -l sample.txt
-rwxr-xr-- 1 sysadmin sysadmin 0 Mar 21 18:17 sample.txt

Consider This

Recall that the stat command provides more detailed information than the ls -l command. Because of this, you
may consider using the stat command instead of the ls -l command when viewing permissions on a file. One
big advantage of the stat command is that it shows permissions using both the symbolic and numeric methods, as
highlighted below:

sysadmin@localhost:~$ stat /tmp/filetest1


File: `/tmp/filetest1'
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 31477 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 502/sysadmin) Gid: ( 503/sysadmin)
Access: 2013-10-21 10:18:02.809118163 -0700
Modify: 2013-10-21 10:18:02.809118163 -0700
Change: 2013-10-21 10:18:02.809118163 -0700

13.5 Permission Scenarios


Before discussing changing or setting permissions, a solid understanding of how permissions really work is
required. Many beginning Linux users get hung up on the short descriptions of read, write, and execute, but these
words don't really define what a user can do with a file or directory.

To understand how permissions behave, several scenarios will be presented. While you review these scenarios,
keep in mind the following descriptions of how each permission behaves:

Permission Effect of File Effect on Directory


r
Allows processes to read the contents of the file, File names in the directory can be listed, but other
read
meaning the contents can be viewed and copied. details are not available.
Allows for contents to be written to by the
Files can be added to or removed from the
process, so changes to a file can be saved. Note
write w directory. Note that w permission requires x
that the w permission really requires the r
permission on the directory to work correctly.
permission on the file to work correctly.
Allows for the user to use the cd command to "get
x
Allows for a file to be executed or run as a into" the directory and use the directory in a
execute
process. pathname to access files and, potentially,
subdirectories under this directory.

For each scenario below, an example is provided to describe the directory hierarchy. In this example, key
permission information is provided for each file and directory. For example, consider the following:

drwxr-xr-x 1 root root 4096 Apr 23 21:08 /


drwxr-xr-x 1 root root 4096 Apr 23 21:08 /etc
-rw-r--r-- 1 root root 1455 Apr 17 22:31 /etc/passwd

The first line describes the / directory. The permissions are rwxr-xr-x, the user owner is root and the group
owner is root. The second line describes the etc directory, which is a subdirectory under the / directory. The third
line describes the passwd file, which is a file under the etc directory.

13.5.1 Scenario #1
Question

Given the following information, what can the user bob do with the /home/bob/test file?

drwxr-xr-x 1 root root 4096 Apr 23 21:08 /


drwxr-xr-x 1 root root 4096 Apr 17 22:31 /home
drwxr-xr-x 1 bob staff 4096 Apr 23 21:09 /home/bob
-r--r--r-- 1 bob staff 390 Apr 17 22:31 /home/bob/test
13.5.1.1 Answer
Question

Given the following information, what can the user bob do with the /home/bob/test file?

drwxr-xr-x 1 root root 4096 Apr 23 21:08 /


drwxr-xr-x 1 root root 4096 Apr 17 22:31 /home
drwxr-xr-x 1 bob staff 4096 Apr 23 21:09 /home/bob
-r--r--r-- 1 bob staff 390 Apr 17 22:31 /home/bob/test

Answer

The user bob can view and copy the file because this user has the permissions of r-- on the file.

13.5.2 Scenario #2
Question

Given the following information, can the user bob delete the /home/bob/test file?

drwxr-xr-x 1 root root 4096 Apr 23 21:08 /


drwxr-xr-x 1 root root 4096 Apr 17 22:31 /home
drwxr-xr-x 1 bob staff 4096 Apr 23 21:09 /home/bob
---------- 1 bob staff 390 Apr 17 22:31 /home/bob/test

13.5.2.1 Answer
Question

Given the following information, can the user bob delete the /home/bob/test file?

drwxr-xr-x 1 root root 4096 Apr 23 21:08 /


drwxr-xr-x 1 root root 4096 Apr 17 22:31 /home
drwxr-xr-x 1 bob staff 4096 Apr 23 21:09 /home/bob
---------- 1 bob staff 390 Apr 17 22:31 /home/bob/test

Answer

Yes. While it may seem like the user bob shouldn't be able to delete this file because he has no permissions on the
file itself, to delete a file a user needs to have write permission in the directory that the file is stored in. File
permissions do not apply when deleting a file.
13.5.3 Scenario #3
Question

Given the following information, can the user sue view the contents of the /home/bob/test file?

drwxr-xr-x 1 root root 4096 Apr 23 21:08 /


drwxr-xr-x 1 root root 4096 Apr 17 22:31 /home
drwxr--r-- 1 bob staff 4096 Apr 23 21:09 /home/bob
-r--r--r-- 1 bob staff 390 Apr 17 22:31 /home/bob/test

13.5.3.1 Answer
Question

Given the following information, can the user sue view the contents of the /home/bob/test file?

drwxr-xr-x 1 root root 4096 Apr 23 21:08 /


drwxr-xr-x 1 root root 4096 Apr 17 22:31 /home
drwxr--r-- 1 bob staff 4096 Apr 23 21:09 /home/bob
-r--r--r-- 1 bob staff 390 Apr 17 22:31 /home/bob/test

Answer

No. Initially it may seem that the user sue should be able to view the contents of the /home/bob/test file because
all users have read permission on the file.

However, when checking permissions, it is important to check the permissions on the parent directories of the file
in question. In this case, only the user bob has the ability to "get into" the /home/bob directory because only the
user bob has execute permission on that directory. If you can't get into a directory, it doesn't matter what the
permissions are set to on the files in that directory.

13.5.4 Scenario #4
Question

Given the following information, who can delete the /home/bob/test file?

drwxr-xr-x 1 root root 4096 Apr 23 21:08 /


drwxr-xr-x 1 root root 4096 Apr 17 22:31 /home
drwxrwxrwx 1 bob staff 4096 Apr 23 21:09 /home/bob
-rwx------ 1 bob staff 390 Apr 17 22:31 /home/bob/test
13.5.4.1 Answer
Question

Given the following information, who can delete the /home/bob/test file?

drwxr-xr-x 1 root root 4096 Apr 23 21:08 /


drwxr-xr-x 1 root root 4096 Apr 17 22:31 /home
drwxrwxrwx 1 bob staff 4096 Apr 23 21:09 /home/bob
-rwx------ 1 bob staff 390 Apr 17 22:31 /home/bob/test

Answer

All users on the system can. Recall that to delete a file, a user needs write and execute permissions on the directory
that the file is stored in. All users have write and execute permission on the /home/bob directory. This is a huge
mistake because now all users can delete all files in the home directory of the user bob.
13.6 Changing Advanced File Permissions
In most circumstances, the basic Linux permissions, read, write, and execute, are enough to accommodate the
security needs of individual users or organizations.

However, when multiple users need to work routinely on the same directories and files, these permissions may not
be enough. The special permissions setuid, setgid, and the sticky bit are designed to address these concerns.

Typically, special permissions are only set by the administrator (the root user) and they perform very specialized
functions. They can be set using the chmod command, using either the symbolic or octal method.

⁠ 
Octal
Permission Symbol Symbolic Purpose
Value
s u+s 4000
Causes an executable file to execute under user owner identity,
setuid on a file
instead of the user running the command.
s g+s 2000
Causes an executable file to execute under group owner identity,
setgid on a file
instead of the user running the command.
setgid on a s g+s 2000
Causes new files and directories that are created inside to be owned
directory by the group that owns the directory.
sticky on a t o+t 1000
Causes files inside a directory to be able to be removed only by the
directory user owner, or the root user.

Note

A leading 0, such as 0755, will remove all special permissions from a file or directory.

13.6.1 Setuid Permission


When the setuid permission is set on an executable binary file (a program), the binary file is run as the owner of the
file, not as the user who executed it. This permission is set on a handful of system utilities so that they can be run
by normal users, but executed with the permissions of root, providing access to system files that the normal user
doesn't normally have access to.

For example, the passwd command has the setuid permission. The passwd command modifies the /etc/shadow
file in order to update the value for the user's password. That file is not normally modifiable by an ordinary user; in
fact, ordinary users normally have no permissions on the file.

sysadmin@localhost:~$ more /etc/shadow


/etc/shadow: Permission denied
sysadmin@localhost:~$ ls -l /etc/shadow
-rw-r-----. 1 root root 5195 Oct 21 19:57 /etc/shadow

Since the passwd command is owned by the root user and has the setuid permission set, it executes with a "dual
personality", which allows it to access files either as the person who is running the command or as the root user.
When the passwd command attempts to update the /etc/shadow file, it uses the credentials of the root user to
modify the file (the term credentials is akin to "authority").

The following demonstrates what this setuid executable file looks like when listed with the ls -l command:
sysadmin@localhost:~$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 59640 Jan 25 2018 /usr/bin/passwd

Notice from the listing, the fourth character is an s, where there would normally be an x if this file was just
executable. When this character is a lowercase s, it indicates that both the setuid and execute permissions are set.
An uppercase S in the fourth character position means that the file does not have the execute permission, only the
setuid permission. Without the execute permission for the user owner, the setuid permission is ineffective, meaning
that the file will not be executable by the user owner even if the setuid permission is set. Although not always the
case, in some instances, an uppercase S can be interpreted as an error.

Like the read, write, and execute permissions, special permissions can be set with the chmod command, using either
the symbolic and octal methods.

To add the setuid permission symbolically, run:

chmod u+s file

To add the setuid permission numerically, add 4000 to the file's existing permissions (assume the file originally
had 775 for its permission in the following example):

chmod 4775 file

To remove the setuid permission symbolically, run:

chmod u-s file

To remove the setuid permission numerically, subtract 4000 from the file's existing permissions:

chmod 0775 file

Previously, we set permission with the octal method using three-digit codes. When a three-digit code is provided,
the chmod command assumes that the first digit before the three-digit code is 0. Only when four digits are specified
is a special permission set.

If three digits are specified when changing the permissions on a file that already has a special permission set, the
first digit will be set to 0, and the special permission will be removed from the file.

13.6.2 Setgid Permission


The setgid permission is similar to setuid, but it makes use of the group owner permissions. There are two forms of
setgid permissions: setgid on a file and setgid on a directory. The behavior of setgid depends on whether it is set on
a file or directory.
13.6.2.1 On a File
The setgid permission on a file works very similarly to the setuid permission, except that instead of executing as
the user who owns the file, setgid permission will execute as the group that owns the file. The system allows the
user running the command to effectively belong to the group that owns the file, but only in the setgid program. The
following displays the setgid executable file /usr/bin/wall when listed with the ls -l command:

sysadmin@localhost:~$ ls -l /usr/bin/wall
-rwxr-sr-x 1 root tty 30800 Oct 15 20:29 /usr/bin/wall

You can see that this file is setgid by the presence of the s in the execute position of the group permissions. Due to
this executable being owned by the tty group, when a user executes this command, the command is able to access
files that are group owned by the tty group.

This access is important because the /usr/bin/wall command sends messages to terminals, which is
accomplished by writing data to files like the following:

sysadmin@localhost:~$ ls -l /dev/tty?
crw--w----. 1 root tty 4, 0 Mar 29 2013 /dev/tty0
crw--w----. 1 root tty 4, 1 Oct 21 19:57 /dev/tty1

Note that the tty group has write permission on the files above while users who are not in the tty group (others)
have no permissions on these files. Without the setgid permission, the /usr/bin/wall command would fail.

Like the setuid permission, a lowercase s in the execute position of the group permissions indicates that this file
has both the setgid and execute permission set. An uppercase S instead of the s means the file lacks execute
permission for the group. Without execute permission for the group, the setgid permission will be ineffective.

Consider This

The way that the Linux kernel restricts both setuid and setgid executables is stricter than some UNIX
implementations. While Linux doesn't prevent users from setting these permissions on script files, the Linux kernel
will not execute scripts with setuid or setgid permissions.

In order to effectively set these permissions, the Linux kernel will only honor them on executable files that are in a
binary format. This increases the security of the system.

13.6.2.2 On a Directory
In most cases, once the installation of a Linux distribution is complete, the files that require setuid and setgid
permissions should have those permissions automatically set. While some of the setuid and setgid permissions on
files may be removed for security reasons, very seldom are new setuid or setgid files created. On the other hand, it
is fairly common for administrators to add setgid to directories.

When set on a directory, the setgid permission causes files created in the directory to be owned by the group that
owns the directory automatically. This behavior is contrary to how new file group ownership would normally
function, as by default new files are group owned by the primary group of the user who created the file.
In addition, any directories created within a directory with the setgid permission set are not only owned by the
group that owns the setgid directory, but the new directory automatically has setgid set on it as well. In other
words, if a directory is setgid, then any directories created within that directory inherit the setgid permission.

The following example shows that the /tmp/data directory has the setgid permission set and that it is owned by
the demo group.

sysadmin@localhost:~$ ls -ld /tmp/data


drwxrwsrwx. 2 root demo 4096 Oct 30 23:20 /tmp/data

Note

The /tmp/data directory used in the example above is used to demonstrate setuid permission on a directory. It
does not exist in our virtual environment.

In a long listing, the setgid permission is represented by an s in the group execute position. A lowercase s means
that both setgid and group execute permissions are set:

drwxrwsrwx. 2 root demo 4096 Oct 30 23:20 /tmp/data

An uppercase S means that only setgid and not group execute permission is set. If you see an uppercase S in the
group execute position of the permissions, then it indicates that although the setgid permission is set, it is not really
in effect because the group lacks the execute permission to use it.

Typically, files created by the user sysadmin are owned by their primary group, also called sysadmin. However, if
the user sysadmin creates a file in the /tmp/data directory (the setgid directory from the preceding example), the
group ownership of the file isn't the sysadmin group, but rather the group that owns the directory, the demo group:

sysadmin@localhost:~$ touch /tmp/data/file.txt


sysadmin@localhost:~$ ls -ld /tmp/data/file.txt
-rw-rw-r--. 1 bob demo 0 Oct 30 23:21 /tmp/data/file.txt

Using setgid on a directory can be extremely helpful for users trying to share a directory of files with other users
who are in different groups. To understand why, consider the following scenario.

First, consider the following user accounts:

 The user joe is a member of the staff group.


 The user maya is a member of the payroll group.
 The user steve is a member of the acct group.

In this scenario, these three users need to work on a joint project. They approach the administrator to ask for a
shared directory in which they can work together, but that no one else can access their files. The administrator does
the following:

 Creates a new group called team.


 Adds joe, maya, and steve to the team group.
 Makes a new directory called shared under the /srv directory.
 root@localhost:~# mkdir /srv/shared
 Makes the team group the group owner of the shared directory.
 root@localhost:~# chgrp team /srv/shared
 Make the shared directory writable for the group by giving it the rwxrwx--- permissions:
 root@localhost:~# chmod 770 /srv/shared
 root@localhost:~# ls -ld /srv/shared
 drwxrwx--- 2 root team 4096 Mar 28 02:14 /srv/shared

This solution is almost perfect: the users joe, maya and steve can now access the /srv/shared directory and add
new files. However, there is a potential problem, because the user joe is a member of the staff group, when joe
makes a new file in the /srv/shared directory, the new file is owned by the staff group:

-rw-rw----. 2 joe staff 8987 Jan 10 09:08 staffdocument.txt

The problem with this is that neither maya or steve are members of the staff group. As a result, their permissions
are ---, which means they can't access the contents of this file.

The user joe could have used the newgrp command to switch to the team group before creating the file. Or, after
creating the file, the user joe could have used the chgrp command to change the group ownership to the common
group. However, users won't always remember to run these commands; some may not even know that these
commands exist.

Instead, the administrator can set up a directory with setgid permission. If a directory is setgid, then all new files
created or copied into the directory will automatically be owned by the group that owns the directory. This means
users don't have to use the newgrp or chgrp commands because the group ownership will be managed
automatically.

So, a better solution to this scenario would be to set the setgid permission on the /srv/shared directory using the
following command:

root@localhost:~# chmod 2775 /srv/shared

Listing the details of the directory after running the previous command would result in the following output:

drwxrwsr-x. 2 root team 4096 Jan 10 09:08 /srv/shared

After completing these steps, the joe, maya, and steve users would now be able to easily create files in the
/srv/shared directory that would automatically be owned by the team group.
13.6.2.3 Setting Setgid
Use the following syntax to add the setgid permission symbolically:

chmod g+s <file|directory>

To add the setgid permission numerically, add 2000 to the file's existing permissions (assume in the following
example that the directory originally had 775 for its permissions):

chmod 2775 <file|directory>

To remove the setgid permission symbolically, run:

chmod g-s <file|directory>

To remove the setgid permission numerically, subtract 2000 from the file's existing permissions:

chmod 0775 <file|directory>

13.6.3 Sticky Bit Permission


The final advanced permission to discuss is the sticky permission, which is sometimes called the sticky bit. Setting
this permission can be important to prevent users from deleting other user's files.

Recall that to be able to delete a file, only the write and execute permissions on the directory are necessary. The
write and execute permissions are also necessary to add files to a directory. So, if an administrator wants to make a
directory where any user can add a file, the required permissions mean that the user can also delete any other user's
file in that directory.

The sticky permission on a directory modifies the write permission on a directory so that only specific users can
delete a file within the directory:

 The user who owns the file.


 The user who owns the directory that has the sticky bit set (typically this is the root user).
 The root user.

On a typical Linux installation, there will normally be two directories that have the sticky permission set by
default: the /tmp and /var/tmp directories. Besides user home directories, these two directories are the only
locations that regular users have write permission for by default.

As their name suggests, these directories are intended to be used for temporary files. Any user can copy files to the
/tmp or /var/tmp directories to share with others.

Since the /tmp or /var/tmp directories have the sticky permission, you don't have to worry about users deleting
the shared files. However, there is a reason that these directories are considered temporary: these directories are
automatically purged of their contents on a regular schedule. If you put a file in them, it will be removed
automatically at some point in the future.
To set the sticky bit permission symbolically, execute a command like the following:

chmod o+t <directory>

To set the sticky bit permission numerically, add 1000 to the directory's existing permissions (assume the directory
in the following example originally had 775 for its permissions):

chmod 1775 <file|directory>

To remove the sticky permission symbolically, run:

chmod o-t <directory>

⁠To remove the sticky bit permission numerically, subtract 1000 from the directory's existing permissions:

chmod 0775 <directory>

When a directory has the sticky permission, a t will replace the x in the set of permissions for others. For example,
the following shows the permissions of the /tmp directory:

sysadmin@localhost:~$ ls -ld /tmp


drwxrwxrwt 1 root root 0 Oct 17 19:17 /tmp

The /tmp directory has an octal permission mode of 1777, or full permissions for everyone plus the sticky
permission on the directory. When the others permission set includes the execute permission, then the t will be in
lowercase. If there is an uppercase T, it means that the execute permission is not present for others. This does not
mean that the directory does not have an effective sticky permission; however, it does mean that the users who are
affected by the others permission can't change to this directory or create files in the directory.

There are cases in which users may not want to have the execute permission for others, but still have the sticky bit
permission on a directory. For example, when creating shared directories with the setgid permission. Consider the
following command:

root@localhost:~# chmod 3770 /shared

Notice that the special permissions of setgid and sticky bit can be added together, the 2000 permission plus the
1000 permission gives you 3000 for the special permissions. Add this to the basic permissions for the user, group,
and others; The owner and group have full access, and others get none. Listing the directory after making the
changes with the ls -ld /shared command results in the following output:

drwxrws--T. 2 root team 4096 Jan 10 09:08 /shared

The uppercase T in the execute permission position for others indicates there is no execute permission for others.
However, since multiple users of the group still have access, the sticky permission is effective for the team group.
13.7 Default File Permissions
Unlike other operating systems where the permissions on a new directory or file may be inherited from the parent
directory, Linux sets the default permissions on these new objects based upon the value of the creator's umask
setting. The umask command is used to both set the umask value and display it.

The umask command is automatically executed when a shell is started. To have a persistent setting for umask, a
custom umask command can be added to the ~/.bashrc file.

To customize the umask value, it is first important to understand what the umask value does. The umask value only
affects the permissions placed on new files and directories at the time they are created. It only affects the basic
permissions for the user owner, the group owner, and others. The umask value does not affect the special advanced
permissions of setuid, setgid, or sticky bit.

The umask is an octal value based upon the same values that you saw earlier in this section:

Octal Value Permission


4 read
2 write
1 execute
0 none

When using the chmod command with octal values, add together the values for the user, the group, and others.
However, the umask octal value is used to specify permissions to be removed. In other words, the octal value set
for the umask is subtracted from the maximum possible permission to determine the permissions that are set when
a file or directory is created.

The maximum default permissions are different for files and directories:

Files Type Octal Symbolic


Files 666 rw-rw-rw-
Directories 777 rwxrwxrwx

Three digits are provided, representing the octal values of the permissions to remove for the user owner, the group
owner, and others respectively. Recall the octal values for the permission sets:

Octal Value Permission Set


7 rwx
6 rw-
5 r-x
4 r--
3 -wx
2 -w-
1 --x
0 ---

The umask command can be used to display the current umask value:
sysadmin@localhost:~$ umask
0002

A breakdown of the output:

 The initial 0 in the umask value is for special permissions (setuid, setgid and sticky bit). Since those are
never set by default, the initial 0 is not necessary when setting the umask value.
 The second 0 (---) indicates which permissions to subtract from the default user owner's permissions.
 The third 0 (---) indicates which permissions to subtract from the default group owner's permissions.
 The last number 2 (-w-) indicates which permissions to subtract from the default other's permissions.

13.7.1 Understanding Umask for Files


By default, the maximum permissions that will be placed on a brand-new file are rw-rw-rw-, which can be
represented octal as 666. The execute permission is turned off for security reasons. The umask value can be used to
specify which of these default permissions to remove for new files. Three digits are provided, representing octal
values of the permissions to remove for the user owner, the group owner, and others respectively.

For example, to set a umask value for new files that would result in default permissions for the owner, remove or
"mask" write permissions for the group owner and remove all permissions from others, calculate the umask value
as follows:

 The first digit for the user owner would be a 0 (---), which would not mask any of the default permissions.
 The second digit would be a 2 (-w-), which would mask only the write permission.
 The third digit would be a 6 (rw-), which would mask the read and write permissions.

As a result, the umask value 026 would result in new files having the permissions of rw-r-----.

File Default 666 rw-rw-rw-


Umask -026 ----w-rw-
Result 640 rw-r-----

Another Example: To set a umask value for new files that would remove write permissions for the owner and
remove read and write permissions for the group and others, calculate the umask value as follows:

 The first digit for the user owner would be a 2 (-w-), which would mask only the write permission.
 The second digit would be a 6 (rw-), which would mask the read and write permissions.
 The third digit would be a 6 (rw-), which would mask the read and write permissions.

As a result, the umask value 266 would result in new files having the permissions of r--------.

File Default 666 rw-rw-rw-


Umask -266 -w-rw-rw-
Result 600 r--------
13.7.2 Understanding Umask for Directories
The way the umask is applied to regular files is different from directory files. For security reasons, regular files are
not allowed to be executable at the time they are created. It would be dangerous to allow for a file to be able to run
as a process without a user explicitly assigning the execute permission. So, regardless of whether you include the
execute permission in the umask value, it will not apply to regular files.

For directories, the execute permission is critical to access the directory properly. Without the execute permission,
you cannot navigate to a directory, and the write permission is not functional. Essentially, directories are not very
useful at all without execute permission, so new directories are allowed to be executable by default. The default
permissions for new directories is rwxrwxrwx or 777.

For example, if you wanted a umask value for new directories that would result in full permissions for the user
owner, remove or mask write permissions for the group owner, and remove all permissions from others, then you
could calculate the umask value as follows:

 The first digit for the user owner would be a 0 (---), which would not mask any of the default permissions.
 The second digit would be a 2 (-w-), which would mask only the write permission.
 The third digit would be a 7 (rwx), which would mask all the default permissions.

As a result, the umask value 027 would result in new directories having the permissions of rwxr-x---.

Directory Default 777 rwxrwxrwx


Umask -027 ----w-rwx
Result 750 rwxr-x---

Very Important

While the umask value affects the permissions for new files and directories differently (because of different
maximum permissions), there is not a separate umask value for files and directories; the single umask value applies
to both, as you can see from the following table of commonly used umask values:

Umask File Permissions Directory Permissions Description


002 664 rw-rw-r-- 775 rwxrwxr-x Default for ordinary users
022 644 rw-r--r-- 755 rwxr-xr-x Default for root user
007 660 rw-rw---- 770 rwxrwx--- No access for others
077 600 rw------- 700 rwx------ Private to user

The following commands will display the current umask value, sets it to a different value and displays the new
value:

sysadmin@localhost:~$ umask
0002
sysadmin@localhost:~$ umask 027
sysadmin@localhost:~$ umask
0027
Key Terms
chgrp
Command that is used to change the primary group of a file. Essentially it changes what group is the owner
of the FILE.
Section 13.2.4
chmod
Command that is used to change the mode bits of a FILE. The chmod utility can be used to change the files
permissions. For example setting the read, write, and execute bits.
Section 13.4
chown
Command that is used to change the ownership of a FILE. The chown utility can also be used to change the
primary group of a FILE as well.
Section 13.2.2
umask
Command that sets the calling process's file mode creation mask. The umask utility will set the default
permissions for FILEs when they are created.
Section 13.7
LAB 13

13.0 Introduction
In this task, you will explore both basic and advanced file permissions. You will display file permissions, set basic
permissions (read, write, and execute) and set advanced permissions (setuid, setgid, and sticky bit).

In addition, you will display and set the umask value, which determines the default permissions to place on new
files and directories.

13.1 Step 1
In order to access or modify a file or directory, the correct permissions must be set. There are three different
permissions that can be placed on a file or directory: read, write, and execute.

Execute the following command to list details about the /etc/shadow file:

ls -l /etc/shadow
sysadmin@localhost:~$ ls -l /etc/shadow
-rw-r----- 1 root shadow 968 Apr 17 22:31 /etc/shadow

The following is a breakdown of the fields relevant to file and directory permissions:

File Type Field


-rw-r----- 1 root shadow 968 Apr 17 22:31 /etc/shadow

The first character of this output indicates the type of a file. Recall if the first character is a dash - character, as it is
in the output above, this is a regular file. If the character was a letter d, it would be a directory.

Permissions Field
-rw-r----- 1 root shadow 968 Apr 17 22:31 /etc/shadow

After the file type character, the permissions are displayed.

User Owner Field


-rw-r----- 1 root shadow 968 Apr 17 22:31 /etc/shadow

After the link count, the file's user owner is displayed.

Group Owner Field


-rw-r----- 1 root shadow 968 Apr 17 22:31 /etc/shadow

After the user owner field, the file group owner is displayed.
Note that the user owner of the /etc/shadow file is the root user and that the group owner is the shadow group.
The user owner has read and write permission (rw-), the group owner only has the read permission (r--), and
regular users have no permissions (---).

3.2 Step 2
Execute the following command to attempt to view the /etc/shadow file:

more /etc/shadow
sysadmin@localhost:~$ more /etc/shadow
more: cannot open /etc/shadow: Permission denied

The command failed because only the root user and the members of the shadow group can view the contents of
this file.

13.3 Step 3
Execute the following command to switch to the root account. When prompted, provide the root password
netlab123:

su – root
sysadmin@localhost:~$ su - root
Password:
root@localhost:~#

13.4 Step 4
Create a file in the /srv directory by executing the following command:

echo "learning about permissions" > /srv/lab.txt


root@localhost:~# echo "learning about permissions" > /srv/la

13.5 Step 5
View the permissions of this file and notice that all users can view the file contents since all users have read
permission for the file:

ls -l /srv/lab.txt
Be aware that both instances in the command above use a lowercase "L", not a number one.
root@localhost:~# ls -l /srv/lab.txt
-rw-r--r-- 1 root root 27 May 16 12:29 /srv/lab.txt
13.6 Step 6
Execute the following command to switch back to the sysadmin account:

exit
root@localhost:~# exit
logout
sysadmin@localhost:~$

13.7 Step 7
Verify that the sysadmin account can view the file contents by executing the following command:

more /srv/lab.txt
sysadmin@localhost:~$ more /srv/lab.txt
learning about permissions

13.8 Step 8
Execute the following command to switch to the root account. When prompted, provide the root password:

su – root
netlab123
sysadmin@localhost:~$ su - root
Password:
root@localhost:~#

13.9 Step 9
The chmod command is used to change the permissions of a file or directory. Only the root user or the user who
owns the file is able to change the permissions of a file.

chmod MODE FILE…

There are two techniques of changing permissions with the chmod command: symbolic and octal. To use the
symbolic method of chmod, use the symbols summarized in the table below:

Group Symbol Operation Symbol Permission Symbol


u (user owner) + (add the permission) r (read)
g (group owner) = (specify the exact permission) w (write)
o (others) - (remove the permission) x (execute)
a (all)

Remove the ability of the sysadmin account (who belongs to the others permission set) to view the /srv/lab.txt
file by executing the following command:
chmod o-r /srv/lab.txt
root@localhost:~# chmod o-r /srv/lab.txt

13.10 Step 10
Verify the permission change by executing the following command:

ls -l /srv/lab.txt
root@localhost:~# ls -l /srv/lab.txt
-rw-r----- 1 root root 27 May 16 12:29 /srv/lab.txt

Notice that the read permission has been removed in the others permission set.

13.11 Step 11
Execute the following command to switch back to the sysadmin account:

exit
root@localhost:~# exit
logout
sysadmin@localhost:~$

3.12 Step 12
Verify that the sysadmin account cannot view the file contents by executing the following command:

more /srv/lab.txt
sysadmin@localhost:~$ more /srv/lab.txt
more: cannot open /srv/lab.txt: Permission denied

13.13 Step 13
Execute the following command to switch to the root account. When prompted, provide the root password:

su – root
netlab123
sysadmin@localhost:~$ su - root
Password:
root@localhost:~#
13.14 Step 14
Execute the following command to provide members of the others permission set the ability to both view and
modify the /srv/lab.txt file:

chmod o+rw /srv/lab.txt


root@localhost:~# chmod o+rw /srv/lab.txt
root@localhost:~#

13.15 Step 15
Verify the permission change by executing the following command:

ls -l /srv/lab.txt
root@localhost:~# ls -l /srv/lab.txt
-rw-r--rw- 1 root root 27 May 16 12:29 /srv/lab.txt
Recall that you would not normally provide others with more permissions than provided to the group members.

13.16 Step 16
Execute the following command to switch back to the sysadmin account:

exit
root@localhost:~# exit
logout
sysadmin@localhost:~$

13.17 Step 17
Verify that the sysadmin account can modify the lab.txt file contents by executing the following command:

echo "well done" >> /srv/lab.txt


sysadmin@localhost:~$ echo "well done" >> /srv/lab.txt
13.18 Step 18
Verify that the sysadmin account can view the lab.txt file contents by executing the following command:

more /srv/lab.txt
sysadmin@localhost:~$ more /srv/lab.txt
learning about permissions
well done

13.19 Step 19
Execute the following command to switch to the root account. When prompted, provide the root password:

su – root
netlab123
sysadmin@localhost:~$ su - root
Password:
root@localhost:~#

3.20 Step 20
Create a directory called /srv/data by executing the following command:

mkdir /srv/data
root@localhost:~# mkdir /srv/data

13.21 Step 21
Changing permissions using the octal method requires that the permissions for all three sets be specified. It is based
on the octal numbering system in which each permission type is assigned a numeric value:

Octal Value Permission


4 read
2 write
1 execute
0 none

By adding together the combination of numbers from 0 to 7, any possible combination of read, write, and execute
permissions can be specified for a single permission group set. For example, for read, write, and execute: add 4 + 2
+ 1 to get 7. Or, for read, not write, and execute: add 4 + 0 + 1 to get 5.

Change the permissions on the /srv/data directory, so only members of the group owner and the user owner have
access to this directory:
chmod 770 /srv/data
root@localhost:~# chmod 770 /srv/data

13.22 Step 22
Verify the changed permissions by executing the following command:

ls -ld /srv/data
root@localhost:~# ls -ld /srv/data
drwxrwx--- 2 root root 4096 May 16 16:31 /srv/data

13.23 Step 23
Copy a file into the /srv/data directory to verify that the current user (the root user) can create files in this
directory. Recall that for the following command to be successful, the user must have both write and execute
permission on the directory:

cp /etc/hosts /srv/data
ls /srv/data
root@localhost:~# cp /etc/hosts /srv/data
root@localhost:~# ls /srv/data
hosts

13.24 Step 24
Execute the following command to switch back to the sysadmin account:

exit
root@localhost:~# exit
logout
sysadmin@localhost:~$

13.25 Step 25
Execute the following command. This command should fail because the current user has no permission to access
this directory:

ls /srv/data
sysadmin@localhost:~$ ls /srv/data
ls: cannot open directory '/srv/data': Permission denied
13.26 Step 26
When the setuid permission is set on an executable binary file (a program), the binary file is run as the owner of
the file, not as the user who executed it. In the next few steps, we will demonstrate the use of setuid files. Start by
viewing the permissions of the /usr/bin/chfn file by executing the following command:

ls -l /usr/bin/chfn
sysadmin@localhost:~$ ls -l /usr/bin/chfn
-rwsr-xr-x 1 root root 76496 Jan 25 2018 /usr/bin/chfn

Recall that the s character in the owner's permission set means that this is a setuid file. When executed, this
program can access files as if the program was run as the root user (the owner of the file). This special permission
allows users to change the information in the /etc/passwd file.

13.27 Step 27
Execute the following command to change your account information. When prompted, provide the sysadmin
password: netlab123:

chfn

Enter the following information when prompted:

Room Number []: 123


Work Phone []: 888-555-5555
Home Phone []: 888-555-5555
sysadmin@localhost:~$ chfn
Password:
Changing the user information for sysadmin
Enter the new value, or press ENTER for the default
Full Name: System Administrator
Room Number []: 123
Work Phone []: 888-555-5555
Home Phone []: 888-555-5555

13.28 Step 28
Execute the following command to switch to the root account. When prompted, provide the root password:

su – root
netlab123
sysadmin@localhost:~$ su - root
Password:
root@localhost:~#
13.29 Step 29
Typically, special permissions are only set by the administrator (the root user), and they perform very specialized
functions. They can be set using the chmod command, using either the symbolic or octal method.

Change the /usr/bin/chfn file, so it is no longer setuid by executing the following command:

chmod 0755 /usr/bin/chfn


root@localhost:~# chmod 0755 /usr/bin/chfn
root@localhost:~#

13.30 Step 30
Verify this change by executing the following command:

ls -l /usr/bin/chfn
root@localhost:~# ls -l /usr/bin/chfn
-rwxr-xr-x 1 root root 76496 Jan 25 2018 /usr/bin/chfn

13.31 Step 31
Execute the following command to switch back to the sysadmin account:

exit
root@localhost:~# exit
logout
sysadmin@localhost:~$

13.32 Step 32
Execute the following command to attempt to change your account information. When prompted, provide the root
password:

chfn
netlab123

Enter the following information when prompted:

Room Number []: 123


Work Phone []: 888-555-5555
Home Phone []: 888-555-5555
sysadmin@localhost:~$ chfn
Password:
Changing the user information for sysadmin
Enter the new value, or press ENTER for the default
Full Name: System Administrator
Room Number [123]: 123
Work Phone [888-555-5555]: 888-555-5555
Home Phone [888-555-5555]: 888-555-5555
Cannot change ID to root.

Note that the error message Cannot change ID to root indicates that you cannot use this command because it
cannot access the /etc/passwd file as the root user. Without the setuid permission, this command will not work
for regular users.

13.33 Step 33
The setgid permission is similar to setuid, but it makes use of the group owner permissions. In the next few steps,
we will demonstrate the use of setgid directories. Start by executing the following command to switch to the root
account. When prompted, provide the root password:

su – root
netlab123
sysadmin@localhost:~$ su - root
Password:
root@localhost:~#

13.34 Step 34
Make a directory and check its permissions by executing the following commands:

mkdir /srv/test
ls -ld /srv/test
root@localhost:~# mkdir /srv/test
root@localhost:~# ls -ld /srv/test
drwxr-xr-x 2 root root 4096 May 17 00:56 /srv/test

13.35 Step 35
It is possible for the user owner of a file or directory to change the group owner of that same file/directory by using
the chgrp command. Verify that the team group exists and then change the group ownership of the /srv/test
directory to the team group by executing the following commands:

chgrp team /srv/test


ls -ld /srv/test
root@localhost:~# grep team /etc/group
team:x:1004:
root@localhost:~# chgrp team /srv/test
root@localhost:~# ls -ld /srv/test
drwxr-xr-x 2 root team 4096 May 17 00:56 /srv/test

The chgrp command was used above to change the group owner of the /srv/test directory from the default
primary group root to the group team.
13.36 Step 36
Normally, when you create a new file, the group ownership of the new file is set to your primary group. Create a
new file called labfile.txt in the /srv/test directory and verify by executing the following commands:

touch /srv/test/labfile.txt
ls -l /srv/test/labfile.txt
root@localhost:~# touch /srv/test/labfile.txt
root@localhost:~# ls -l /srv/test/labfile.txt
-rw-r--r-- 1 root root 0 May 17 01:14 /srv/test/labfile.txt

The group owner of this new file is the root user's primary group, which is also called root.

13.37 Step 37
If the directory has the setgid permission set, then all new files created in the directory will be owned by the same
group that owns the directory. Use the following commands to set the setgid permission on the /srv/test
directory and verify the new permissions. You should see an s where the group execute permission should be:

chmod g+s /srv/test


ls -ld /srv/test
root@localhost:~# chmod g+s /srv/test
root@localhost:~# ls -ld /srv/test
drwxr-sr-x 2 root team 4096 May 17 01:14 /srv/test

13.38 Step 38
Verify that the setgid permission works by executing the following commands:

touch /srv/test/labfile2.txt
ls -l /tmp/test/labfile2.txt
root@localhost:~# touch /srv/test/labfile2.txt
root@localhost:~# ls -l /srv/test/labfile2.txt
-rw-r--r-- 1 root team 0 May 17 01:23 /srv/test/labfile2.txt

Notice that this new file is group owned by the team group, not the root group.

13.39 Step 39
In the next few steps, we will demonstrate the use of sticky bit directories. Start by creating a new directory by
executing the following commands:

mkdir /pub
chmod 777 /pub
ls -ld /pub
root@localhost:~# mkdir /pub
root@localhost:~# chmod 777 /pub
root@localhost:~# ls -ld /pub
drwxrwxrwx 2 root root 4096 Apr 18 20:10 /pub
13.40 Step 40
The permissions on this new directory will allow any user to create and delete files in the directory. To test this,
first, create a file:

touch /pub/mylabfile
ls -l /pub
root@localhost:~# touch /pub/mylabfile
root@localhost:~# ls -l /pub
total 0
-rw-r--r-- 1 root root 0 May 17 01:28 mylabfile

13.41 Step 41
Execute the following command to switch back to the sysadmin account:

exit
root@localhost:~# exit
logout
sysadmin@localhost:~$

13.42 Step 42
Execute the following command to delete the previously created file. When prompted with the message, rm:
remove write-protected regular empty file `/pub/myfile'?, type the Y key and then press Enter:

rm /pub/mylabfile
Y
Enter
ls -l /pub
sysadmin@localhost:~$ rm /pub/mylabfile
rm: remove write-protected regular empty file '/pub/myfile'? y
sysadmin@localhost:~$ ls -l /pub
total 0

Notice that the sysadmin user was able to delete a file owned by the root user. This is because the write
permission of a directory grants the ability to add and delete files in a directory.

13.43 Step 43
Execute the following command to switch to the root account. When prompted, provide the root password:

su – root
netlab123
sysadmin@localhost:~$ su - root
Password:
root@localhost:~#
13.44 Step 44
Add the sticky bit permission to the /pub directory so users can only delete the files that they own in this directory,
then verify the permissions with the following commands:

chmod o+t /pub


ls -ld /pub
root@localhost:~# chmod o+t /pub
root@localhost:~# ls -ld /pub
drwxrwxrwt 2 root root 4096 Apr 18 20:12 /pub

3.45 Step 45
Again, create a file called mylabfile in this directory that can be used to test the new permission set:

touch /pub/mylabfile
ls -l /pub
root@localhost:~# touch /pub/mylabfile
root@localhost:~# ls -l /pub
total 0
-rw-r--r-- 1 root root 0 May 17 02:22 mylabfile

13.46 Step 46
Execute the following command to switch back to the sysadmin account:

exit
root@localhost:~# exit
logout
sysadmin@localhost:~$

13.47 Step 47
Execute the following commands to attempt to delete the previously created file. When prompted with the
message, rm: remove write-protected regular empty file `/pub/myfile'?, type the Y key and then press
Enter:

rm /pub/mylabfile
Y
Enter
ls -l /pub
sysadmin@localhost:~$ rm /pub/mylabfile
rm: remove write-protected regular empty file '/pub/mylabfile'? y
rm: cannot remove '/pub/mylabfile': Operation not permitted
sysadmin@localhost:~$ ls -l /pub
total 0
-rw-r--r-- 1 root root 0 Apr 18 20:16 myfile

Notice that this time, the sysadmin user was not able to delete the mylabfile file.
13.48 Step 48
In the next few steps, we will demonstrate the use of the umask command. Start by creating a file called
mysample.txt and viewing its permissions by executing the following commands:

touch mysample.txt
ls -l mysample.txt
sysadmin@localhost:~$ touch mysamplefile.txt
sysadmin@localhost:~$ ls -l mysamplefile.txt
-rw-rw-r-- 1 sysadmin sysadmin 0 May 17 02:30 mysamplefile.txt

Note that the default permissions of the mysample.txt file are rw-rw-r--. This is the result of the umask value of
002. The umask is an octal value based upon the same values as the ones used for setting permissions earlier in the
lab except that for permissions, you add together the values for the user, the group, and others. However, the umask
octal value is used to specify permissions to be removed.

4 read
2 write
1 execute
0 none

Execute the following command to see the current umask setting:

umask
sysadmin@localhost:~$ umask
0002
It may be confusing that there is a fourth value in the output of the previous umask command. This is because there
are technically four sets of permissions: user owner, group owner, others, and special permissions (the first 0 in the
output above). Since special permissions are never set by default, the initial 0 is not necessary when setting the
umask value. As a result, this extra value will be largely ignored during this lab.

13.49 Step 49
To set a umask value for new files that would result in default permissions for the owner, remove write permissions
for the group owner and remove all permissions from others, the umask value would be 026:

File Default 666 rw-rw-rw-


Umask -026 ----w-rw-
Result 640 rw-r-----

Execute the following commands to change the umask setting to 026 and verify that new files now have a
permission set of rw-r-----:

umask 026
touch mytestfile.txt
ls -l mytestfile.txt
sysadmin@localhost:~$ umask 026
sysadmin@localhost:~$ touch mytestfile.txt
sysadmin@localhost:~$ ls -l mytestfile.txt
-rw-r----- 1 sysadmin sysadmin 0 May 17 02:41 mytestfile.txt
File Default 666 rw-rw-rw-
Umask -027 ----w-rw-
Result 640 rw-r-----

Remember that a umask value only affects new files and directories. Any existing file will never be affected by the
umask value.

The umask value is designed to make it easy for you to specify default permissions for new files and directories.
By choosing a good umask value, you save yourself a lot of effort in the future since you won't have to change
permissions on new files and directories very often.

13.50 Step 50
Execute the following commands to create a new directory called mydir1 and verify that the umask value of 027
results in permissions for new directories of rwxr-x---:

mkdir mydir1
ls -ld mydir1
sysadmin@localhost:~$ mkdir mydir1
sysadmin@localhost:~$ ls -ld mydir1
drwxr-x--- 2 sysadmin sysadmin 4096 Apr 18 20:24 mydir1
Directory Default 777 rwxrwxrwx
Umask -027 ----w-rwx
Result 640 rwxr-x---

13.51 Step 51
Execute the following commands to change the umask to 002 and verify that this results in all new directories
having the permission set of rwxrwxr-x:

umask 002
mkdir mydir2
ls -ld mydir2
sysadmin@localhost:~$ umask 002
sysadmin@localhost:~$ mkdir mydir2
sysadmin@localhost:~$ ls -ld mydir2
drwxrwxr-x 2 sysadmin sysadmin 4096 Apr 18 20:25 mydir2
Recall that umask values, when set in the shell, are not permanent. To make a umask that will apply to every shell
that you open, add the umask command line to your ~/.bashrc file.
Chapter 14: Filesystem Links

14.1 Introduction
Linux provides two different kinds of links for files within the filesystem: hard links and soft links. Both provide
the ability to have more than one path name that refers to the same file, but each has its own advantages and
disadvantages.

14.2 Soft Links


Soft links, also known as symbolic links, are files that are designed to point to other files via path names. For
example, the /bin/systemd file is a symbolic link that links to /lib/systemd/systemd.

If it seems odd that anyone would want a file that points to another file, then consider the "Shortcuts" located on
most desktops and menu bars. It is common for users to place icons on the Desktop that, when clicked, will run a
program or open a file. Those icons are actually files that point to other files; in other words, those icons are soft
links.

As the Linux system grows and transforms, the organization of programs also changes. To retain some backward
compatibility for programs and processes, and to make it easier for users and administrators, symbolic links are
created which allow the use of programs from their legacy locations.

Another advantage of using links is that as programs are updated and version numbers change, administrators don’t
need to remember the exact file name, version, and extension to run the program—as long as the link points to the
current program. Sometimes entire command names are switched out, but the old name is kept as an alias; for
example, the vi command runs vim. Symbolic links on the system are stored in the /etc/alternatives directory
where they are managed by the alternatives system. The alternatives system manages, maintains, and updates
information about the symbolic links so that system administrators can define which program and version are run
when a user types a generic command.

This system allows developers to update information about their programs in the appropriate file in the
/etc/alternatives directory. Additionally, system administrators can modify these files to specify which
program is executed when the user types a command. So, if a user types ls at the prompt, it can be interpreted by
the system as ls.bin.1.1.2, or new_ls.bin.00.2.1.37.x, or whichever file needs to respond to the basic
command typed into the console.

Links are organized into groups according to the functionality that the programs have. By default, the system
automatically takes care of updating these groups when program files are installed or updated. This way, most
users do not need to be aware of changes in the underlying program files that provide the functionality required
when they invoke a program.

Consider This

More detail about the alternatives system can be found in the update-alternatives man page:

sysadmin@localhost:~$ man update-alternatives


Soft links are very visual compared to hard links. This is because soft links are distinguishable by their file type.

For example, a detailed listing of the /bin/systemd file shows that it is a symbolic link that points to the
/lib/systemd/systemd file:

sysadmin@localhost:~$ ls -l /bin/systemd
lrwxrwxrwx 1 root root 20 Feb 28 21:03 /bin/systemd -> /lib/systemd/systemd

While this is helpful for regular users, it can sometimes be a disadvantage, as certain programs may refuse to work
with the symbolic link type file and might require a regular file.

In a detailed listing of a symbolic link, notice that the first character preceding the permissions is the letter l:

lrwxrwxrwx 1 root root 20 Feb 28 21:03 /bin/systemd -> /lib/systemd/systemd


⁠ 

The other thing to notice about listing a soft link is that the link file name is followed by an arrow, which points to
a path name:

lrwxrwxrwx 1 root root 20 Feb 28 21:03 /bin/systemd -> /lib/systemd/systemd

When accessing the /bin/systemd file, the link is followed, and the /lib/systemd/systemd file is accessed
instead. In other words, the less /bin/systemd command will really display the content of the
/lib/systemd/systemd file.

The permissions that appear on the soft link only determine who may attempt to follow the link. Typically, the
permissions on the soft link are rwx for all users. The permissions on the file that has been linked to will determine
the actual or effective permissions that a user will have, if they attempt to follow the link.

For example, the permissions on the /bin/systemd file are rwxrwxrwx, which indicate that everyone would have
full access on the link file.

However, examining the permissions on the /lib/systemd/systemd file shows that only the root user would
have write access to the file:

sysadmin@localhost:~$ ls -l /lib/systemd/systemd
-rwxr-xr-x 1 root root 1595792 Feb 28 21:03 /lib/systemd/systemd

To create a soft link file, use the ln command with the -s option. The first argument is the original file name, and
the second argument is the name of the link to be created.

ln -s TARGET LINK_NAME

Be sure to put the arguments in the correct order, as it is not possible to create a link from a file name that already
exists. In the following example, we will create a file called file1.txt and attempt to create a soft link file called
file2.txt:

sysadmin@localhost:~$ touch file1.txt


sysadmin@localhost:~$ ln -s file2.txt file1.txt
ln: failed to create symbolic link `file1.txt': File exists

Switch the arguments from the example above around, and a symbolic link is successfully created:

sysadmin@localhost:~$ ln -s file1.txt file2.txt


sysadmin@localhost:~$ ls -l file*
-rw-rw-r-- 1 sysadmin sysadmin 0 May 9 02:48 file1.txt
lrwxrwxrwx 1 sysadmin sysadmin 9 May 9 02:49 file2.txt -> file1.txt

Unlike hard links, soft link files do not increase the link count number associated with a regular file. In the above
example, the link count number for the ./file1.txt file would stay at one, regardless of how many soft or
symbolic link files were created to refer to that file. Recall that the link count is the number immediately following
the permissions field:

-rw-r--r-- 1 sysadmin sysadmin May 9 14:39 file1.txt


lrwxrwxrwx 1 sysadmin sysadmin May 9 14:39 file2.txt -> file

14.3 Hard Links


Hard link files are just like regular files except that they share an inode with another file. This means that although
the path names for the hard linked files may be different, everything else about them is identical. This sometimes
gives hard links the advantage over soft links in that programs are unable to distinguish between a regular file and a
hard linked file.

To understand hard links, it is helpful to understand a little bit about how the file system keeps track of files. For
every file created, there is a block of data on the file system that stores the metadata of the file. Metadata includes
information about the file like the permissions, ownership, and timestamps. Metadata does not include the file
name or the contents of the file, but it does include just about all other information about the file.

This metadata is called the file's inode table. The inode table also includes pointers to the other blocks on the file
system called data blocks where the data is stored.

Every file on a partition has a unique identification number called an inode number. The ls -i command displays
the inode number of a file.

sysadmin@localhost:~$ ls -i ~/Documents/linux.txt
73798439 /home/sysadmin/Documents/linux.txt

Like users and groups, what defines a file is not its name, but rather the number it has been assigned. The inode
table does not include the file name. For each file, there is also an entry that is stored in a directory's data area (data
block) that includes an association between an inode number and a file name.

In the data block for the /etc directory, there would be a list of all of the files in this directory and their
corresponding inode number. For example:

File Name Inode Number


passwd 123
shadow 175
group 144
gshadow 897
When you attempt to access the /etc/passwd file, the system uses this table to translate the file name into an inode
number. It then retrieves the file data by looking at the information in the inode table for the file.

Hard links are two file names that point to the same inode. For example, consider the following directory entries:

File Name Inode Number


passwd 123
mypasswd 123
shadow 175
group 144
gshadow 897

Because both the passwd and mypasswd files have the same inode number, they essentially are the same file. You
can access the file data using either file name.

When you execute the ls -li command, the number that appears for each file between the permissions and the
user owner is the link count number:

sysadmin@localhost:~$ echo data > file.original


sysadmin@localhost:~$ ls -li file.original
278772 -rw-rw-r--. 1 sysadmin sysadmin 5 Oct 25 15:42 file.original

The link count number indicates how many hard links have been created. When the number is a value of one, then
the file has only one name linked to the inode.

To create hard links, the ln command is used with two arguments (and without the -s option). The first argument
is an existing file name to link to, called a target, and the second argument is the new file name to link to the target.

ln TARGET LINK_NAME

When a hard link is created, the link count value is increased by a value of one. For example, the following
example demonstrates using the ln command to create a hard link file. Notice the link count (the number after the
permissions) before and after the hard link was created:

Note

The sudo command requires the root password. When prompted, enter netlab123.

sysadmin@localhost:~$ cd Documents/
sysadmin@localhost:~/Documents$ ls -l profile.txt
-rw-r--r-- 1 sysadmin sysadmin 110 Apr 24 16:24 profile.txt
sysadmin@localhost:~/Documents$ ln profile.txt myprofile.txt
sysadmin@localhost:~/Documents$ ls -l profile.txt
-rw-r--r-- 2 sysadmin sysadmin 110 Apr 24 16:24 profile.txt

When viewing hard link files, the ls -i option can be helpful to validate that the files are in fact sharing an inode,
as the option causes the inode number to be displayed in front of the permissions. For example, notice that the
following two files both have the same inode number:

sysadmin@localhost:~/Documents$ ls -li profile.txt myprofile.txt


95813671 -rw-r--r-- 2 sysadmin sysadmin 110 Apr 24 16:24 myprofile.txt
95813671 -rw-r--r-- 2 sysadmin sysadmin 110 Apr 24 16:24 profile.txt
Note

The inode number in our virtual machine environment will likely be different than the one in the example.

14.4 Soft Links vs. Hard Links


Which is better: soft or hard links? The answer isn't so straightforward as it really depends on several criteria.
Consider the following:

Hard Link Advantages

 Hard linked files are indistinguishable by programs from regular files.


 If files are hard linked, then they are always contained within one filesystem.
 Hard links don’t have a single point of failure.

Once files are hard linked together, there is no concept of the original. Each file is equal, and if one link is
deleted, the others still work, you don't lose the data. As long as one hard link remains, the file data can be
accessed.

This is unlike soft links in which the data is stored in the file that is being pointed to, meaning that if the
original file is removed, all of the soft links are now pointing to nothing. Consider the following example in
which access to the data fails if the original file is deleted. The mytest.txt file is a symbolic link to the
text.txt file:

Note

The test.txt and mytest.txt files do not exist in our virtual environment.

sysadmin@localhost:~$ ls -l mytest.txt
lrwxrwxrwx. 1 sysadmin sysadmin 8 Oct 31 13:29 mytest.txt -> test.txt
sysadmin@localhost:~$ more test.txt
hi there
sysadmin@localhost:~$ more mytest.txt
hi there

If the original file, the test.txt file is removed, then any files linked to it, including the mytest.txt file,
fail:

sysadmin@localhost:~$ rm test.txt
sysadmin@localhost:~$ more mytest.txt
mytest.txt: No such file or directory
sysadmin@localhost:~$ ls -l mytest.txt
lrwxrwxrwx. 1 sysadmin sysadmin 8 Oct 31 13:29 mytest.txt -> test.txt

 Hard links are easier to locate.

One of the disadvantages of soft links is that it is not easy to tell if a file has a soft link pointing to it. For
example, look at the output of the following ls command:
sysadmin@localhost:~/Documents$ cd /bin
sysadmin@localhost:/bin$ ls -l dash
-rwxr-xr-x 1 root root 121272 Feb 19 2014 dash

The /bin/sh file is a symbolic link to the /bin/dash file, but this is not apparent by looking at the original
file.

sysadmin@localhost:/bin$ ls -l sh
lrwxrwxrwx 1 root root 4 Mar 8 19:08 sh -> dash

On the other hand, a regular file with a hard link count value greater than one is a file that has a hard link.
Using the file's inode number, it is possible to find all the linked files by using the find command with the
-inum option. For example:

sysadmin@localhost:/bin$ cd ~/Documents
sysadmin@localhost:~/Documents$ ls -i words
48365918 words
sysadmin@localhost:~/Documents$ find -inum 48365918
./words
./mywords

Note

The inode number in our virtual machine environment will likely be different than the one in the example.

Soft Link Advantages

 Soft links can be made to a directory file; hard links cannot.

Another limitation of hard links is that they cannot be created on directories. The reason for this limitation
is that the operating system itself uses hard links to define the hierarchy of the directory structure. The
following example shows the error message that is displayed if you attempt to hard link to a directory:

sysadmin@localhost:~/Documents$ cd
sysadmin@localhost:~$
sysadmin@localhost:~$ ln /bin binary
ln: `/bin': hard link not allowed for directory

Linking to directories using a symbolic link is permitted:

sysadmin@localhost:~$ ln -s /bin binary


sysadmin@localhost:~$ ls -l binary
lrwxrwxrwx 1 sysadmin sysadmin 4 May 9 04:04 binary -> /bin

 Soft links can link to any file.

Soft links can be made from a file on one filesystem to a file on another filesystem; hard links cannot. Since
each filesystem (partition) has a separate set of inodes, hard links cannot be created that attempt to cross file
systems:

Note

The /boot/vmlinuz-2.6.32-358.6.1.e16.i686Linux.Kernel files do not exist in our virtual


environment.

sysadmin@localhost:~$ ln /boot/vmlinuz-2.6.32-358.6.1.el6.i686 Linux.Kernel


ln: creating hard link `Linux.Kernel' => `/boot/vmlinuz-2.6.32-358.6.1.el6.i686':
Invalid cross-device link

In the previous example, an attempt was made to create a hard link between a file in the /boot file system
and the / file system; it failed because each of these file systems has a unique set of inode numbers that
can't be used outside of the filesystem.

However, because a symbolic link points to another file using a pathname, you can create a soft link to a
file in another filesystem:

sysadmin@localhost:~$ ln -s /boot/vmlinuz-2.6.32-358.6.1.el6.i686 Linux.Kernel


sysadmin@localhost:~$ ls -l Linux.Kernel
lrwxrwxrwx. 1 sysadmin sysadmin 11 Oct 31 13:17 Linux.Kernel -> /boot/vmlinuz-2.6.32-
358.6.1.el6.i686

 Soft links are easier to see.

Soft links are very visual because the output of the ls -l command displays which file the soft link is
pointing to.

In general, if you need to link to a file on another filesystem or to a directory, then soft links are the correct type to
use. Otherwise, you should make use of hard links.
Key Terms

ln
Command used to create a link between two files. The ln utility can be used to create either symbolic links
or hard links based on the parameters supplied.
Section 14.2 | Section 14.3
ls
Command that will list information about files. The current directory is listed by default.
LAB 14
14.0 Introduction
Understanding filesystem links is important because a typical Linux filesystem has many of these files by default.
As a regular user, you may routinely be accessing files that are actually symbolic links. Understanding how these
files work will make it easier for you to use them.

As an administrator, you will be responsible for maintaining the system's hard and soft links. You should know
what these files are, the difference between hard and soft links and how to create them.

14.1 Step 1
Execute the following command to switch to the root account. When prompted, provide the root password:

su – root
netlab123
[sysadmin@localhost ~]$ su - root
Password:
[root@localhost ~]#

14.2 Step 2
Execute the following command to see a soft link file:

ls -l /etc/rc.local
[root@localhost ~]# ls -l /etc/rc.local
lrwxrwxrwx 1 root root 13 Feb 4 2016 /etc/rc.local -> rc.d/rc.local

Note that soft links are easy to see as the file type (first character before permissions) is a letter l and the filename
includes the link.

14.3 Step 3
Execute the following command to view the file that the /etc/rc.local file is pointing to:

ls -l /etc/rc.d/rc.local
[root@localhost ~]# ls -l /etc/rc.d/rc.local
-rwxr-xr-x 1 root root 220 Dec 15 2015 /etc/rc.d/rc.local

Note that when the link is followed, the permissions on the real file are what is used to provide access to the file.
As a result, soft link files typically have the permissions of rwxrwxrwx while the files that they point to have real
permissions.
14.4 Step 4
Execute the following commands to copy a file to the /tmp directory and then create a soft link to this file:

cp /etc/hosts /tmp
ln -s /tmp/hosts /var/hosts
ls -l /var/hosts
ls -l /tmp/hosts
[root@localhost ~]# cp /etc/hosts /tmp
[root@localhost ~]# ln -s /tmp/hosts /var/hosts
[root@localhost ~]# ls -l /var/hosts
lrwxrwxrwx 1 root root 10 Apr 19 16:01 /var/hosts -> /tmp/hosts
[root@localhost ~]# ls -l /tmp/hosts
-rw-r--r-- 1 root root 172 Apr 19 16:01 /tmp/hosts

Note that while it is easy to see that /var/hosts points to the /tmp/hosts file, it is impossible to determine a soft
link from the file that is being pointed to. In other words, listing the /tmp/hosts file doesn't tell you that the
/var/hosts file points to it.

14.5 Step 5
View the /tmp/hosts file via the /var/hosts file by executing the following command:

more /var/hosts
[root@localhost ~]# more /var/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.1.2 localhost

14.6 Step 6
Delete the /tmp/hosts file and attempt to view the /var/hosts file again by executing the following commands:

rm /tmp/hosts
y
more /var/hosts
[root@localhost ~]# rm /tmp/hosts
rm: remove regular file '/tmp/hosts'? y
[root@localhost ~]# more /var/hosts
/var/hosts: No such file or directory

Note the strange error message No such file or directory. The /var/hosts file does exist, but when it
follows the link, the system can't find the /tmp/hosts file, which results in the error message. This is the primary
weakness of soft links.
14.7 Step 7
View the listing of the /var/hosts file by executing the following command:

ls -l /var/hosts
[root@localhost ~]# ls -l /var/hosts
lrwxrwxrwx 1 root root 10 Apr 19 16:01 /var/hosts -> /tmp/hosts

The red color in the filename indicates something is wrong; in this case a broken link.

14.8 Step 8
Soft links can also be made to directories. For example, execute the following commands:

ln -s /etc/yum /tmp/yum-files
ls -l /tmp/yum-files
ls -l /tmp/yum-files/
[root@localhost ~]# ln -s /etc/yum /tmp/yum-files
[root@localhost ~]# ls -l /tmp/yum-files
lrwxrwxrwx 1 root root 8 Apr 19 17:20 /tmp/yum-files -> /etc/yum
[root@localhost ~]# ls -l /tmp/yum-files/
total 20
drwxr-xr-x 2 root root 4096 Nov 5 01:53 fssnap.d
drwxr-xr-x 2 root root 4096 Dec 4 14:39 pluginconf.d
drwxr-xr-x 1 root root 4096 Mar 29 19:23 protected.d
drwxr-xr-x 2 root root 4096 Dec 4 14:38 vars
-rw-r--r-- 1 root root 444 Nov 5 01:53 version-groups.conf

Soft links to directories are tricky. If you just refer to the soft link (like the first ls command above), only the soft
link itself will be displayed. If you add a trailing / character to the end of the soft link name, then it follows the soft
link and displays the contents of the directory that the soft link is linked to

14.9 Step 9
Hard links share the same inode table. Execute the following command to create a hard link file:

mkdir /test
cp /etc/crontab /test
cd /test
ln crontab hcrontab
ls -l
[root@localhost ~]# mkdir /test
[root@localhost ~]# cp /etc/crontab /test
[root@localhost ~]# cd /test
[root@localhost test]# ln crontab hcrontab
[root@localhost test]# ls -l
total 8
-rw-r--r-- 2 root root 451 Apr 19 17:21 crontab
-rw-r--r-- 2 root root 451 Apr 19 17:21 hcrontab

An inode table contains the metadata for the file. This is all the information about the file besides the file name.
When two files share an inode table, they are essentially the same file, but with different names.
14.10 Step 10
Note that the hard linked files are identical, besides their names. If you add another hard link, the hard link count
increases. Execute the following commands for an example:

ln hcrontab newcrontab
ls -l
[root@localhost test]# ln hcrontab newcrontab
[root@localhost test]# ls -l
total 12
-rw-r--r-- 3 root root 451 Apr 19 17:21 crontab
-rw-r--r-- 3 root root 451 Apr 19 17:21 hcrontab
-rw-r--r-- 3 root root 451 Apr 19 17:21 newcrontab

14.11 Step 11
You can tell that these files are all hard linked together by using the -i option to the ls command:

ls -i
[root@localhost test]# ls -i
132383356 crontab 132383356 hcrontab 132383356 newcrontab

Because all of these files share the same inode number, they are hard linked together.

14.12 Step 12
Unfortunately, hard links can't be made to directories. Execute the following command to see a demonstration:

ln /etc /myetc
[root@localhost test]# ln /etc /myetc
ln: '/etc': hard link not allowed for directory
Chapter 15: Hardware Configuration

15.1 Introduction
Understanding how to view and configure computer system hardware is a critical skill for a Linux administrator.
Even though some hardware may not require any configuration, an administrator can benefit from understanding
the function of that hardware when attempting to diagnose any problems. The usage of virtualization and virtual
machines does not lessen the need to understand hardware, as the concept of hardware still exists in the virtual
machine environment, and virtualization environments run on physical hardware.

15.2 Core Hardware


Components that are essential to operate a computer are considered core hardware. Every system should include a
central processing unit, random access memory, and some kind of firmware. This module will define these
components and demonstrate commands and files that can be used to view core hardware information in the
terminal. Other hardware that is essential for a complete system includes some type of persistent storage device
like a mechanical hard drive or solid-state drive (SSD), a method of controlling the device, either remotely, or by
using a display device/monitor, a keyboard, and a mouse. Most systems also include one or more networking
devices, possibly a sound device, and ports for connecting external devices.

15.2.1 Central Processing Unit


The central processing unit (CPU) is the brain of the computer, where the instructions to perform calculations or
manipulate data are processed. There are numerous types of CPUs that are able to work with Linux, but the most
common is the 64-bit x86_64 type, and decreasingly, the 32-bit x86 type. Both of these types of CPUs are
backward compatible with the CPU used in the first IBM Personal Computer (PC), the Intel 8088 CPU.

Knowing the type and capability of a system’s CPU is essential to knowing what software can be installed on it,
and how it will perform. There are several ways to gather information about the type of CPU in a system. We will
focus on determining this information from an already-installed Linux system.

A prime location for CPU information is the firmware settings. Viewing the contents of the /proc/cpuinfo file
will display extremely detailed information, including the model name, speed in MHz, and specific features
available in a list of flags.

The uname command is a valuable tool for quickly determining system information from the command line.
Running the uname command with no parameters yields only the kernel name as shown below:

sysadmin@localhost:~$ uname
Linux

The uname command has access to the files in the /proc and /sys directories which can display a lot of organized
information about your system. Running uname with the -a option will show the following information (in order of
appearance):
Information Option Example
Kernel name -s Linux
Nodename -n localhost
Kernel release -r 4.4.0-72-generic
Kernel version -v #93~14.04.1-Ubuntu SMP Fri Mar 31 15:05:15 UTC 2017
Machine hardware -m x86_64
Processor -p x86_64
Hardware platform -i x86_64
Operating System -o GNU/Linux
sysadmin@localhost:~$ uname -a
Linux localhost 4.4.0-72-generic #93~14.04.1-Ubuntu SMP Fri Mar 31 15:05:15 UTC
2017 x86_64 x86_64 x86_64 GNU/Linux

Each item can be display individually with the corresponding option. For a less detailed summary of the CPUs in
your system, execute the uname -p command:

sysadmin@localhost:~$ uname -p
x86_64

Another way to get more detailed information than the uname command can give you is to run the lscpu
command. Much of the information the lscpu command returns is out of the scope of this objective but can be
very useful in determining the hardware’s capabilities.

sysadmin@localhost:~$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 8
On-line CPU(s) list: 0-7
Thread(s) per core: 1
Core(s) per socket: 4
Socket(s): 2
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 44
Stepping: 2
CPU MHz: 2394.000
BogoMIPS: 4788.00
Hypervisor vendor: VMware
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 12288K
NUMA node0 CPU(s): 0-7
15.2.2 Random Access Memory
The random access memory (RAM) of a system is used to temporarily store data and instructions for the operating
system and the programs that are executing. When the IBM PC debuted in 1981, it was able to access 1 MiB of
memory, of which 640 KiB was RAM, and 384 KiB was for the system ROM.

The maximum amount of memory that can be used with a 32-bit processor is 4 GiB, whereas a 64-bit processor
can theoretically use 16 EiB of memory. In reality, many 32-bit systems may actually be limited to using 3 GiB of
memory, and the hardware doesn't exist yet to be able to use the maximum amount of memory on a 64-bit system.

From a practical perspective, if a system doesn't currently have at least 1 GiB of RAM, then it may not be able to
use the graphical user interface (GUI) with Linux. When using only the command line interface (CLI), the memory
requirements are much less.

Consider This

Unit Abbreviation Value (Bytes)


kibibyte KiB 1024
mebibyte MiB 10242 = 1,048,576
gibibyte GiB 10243 = 1,073,741,824
tebibyte TiB 10244 = 1,099,511,627,776
exbibyte EiB 10246 = 1,152,921,504,606,846,976

A typical desktop in the year 2019 has 16 GiB of RAM. That is more than 26000 times the amount of RAM in a
fully loaded IBM PC in the year 1981!

Normally a system will have enough RAM to conduct its normal operations, run a few services, and maybe
applications. If a system doesn't have sufficient RAM for the processes you are executing on it, then it will use
virtual memory, called swap space in Linux. Swap space is hard drive space that is temporarily used to hold data
that exceeds the amount of RAM available. When the system begins to run low on memory, it will "swap out" data
that is least in demand at that moment, so that RAM space can free up for something that is currently in demand
(typically a new process). If the system is using swap space constantly, then it will perform poorly in comparison
to a system that doesn't; an increase in performance could be obtained if more RAM were added to the system.

Swap space comes in two types; a swapfile that would reside on an existing filesystem, or a swap partition, which
is a section of a disk that is dedicated to swap and is formatted with the swap filesystem. A swap partition is an
essential part of a properly configured Linux system and yields the best performance for swap operations. Swap
files have the overhead of being on an existing filesystem and should be used sparingly, and only if absolutely
necessary.

The amount of RAM in a system can be viewed in the firmware settings. For a very detailed breakdown of how
much memory a system has and how it is being used, view the /proc/meminfo file:

sysadmin@localhost:~$ cat /proc/meminfo


MemTotal: 132014640 kB
MemFree: 67439868 kB
MemAvailable: 99487364 kB
Buffers: 2116936 kB
Cached: 27429740 kB
SwapCached: 40 kB
Active: 14409408 kB
Inactive: 23724500 kB
Active(anon): 8400252 kB
Inactive(anon): 191680 kB
Active(file): 6009156 kB
Inactive(file): 23532820 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 134196220 kB
SwapFree: 134195752 kB
Output Omitted...

For a quick summary of RAM memory and swap space, execute the free command:

sysadmin@localhost:~$ free
total used free shared buff/cache available
Mem: 128920 35120 89205 2 4594 93190
Swap: 131050 140 130910

The output above shows this system contains about 128 MiB of RAM memory; almost all of it is used. Very little
memory is free because the system configures any unused memory for buffers and caches, which are temporary
data stores, to speed up the system.

Despite having so little free RAM, notice that the swap space of about 131 MiB has not been used at all; although
if a heavy demand for memory (due to an additional load of processes) were placed on this system, then this swap
space is available and would likely be used.

Another notable bit of information from this output is that the swap space that has been configured is about twice
as large as the amount of RAM. For systems with smaller amounts of RAM (under 16-32 GiB), it is common to
configure the swap space to be twice the size of the amount of RAM.

15.2.3 Firmware
Firmware is software that has been written to non-volatile memory such as read-only memory (ROM) or flash
memory. There are several types of firmware that may be present in a computer system. On each device that
provides services to a system (like a network interface card or a graphics display), there is typically a ROM chip
that contains firmware for the device.

The motherboard firmware contains the code that allows the integrated components of the system to work together.
This firmware tests the components upon startup, identifies and initializes these components, and attempts to find a
bootloader to load an operating system.

Note

Bootloaders will be covered in greater detail later in the course.

Originally, this firmware was known as the Basic Input/Output System (BIOS), System ROM, or ROM BIOS.
BIOS is used to provide basic services, called input and output services before an operating system is loaded, so
the user may provide input through the keyboard or see output on a monitor even before the bootloader or an
operating system is executed.

Recently, computer manufacturers have begun to replace the traditional BIOS with something called the Unified
Extensible Firmware Interface (UEFI); however, the functions of UEFI appear so similar to BIOS that many
people still refer to the system firmware as BIOS.
Both UEFI-based systems and BIOS-based systems provide a proprietary menu program that allows integrated
devices to be enabled or disabled. The firmware that is included varies with each system vendor, so, unfortunately,
there is no standard way to start this program or standard menu item for enabling or disabling devices.

Entering the program that will allow adjustments to the firmware settings typically requires that a designated key is
pressed immediately after turning the system on. Many systems use a function key like F2 or F12, while others
might use the Esc or Del keys to start the firmware settings program. When a computer is powered on, messages
typically appear on the splash screen indicating the appropriate key to press. If the correct key is not displayed on
the splash screen, it may be necessary to refer to vendor documentation.

⁠If a system has UEFI firmware, then it may be more challenging to boot the Linux operating system due to a
feature called Secure Boot. If Secure Boot is enabled, then the bootloader must be cryptographically signed by a
digital key that is recognized by the firmware. If the bootloader is not properly signed, then booting may still be
possible by disabling Secure Boot in the firmware settings, in favor of the Compatibility Support Module
(CSM).

Not only can the firmware settings be used to enable or disable Secure Boot, settings can also be changed that will
affect which devices, and in what order, the firmware will look for a bootable device. The firmware settings can
even be used to affect the use of external devices like keyboards.

As advancements in integration of peripherals have occurred, more components have been placed on-board,
meaning they are embedded into the motherboard of a system. These integrated peripherals can be managed
through firmware as well. Historically, a peripheral was added to the system by inserting a card on the peripherals
bus, such as a video card or networking card. Then the peripheral had to be manipulated either via physical jumper
or switch settings to properly use the right memory location and IRQ or Interrupt Request number. All of this is
typically pre-configured on systems that have integrated peripherals, by the manufacturer, typically with no need
for the computer’s user to be involved.

Commonly, server systems may be configured to run headless, that is without a keyboard, mouse, or monitor.
Typically, the BIOS will prevent a computer from booting without a keyboard present. It may be necessary to
change the firmware settings to disable this feature for headless systems

15.2.4 Mass Storage Devices


Although Linux doesn't strictly require a mass storage device, most systems will include one or more of such
devices. The most common mass storage device is the mechanical hard disk (or fixed disk). These types of disks
come with a variety of interfaces or ways that they connect to the computer system.

There are quite a few mass storage interfaces that are still in use today:

 The Small Computer System Interface (SCSI) is one of the oldest and requires a SCSI controller in the
system to control one or more disk drives that connect to it.
 The Integrated Drive Electronics (IDE) or Parallel Advanced Technology Attachment (PATA) type
interface includes the controller directly on each drive and was very popular for hard disks through the
1990s. This type is still used for some optical drive devices today.
 The most common interface used for internal mass storage devices today is the Serial Advanced
Technology Attachment (SATA) type. Each SATA drive is connected directly to the system board by a
cable. To configure the primary SATA drive, connect it with a cable to the connector of the system board
that is designated as the primary port.
 For external drives, the Universal Serial Bus (USB) interface is the most common, but there are other
standards such as FireWire and Thunderbolt.

Note

Data storage devices use either serial or parallel interfaces. The S in SCSI, in SATA, and in USB all stand for the
word serial. That is why they appear as /dev/sda1 meaning Device Serial Drive A partition 1.

The df -h command can be used to determine which type of drive is being used in a Linux based computer.

sysadmin@localhost:~$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda9 58G 7.7G 49G 14% /
tmpfs 7.9G 0 7.9G 0% /dev
shm 64M 0 64M 0% /dev/shm
/dev/sda9 58G 7.7G 49G 14% /etc/hosts

The df command is covered in greater detail later in the course.

15.3 Plug and Play


In addition to the core hardware, there are many other components, commonly known as peripherals, that may be
used with the computer system. It is important to know if a peripheral requires that the power to the computer
system be turned off at the time it is connected, or if the peripheral may be connected while the computer system is
on. If the power to the computer system is on and the peripheral requires that the power be turned off, connecting
the device may result in damage to the peripheral, ⁠ the computer system, or both.

Devices that are supposed to be connected when the power is off are known as coldplug devices. Devices that can
be connected when the power is on are known as hotplug devices. In order to "plug and play", or plug in a device
while the system is powered on and have it work, the device, the interface, the driver, and the operating system all
must support hotplugging for that device.

Consider This

Typically, USB devices are hot pluggable. This means that the USB device will be auto-recognized by the running
operating system, so you don't have to do anything for the system to “see” the device; just plug it in, and the USB
drivers will see it, auto-configure, and connect it properly.

15.4 Hardware Resources


In order for a device to work correctly, certain resources must be allocated to it. Originally, PCs had very limited
resources that had to be manually managed; the administrator would have to set jumpers or switches on the devices
to configure them for the resources that they would use. This was problematic, as a mistake might create a situation
where one resource was being allocated to more than one device, resulting in one or both devices not working. In
some cases, improper allocation of resources could even result in a non-functional system.

Not only are more resources available today, but they are also automatically allocated and managed by the
operating system instead of manually by the administrator.
There are four types of hardware resources that devices use to communicate with the system. As some of these
resources refer to input and output, part of their name may be abbreviated as IO. The four resources are: IO ports,
IO memory, interrupt requests (IRQ), and direct memory access (DMA) channels:

 IO Ports - Memory addresses that allow for communication with hardware devices. The current system
addresses in use can be viewed by executing the following command:
 sysadmin@localhost:~$ cat /proc/ioports
 0000-0cf7 : PCI Bus 0000:00
 0000-001f : dma1
 0020-0021 : pic1
 0040-0043 : timer0
 0050-0053 : timer1
 0060-0060 : keyboard
 0064-0064 : keyboard
 Output Omitted...
 IO Memory - A section or location that acts much like the RAM that is presented to the processor via the
system bus. These are used to pass and store data as well as for access to devices on the system. IO memory
information can be viewed by executing the following command:
 sysadmin@localhost:~$ cat /proc/iomem
 00010000-0009ffff : System RAM
 000a0000-000bffff : PCI Bus 0000:00
 000c0000-000c7fff : Video ROM
 000c8000-000cdfff : Adapter ROM
 000f0000-000fffff : System ROM
 00100000-be777fff : System RAM
 06000000-0680bdb2 : Kernel code
 0680bdb3-06f45abf : Kernel data
 Output Omitted...
 Interrupt Requests (IRQ) - An interrupt is a hardware signal that pauses or stops a running program so
that the interrupt handler can switch to running another program, or send and receive data. There are a set
of commonly-defined interrupts called IRQ’s that map to common interfaces, such as the system timer,
keyboard controller, serial and parallel ports, and floppy controllers. The /proc/irq directory contains
configuration information for each IRQ on the system.
 Direct Memory Access (DMA) - A method by which particular hardware items in the system can directly
access RAM, without going through the CPU. This speeds up access, as the CPU would otherwise be fully
tasked during such access, making it unavailable for other tasks for the duration. DMA information can be
viewed by executing the following command:
 sysadmin@localhost:~$ cat /proc/dma
4: cascade

Note that, with the exception of interrupt requests, these resources cannot be shared between devices. Also, keep in
mind that administrators rarely need to view this data on modern Linux systems as the configuration of devices is
almost always transparent and automatic.

15.5 Viewing Hardware


Viewing the details of what hardware is attached (including peripherals attached via USB, etc.) or contained in a
running Linux system is important to successfully troubleshoot problems that may occur during boot up and day-
to-day operations.

Consider This
Modern computers typically use the Peripheral Component Interconnect Express (PCIe) bus to connect
components inside the computer. For example, video, sound, network, and disk controllers are normally found on
the PCIe bus.

A bus is not only used to refer to actual physical connections, but also software components designed to connect
programs and certain communications protocols. Components are attached with a type of bus and communicate
through it at high rates of speed.

Buses can be alternatively grouped into internal and external bus types. Internal buses are considered to be inside
the actual computer, while external or “expansion” buses are used to attach external devices to the computer. Good
examples of internal buses are the aforementioned PCIe bus, the older Industry Standard Architecture (ISA)
bus, and the very popular Small Computer Systems Interface (SCSI) bus. An example of an external or
expansion bus type would be the most universally available Universal Serial Bus (USB) bus.

Bridges connect the various buses on a system to each other and allow for cross bus communications when
necessary.

While there are files and directories in the /proc and /sys directories that contain hardware information, users can
run various commands to view the multiple aspects of the hardware that makes up or is attached to the system.

First among these is the lspci command, designed to show the user the PCI buses and devices attached to them.
In the output of the command below you will see the various bridges listed; those are connections between the
different buses on the system, interconnecting them with each other.

Additionally, users can view the USB controller, Ethernet, sound, and other video and peripheral connection buses
and controllers.

sysadmin@localhost:~$ lspci
00:00.0 Host bridge: Intel Corporation 5520 I/O Hub to ESI Port (rev 13)
00:01.0 PCI bridge: Intel Corporation 5520/5500/X58 I/O Hub PCI Express Root Por
t 1 (rev 13)
00:03.0 PCI bridge: Intel Corporation 5520/5500/X58 I/O Hub PCI Express Root Por
t 3 (rev 13)
00:04.0 PCI bridge: Intel Corporation 5520/X58 I/O Hub PCI Express Root Port 4 (
rev 13)
00:05.0 PCI bridge: Intel Corporation 5520/X58 I/O Hub PCI Express Root Port 5 (
rev 13)
00:06.0 PCI bridge: Intel Corporation 5520/X58 I/O Hub PCI Express Root Port 6 (
rev 13)
00:07.0 PCI bridge: Intel Corporation 5520/5500/X58 I/O Hub PCI Express Root Por
t 7 (rev 13)
00:09.0 PCI bridge: Intel Corporation 7500/5520/5500/X58 I/O Hub PCI Express Roo
t Port 9 (rev 13)
00:14.0 PIC: Intel Corporation 7500/5520/5500/X58 I/O Hub System Management Regi
sters (rev 13)
00:14.1 PIC: Intel Corporation 7500/5520/5500/X58 I/O Hub GPIO and Scratch Pad
Registers (rev 13)

For viewing external devices, the lsusb command will show those that are specifically connected to the Universal
Serial Bus (USB).

sysadmin@localhost:~$ lsusb
Bus 002 Device 006: ID 0624:0249 Avocent Corp. Virtual Keyboard/Mouse
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 003: ID 0624:0248 Avocent Corp. Virtual Hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 002: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

Another tool for viewing details about USB devices connected to the system is the usb-devices command. This is
a script, which when executed will display information about the USB device that can otherwise be found in the
/sys or /proc directories, including; the USB device number, vendor, port and more:

sysadmin@localhost:~$ usb-devices | tail -n 15


S: Manufacturer=Avocent
S: Product=USB Composite Device-0
S: SerialNumber=20120430
C: #Ifs= 2 Cfg#= 1 Atr=c0 MxPwr=2mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=01 Driver=usbhid
I: If#= 1 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=02 Driver=usbhid

T: Bus=06 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2


D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=1d6b ProdID=0001 Rev=04.04
S: Manufacturer=Linux 4.4.0-72-generic uhci_hcd
S: Product=UHCI Host Controller
S: SerialNumber=0000:00:1d.1
C: #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
If the user requires more information than the lspci and lsusb commands show normally, simply append a -v
option to either command and a great deal more information will be shown; taking the output from one line per
item to a stanza-based output where each item is shown with multiple details.

To demonstrate, the output of the lspci -v command below displays only a single screen of output. The complete
output would be 350+ lines long!

sysadmin@localhost:~$ lspci -v
00:00.0 Host bridge: Intel Corporation 5520 I/O Hub to ESI Port (rev 13)
Subsystem: Dell 5520 I/O Hub to ESI Port
Flags: fast devsel, IRQ 15
Capabilities: <access denied>
lspci: Unable to load libkmod resources: error -12

00:01.0 PCI bridge: Intel Corporation 5520/5500/X58 I/O Hub PCI Express
Root Port 1 (rev 13) (prog-if 00 [Normal decode])
Flags: bus master, fast devsel, latency 0, IRQ 25
Bus: primary=00, secondary=01, subordinate=01, sec-latency=0
Memory behind bridge: d6000000-d9ffffff
Capabilities: <access denied>
Kernel driver in use: pcieport

00:03.0 PCI bridge: Intel Corporation 5520/5500/X58 I/O Hub PCI Express
Root Port 3 (rev 13) (prog-if 00 [Normal decode])
Flags: bus master, fast devsel, latency 0, IRQ 26
Bus: primary=00, secondary=02, subordinate=02, sec-latency=0
Memory behind bridge: da000000-ddffffff

Finally, if a user has an issue with a component and is able to see that component mentioned in the lspci -v
output, they can get more information about the malfunctioning component by referring to the multiple digit
vendor and device code that prefaces the stanza for each device.

For example, to get more information about the IDE interface from the machine above, the user can run the lspci
command with the -v and -s options followed by the vendor and device code as a parameter. The -s option will
allow for a domain to be specified which will display information solely about devices in that domain:

sysadmin@localhost:~$ lspci -v -s 00:07.0


00:07.0 PCI bridge: Intel Corporation 5520/5500/X58 I/O Hub PCI Express
Root Port 7 (rev 13) (prog-if 00 [Normal decode])
Flags: bus master, fast devsel, latency 0, IRQ 30
Bus: primary=00, secondary=06, subordinate=06, sec-latency=0
Capabilities: <access denied>
Kernel driver in use: pcieport
lspci: Unable to load libkmod resources: error -12

To isolate the details of a specific USB device, find the vendor and device code in the output of the lsusb
command, then use the lsusb command again, this time with the -v and -d options to get the isolated details of a
device. The -d option will allow for a vendor or product ID to be specified, which will only display devices with
that number. For example, to show details about Device 003, use the following command:

sysadmin@localhost:~$ lsusb -v -d 0624:0248 | less


Bus 005 Device 003: ID 0624:0248 Avocent Corp. Virtual Hub
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x0624 Avocent Corp.
idProduct 0x0248 Virtual Hub
bcdDevice 0.00
iManufacturer 1
iProduct 2
iSerial 3
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 59
bNumInterfaces 2
bConfigurationValue 1
:

Note

Type the Q key to exit the less command.

15.6 Hardware Subsystems


Linux distributions are more capable than ever, particularly in the area of device management. Devices built into
the computer system are typically not removable unless the system is shut down and power disconnected for safety.

The concept of hotplugging — plugging devices into a port on a Linux system and having the running system
automatically recognize the device correctly, then possibly run a program or execute a set of actions, works
extremely well in modern Linux distributions due to a trio of device management tools.

The trio of device management tools starts with udev, a device management subsystem that manages the /dev
directory and will automatically create and destroy node points (references to a device) for devices that are
attached to the system, or subsequently removed.

To accomplish this, the udev subsystem maintains a pseudo-filesystem mounted as the /dev directory. The files in
the /dev directory represent devices currently connected to the system. When the Linux kernel detects a device
being connected, the udev daemon is used to create a device file (or node) in the /dev directory. If the device is
removed, the udev daemon then removes the device node in the /dev directory.

Consider This

Older Unix systems tended to create all possible device nodes in /dev, just in case they were needed; udev only
creates and maintains nodes for devices currently connected. This keeps the directory nice and neat and clean, easy
to troubleshoot, and to determine what’s actually present and attached to the system.

Configuration files in the /etc/udev/rules.d directory are used to define rules that assign specific ownerships,
permissions, and persistent names to these device files. These files allow a user to configure how udev handles the
devices it manages.

The second part of the device management trio is the sysfs subsystem, which is another in-memory filesystem that
consists of directories and text files that contain values about the kernel’s operation and configuration.
The sysfs subsystem is typically mounted as the /sys subdirectory. The /sys directory and sysfs exist because
there is a need to provide information about the kernel, its attributes, and contents to users via programs such as ps,
top, and other programs that provide information to the regular user through command line output. To view the
contents of the /sys directory on the system, use the following command:

sysadmin@localhost:~$ ls /sys
block class devices fs kernel power
bus dev firmware hypervisor module

Modern systems (kernels 2.5 and beyond) use sysfs to express kernel information into the /sys directory because
the procfs subsystem (and the /proc directory) had become increasingly busy and cluttered. Like the /sys
directory, the /proc directory contains information about the system hardware, including devices and the kernel.
However, as an ever-larger set of kernel subsystems started using the /proc directory to express their structures
and expose kernel information for the system user to access, the /proc directory became busy and somewhat
jumbled in nature, like a closet that has too many items packed into it. In comparison, the /sys directory structure
forces a certain austerity and cleanliness by design, as the rules for using the /sys directory are “one item per file”
and no more.

This allows for a much neater and easier to understand expression of kernel objects and their attributes, and allows
for easier documentation and programming.

For example, in the /proc directory, you can use the tree command to show a hierarchical tree of the files and
directories that are contained there. However, the listing will be many pages long, so using the less command will
be of great benefit in scrolling up and down and looking at the output.

sysadmin@localhost:~$ tree /proc | less


/proc
|-- 1
| |-- attr
| | |-- current
| | |-- exec
| | |-- fscreate
| | |-- keycreate
| | |-- prev
| | `-- sockcreate
| |-- autogroup
| |-- auxv
| |-- cgroup
| |-- clear_refs
| |-- cmdline
| |-- comm
| |-- coredump_filter
| |-- cpuset
| |-- cwd -> [Error\ reading\ symbolic\ link\ information]
| |-- environ
| |-- exe -> [Error\ reading\ symbolic\ link\ information]
| |-- fd [error opening dir]
| |-- fdinfo [error opening dir]
| |-- gid_map
:

Many of the files in the /proc directory will contain more than a single value, whereas the files in the /sys
directory are designed to be simpler and contain a single text value, making them more predictable and easier to
use.

Finally, the last of the trinity of device management tools is the Hardware Abstraction Layer (HAL) daemon, (aka
hald). As the kernel detects a device, it puts the information about the device into the appropriate files in the /sys
directory. The hald is responsible for discovering and maintaining a list of connected devices and their attributes by
monitoring the files in the /sys directory.

To view the list of devices and their attributes that have been stored by hald, execute the lshal command. The
lshal command's output will likely contain thousands of lines of text. To see information about specific devices,
make use of the grep command, as shown in the following example:

Note

The following example may not match the output in our virtual environment.

sysadmin@localhost:~$
lshal | grep cdrom | grep true
storage.cdrom.dvd = true (bool)
storage.cdrom.mrw = true (bool)
storage.cdrom.mrw_w = true (bool)
storage.cdrom.support_media_changed = true (bool)
storage.cdrom.support_multisession = true (bool)

Finally, when programs want information about devices, they are able to query hald by using D-Bus.

D-Bus is a method of allowing inter-process communications, primarily the communications between components
in the Linux Desktop environments, KDE and GNOME. Without D-Bus, desktop environments will communicate
between components with many separate processes, each requiring its own one-to-one communication with other
components. This produces a confusing communications environment and can contribute to inefficiency and a lack
of reliability and instability in the graphics subsystem.

D-Bus is a software bus that allows individual and groups of processes to communicate on a single virtual bus or
channel, a feature called Interprocess Communication (IPC).
D-Bus operates with an overall system bus that is available to all the processes on the system, whether they are
system or user-related processes. Additionally, there is a session bus for each of the logged-in users for the
processes that are connected to that user’s desktop session.

Programs can also register themselves with D-bus to receive notifications from hald when specific types of
hardware events occur. When the state of a hardware device changes, hald uses D-Bus to send notifications to
those programs that have been registered for that type of hardware event.

Since 2011, hald has been deprecated by many of the leading Linux distributions and has been eliminated from
recent releases. In its place, the udev subsystem has been expanded, along with integrating Systemd.

Systemd typically uses udev for its device management tasks. The job of udev is to let your computer know of
device events, among other tasks. A user will likely not have to deal with udev directly unless there are archaic or
odd devices that need to be made available and manual configuration to be done.

Udev can manage any device that shows a link in the /dev directory when attached to the system, which udev is
able to do through scripts known most commonly as udev rules. At their simplest, a udev rule is something that
performs an action when a device is inserted, such as a thumb drive.

For the majority of devices, the kernel will know exactly what to do already. For example, if you plug in a USB
thumb drive, the kernel will likely mount it to one of the available spots in the /dev/sd* devices directory. If it
does, you can access and use it, depending on its format and other compatibility settings.

Udev can detect when a device has been attached or removed. Udev rules can establish custom actions that are
taken when these events occur.
Writing udev rules is beyond the scope of this course; however, you can use the udevadm command to view the
pertinent information that would allow you to directly specify a device within a udev rule when it’s attached, and
then execute specific actions on that device.

There are two ways to do this:

 When a device is inserted.


 When you want to query a device that is either already attached or is built-in to the system, such as the main
storage device (the /dev/sda device for example.)

To watch what happens when a device is inserted or attached, run the following command:

sysadmin@localhost:~$ udevadm monitor


monitor will print the received events for:
UDEV: the event udev sends out after rule processing
KERNEL - the kernel uevent

To query an already-attached device for the necessary information, execute the command below:

sysadmin@localhost:~$ udevadm info /dev/sda


P: /devices/pci0000:00/0000:00:07.1/ata1/host0/target0:0:0/0:0:0:0/block/sda
N: sda
S: disk/by-id/ata-VMware_Virtual_IDE_Hard_Drive_00000000000000000001
S: disk/by-id/wwn-0x5000c2947bd39bdb
S: disk/by-path/pci-0000:00:07.1-ata-1
E: DEVLINKS=/dev/disk/by-id/wwn-0x5000c2947bd39bdb /dev/disk/by-path/pci-0000:00:07.1-ata-1
/dev/disk/by-id/ata-VMware_Virtual_IDE_Hard_Drive_00000000000000000001
E: DEVNAME=/dev/sda
E: DEVPATH=/devices/pci0000:00/0000:00:07.1/ata1/host0/target0:0:0/0:0:0:0/block/sda
E: DEVTYPE=disk

The two preceding commands and a short study of the udev man pages about rules will inform beginners and
system administrators on how to create custom rules for devices.
15.7 Kernel Modules
In addition to detecting devices, the Linux kernel may load software called kernel modules to support the device.
Some devices are so common that the software to support them is normally compiled into the kernel itself, for
example, the software for the CPU. Other devices that are not as common will have modules that are only loaded if
the device is detected, for example, a specific network card.

The kernel module may even load additional software such as firmware from a file or from the device itself. One
concern of some users is that these firmware files may contain code that is not open source, meaning there is no
way for a user to know what the code does exactly because it is proprietary and not shared with the public. If the
kernel loads "non-free" code, then the kernel is considered to be "tainted" as the code of the kernel itself is free.

Kernel modules can be used for more than supporting devices; since modules are simply software that is able to
run within the kernel, they are able to be used for virtually anything. Some common uses besides device drivers
include filesystems modules, networking protocols modules, and cryptographic algorithms modules.

To view the list of loaded kernel modules, use the lsmod command:

sysadmin@localhost:~$ lsmod
Module Size Used by
af_packet_diag 16384 0
netlink_diag 16384 0
dccp_diag 16384 0
dccp 73728 1 dccp_diag
udp_diag 16384 0
unix_diag 16384 0
tcp_diag 16384 0
inet_diag 20480 3 tcp_diag,dccp_diag,udp_diag
xt_nat 16384 700
xt_tcpudp 16384 718
Output Omitted...

The columns of data in the output above are:

 Module

dccp 73728 1 dccp_diag

The name of the loaded module.

 Size

dccp 73728 1 dccp_diag

The size in bytes of the module.

 Used by

dccp 73728 1 dccp_diag

Indicates how many "things" depend on the current module being loaded. These "things" could include
other modules, processes, or other features (such as a filesystem being mounted).

dccp 73728 1 dccp_diag


Shows the name of the module that depends on the current module.

It may be the case that you need to find modules based on the name, size, or dependencies. To filter the output of
the lsmod command to only show specific modules, use the grep command:

Note

The following examples may not match the output in the virtual environment.

sysadmin@localhost:~$ lsmod | grep ext4


ext4 465245 2
crc16 12503 1 ext4
mbcache 17476 1 ext4
jbd2 82480 1 ext4

The output above shows the modules that work together to support the ext4 filesystem. In other words, the ext4
filesystem depends on these modules.

Additionally, you can get more details about a module by using the modinfo command. For example, to learn more
about the snd kernel module, execute the following command:

sysadmin@localhost:~$ modinfo snd


filename: /lib/modules/3.13.0-35-generic/kernel/sound/core/snd.ko
alias: char-major-116-*
license: GPL
description: Advanced Linux Sound Architecture driver for soundcards.
author: Jaroslav Kysela <perex@perex.cz>
license: GPL
description: Jack detection support for ALSA
author: Mark Brown <broonie@opensource.wolfsonmicro.com>
srcversion: 0EBCEABF53FC967306ED228
depends: soundcore
intree: Y
vermagic: 3.13.0-35-generic SMP mod_unload modversions
signer: Magrathea: Glacier signing key
sig_key: B1:41:4A:E9:6C:1B:0E:BB:7C:14:1F:A4:05:C1:F6:C9:8E:8A:66:F0
sig_hashalgo: sha512
parm: debug:Debug level (0 = disable) (int)
parm: slots:Module names assigned to the slots. (array of charp)
parm: major:Major # for sound driver. (int)
parm: cards_limit:Count of auto-loadable soundcards. (int)

To get a list of all available modules, use the modprobe -l command:

sysadmin@localhost:~$ modprobe -l | head


kernel/arch/x86/kernel/cpu/mcheck/mce-inject.ko
kernel/arch/x86/kernel/cpu/cpufreq/powernow-k8.ko
kernel/arch/x86/kernel/cpu/cpufreq/mperf.ko
kernel/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.ko
kernel/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.ko
kernel/arch/x86/kernel/cpu/cpufreq/p4-clockmod.ko
kernel/arch/x86/kernel/test_nx.ko
kernel/arch/x86/kernel/microcode.ko
kernel/arch/x86/crypto/aes-i586.ko
kernel/arch/x86/crypto/twofish-i586.ko

Normally, kernel modules are loaded automatically by the kernel. To load a module manually, execute the
modprobe command with the name of the module.
For example, to load the ext4 module, execute the modprobe ext4 command. Note that if the module is loaded
successfully, there is no output to this command. A quick use of the lsmod command will show if the module was
loaded properly.

One nice feature of the modprobe command is that it will automatically load all dependency modules, so in the
case of loading the ext4 module, it would automatically load the crc16, mbcache, and jdb2 modules.

The modprobe command can also be used to remove modules from memory with the -r option. Executing the
modprobe -r ext4 command would remove the ext4 module from memory, and it will automatically remove the
crc16, mbcache, and jdb2 modules from memory as long there was nothing else that depended upon them:

sysadmin@localhost:~$ lsmod | grep ext4


ext4 465245 2
crc16 12503 1 ext4
mbcache 17476 1 ext4
jbd2 82480 1 ext4
sysadmin@localhost:~$ modprobe -r ext4
sysadmin@localhost:~$ lsmod | grep ext4
Key Terms
lsmod
Prints the contents of the /proc/modules file
Section 15.7
lspci
Prints detailed information about all PCI buses and devices in the system
Section 15.5
lsusb
Prints detailed information about all USB buses and devices in the system
Section 15.5
modprobe
Used to add a loadable kernel module (LKM) to the Linux kernel or to remove an LKM from the kernel
Section 15.7
swap space
Used when the amount of physical memory (RAM) is full. If the system needs more memory resources and
the RAM is full, inactive pages in memory are moved to the swap space.
Section 15.2.2
LAB 15

15.0 Introduction
In order to provide the functionality you need to apply these concepts, this VM may require a minute or two to
load.

There are a variety of files and commands that will provide useful information regarding the hardware that is
attached to the system. This information can be used to configure or fine-tune how the hardware behaves on the
system. The information is also very useful when troubleshooting hardware device issues.

15.1 Step 1
Please use the Ubuntu image to complete the following steps. Select the Ubuntu PC by clicking on the tab in the
window on the right side of the screen.

Log in to the system using the root account. When prompted, provide the root password:

root
netlab123
Ubuntu 18.04.2 LTS ubuntu tty1
ubuntu login: root
Password:

Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-45-generic x86_64)


* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage

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.

root@ubuntu:~#

15.2 Step 2
Unfortunately, hard links can't be made to directories. Execute the following command to see a demonstration:

ln /etc /myetc
[root@localhost test]# ln /etc /myetc
ln: '/etc': hard link not allowed for directory
15.3 Step 3
For a more detailed look at your CPU's features, execute the following command:

cat /proc/cpuinfo
root@ubuntu:~# cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 44
model name : Intel(R) Xeon(R) E5620 @2.40GHz
stepping : 2
microcode : 0x1
cpu MHz : 2393.992
cache size : 12288 KB
physical id : 0
siblings : 1
core id : 0
cpu cores : 1
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 11
wp : yes
flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat
pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1g rdtscp lm constant_tsc arch_perfmon
rep_good nopl eagerfpu pni pclmulqdq ssse3 cx16 pcid sse4_1 sse4_2 x2apic popcnt
tsc_deadline_timer aes hpervisor lahf_lm tsc_adjust arat

bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf


bogomips : 4787.98
clflush size : 64
cache_alignment : 64
address sizes : 40 bits physical, 48 bits virtual
power management:

Note the highlighted flags: field in the output above. One of the key settings of the /proc/cpuinfo file is the
flags that the CPU supports, which are a feature of the CPU. Some advanced CPU functions require specific flags.

15.4 Step 4
The free command gives details on total, used, and free memory the system has access to, including swap space
on fixed disks that can be used as temporary storage for memory operations. Your output may differ, depending on
system loads.

To display information about memory usage, execute the following command:

free
root@ubuntu:~# free
total used free shared buff/cache available
Mem: 498828 50920 344884 4532 103024 420876
Swap: 5517308 0 5517308
15.5 Step 5
The /proc/meminfo file provides a very detailed breakdown of how much memory a system has and how it is
being used. For a more detailed look at memory usage, execute the following command:

cat /proc/meminfo | less


root@ubuntu:~# cat /proc/meminfo | less
MemTotal: 492952 kB
MemFree: 298216 kB
MemAvailable: 436160 kB
Buffers: 10544 kB
Cached: 124068 kB
SwapCached: 0 kB
Active: 117304 kB
Inactive: 39200 kB
Active(anon): 22268 kB
Inactive(anon): 216 kB
Active(file): 95036 kB
Inactive(file): 38984 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 524284 kB
SwapFree: 524284 kB
Dirty: 0 kB
WriteBack: 0 kB
AnonPages: 21712 kB
Mapped: 27868 kB
Shmem: 576 kB
Slab: 26388 kB
SReclaimable: 11952 kB
SUnreclaim: 9316 kB
KernelStack: 1376 kB
PageTables: 3568 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 5766720 kB
Committed_AS: 236336 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 4708 kB
VmallocChunk: 34359731508 kB
HardwareCorrupted: 0 kB
AnonHugePages: 0 kB
:

Type Q to exit the less command:

q
15.6 Step 6
Execute the following command to display the USB devices that are attached to the system:

lsusb
root@ubuntu:~# lsusb
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 002: ID 0627:0001 Adomax Technology Co., Ltd

Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

Since the only devices listed in the output above are the root hub, and Adomax Technology Co.,Ltd, we can
determine that there are no real USB devices attached to the system. The root hub is the USB port itself.

15.7 Step 7
Please use the CentOS image to complete the following steps. Select the CentOS PC by clicking on the tab in the
window on the right side of the screen.

Log in to the system using the root account. When prompted, provide the root password:

root
netlab123
CentOS Linux 7 (Core)
Kernel 3.10.0-957.el7.x86_64 on an x_86_64

centos login:
Password:
[root@localhost ~]#

Display the hardware devices by executing the following command:

lspci
[root@centos ~]# lspci
00:00.0 Host bridge: Intel Corporation 440FX - 82441FX PMC [Natoma] (rev 02)
00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II]
00:01.1 IDE interface: Intel Corporation 82371SB PIIX3 IDE [Natoma/Triton II]
00:01.2 USB controller: Intel Corporation 82371SB PIIX3 USB [Natoma/Triton II] (rev 01)
00:01.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 (rev 03)
08:02.0 VGA compatible controller: Device 1234:1111 (rev 02)
00:03.0 Ethernet controller: Intel Corporation 82540EM Gigabit Ethernet Controller (rev 03)
00:1a.0 USB controller: Intel Corporation 82371SB PIIX3 [Natoma/Triton II] (rev 01)

Some of the devices displayed in the output above include:

 IDE Interface - A device that permits you to attach IDE hard drives to the system.

00:01.1 IDE interface: Intel Corporation 82371SB PIIX3 IDE [Natoma/Triton II]

 VGA compatible controller - A device that permits you to attach a monitor to the system.

08:02.0 VGA compatible controller: Device 1234:1111 (rev 02

 Ethernet controller - A device that allows you to connect to the network.

00:03.0 Ethernet controller: Intel Corporation 82540EM


15.8 Step 8
Display devices along with their device code by executing the lspci command with the -nn option:

lspci -nn
[root@cenos ~]# lspci -nn
00:00.0 Host bridge [0600]: Intel Corporation 440FX - 82441FX PMC [Natoma] (rev
02)[8086:1237]
00:01.0 ISA bridge [0601]: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II]
[8086:7000]
00:01.1 IDE interface [0101]: Intel Corporation 82371SB PIIX3 IDE [Natoma/Triton II]
[8086:7010]
00:01.3 Bridge [0680]: Intel Corporation 82371AB/EB/MB PIIX4 ACPI [8086:7113] (rev 03)
08:02.0 VGA compatible controller [0300]: Device [1234:1111] (rev 02)
00:03.0 Ethernet controller [0200]: Intel Corporation 82540EM Gigabit Ethernet Controller
[8086:100e](rev 03)
00:1a.0 USB controller 0c03]: Intel Corporation 82371SB PIIX3 [Natoma/Triton II] [8086:7020]
(rev 01)
00:01.2 USB controller [0c03]: Intel Corporation 82371SB PIIX3 USB [Natoma/Triton II]
[8086:7020] (rev 01)
Important Take note of the highlighted USB controller device code, as you will need this code to perform the next
example.

15.9 Step 9
Using the highlighted value from the output of the previous command, display the details about the USB
Controller:

lspci -v -d 8086:7020
[root@localhost ~]# lspci -v -d 8086:7020
00:01.2 USB controller [0c03]: Intel Corporation 82371SB PIIX3 USB [Natoma/Triton II]
[8086:7020] (rev 01) (prog-if 00 [UHCI])
Subsystem: Red Hat, Inc. QEMU Virtual Machine
Flags: bus master, fast devsel, latency 0, IRQ 11
I/O ports at c040 [size=32]

Kernel driver in use: uhci_hcd


00:04.0 USB controller: Intel Corporation 82371SB PIIX3 USB [Natoma/Triton II] (rev 01)
(prog-if 00 [UHCI])
Subsystem: Red Hat, Inc. QEMU Virtual Machine
Physical Slot: 4
Flags: bus master, fast devsel, latency 0, IRQ 10
I/O ports at c060 [size=32]

Kernel driver in use: uhci_hcd


15.10 Step 10
Display all of the SATA drives on the system by executing the following command:

ls /dev/sd*
[root@centos ~]# ls /dev/sd*
/dev/sda /dev/sda1 /dev/sda2
[root@centos ~]#

Devices that begin with sd in the /dev directory are device files that represent SATA or SCSI devices.

15.11 Step 11
Display kernel modules that are loaded into memory by executing the lsmod command:

lsmod | less
[root@centos ~]# lsmod | less
Module Size Used by
crc32_pclmul 13133 0
ghash_clmulni_intel 13273 0
ppdev 17671 0
aesni_intel 189414 0
lrw 13286 0 aesni_intel
gf128mul 15139 1 lwr
glue_helper 13990 1 aesni_intel
ablk_helper 21190 3 aesni_intel
cryptd 21190 3 ghash_clmulni_intel, aesni_intel, ablk_helper
joydev 17389 0
Some output has been omitted in the example above for brevity.

Type Q to exit the less command:

15.12 Step 12
Display information about the dm_mod module by executing the following command:

modinfo dm_mod | less


[root@centos ~]# modinfo dm_mod | less

Filename: /lib/modules/3.10.0-957.el7.x86_64/kernel/drivers/md/dm-mod.ko.xz
license: GPL
author: Joe Thornber <dm-devel@redhat.com>
description: device-mapper driver
alias: devname:mapper/control
alias: char-major-10-236
retpoline: Y
rhelversion: 7.6
srcversion: BA7CED77E4803DA1F325BC6
depends:
intree: 3.10.0-957.el7.x86_64 SMP mod_unload modversions
signer: CentOS Linux kernel signing key
sig_key: B7:0D:CF:0D:F2:D9:B7:F2:91:59:24:82:49:FD:6F:E8:7B:78:14:2
sig_hashalgo: sha256
PARM: reserved_rq_based_ios:Reserved IOs in request-based mempools (uint)
parm: use_blk_mq:Use block multiqueue for request-based DM devices (bool)
parm: dm_mq_nr_hw_queues:Number of hardware queues for request-based dm-mq devices
(uint)
parm: dm_mq_queue_depth:Queue depth for request-based dm-mq devices (uint)
:

Type Q to exit the less command:

15.13 Step 13
Display information about the dm_log module by executing the following command:

modinfo dm_log
[root@centos ~]# modinfo dm_log
filename: /lib/modules/3.10.0-957.e17.x86_64/kernel/drivers/md/dm-log.ko.xz
license: GPL
author: Joe Thornber, Heinz Mauelshagen <dm-devel@redhat.com>
description: device-mapper dirty region log
retpoline: Y
rhelversion: 7.6
srcversion: 2520F689AFECC997AB36ADE
depends: dm-mod
intree: Y
vermagic: 3.10.0-957.el7.x86_64 SMP mod_unload modversions
signer: CentOS Linux kernel signing key
sig_key: B7:0D:CF:0D:F2:D9:B7:F2:91:59:24:82:49:FD:6F:E8:7B:78:14:27
sig_hashalgo: sha256

Notice that the dm_log module has a dependency module: dm-mod. Because the modules are currently loaded into
memory, you can see this dependency by looking at the output of the lsmod command:

lsmod
[root@centos ~]# lsmod
...
floppy 69432 0
dm_mirror 22289 0
dm_region_hash 20813 1 dm_mirror
dm_log 18411 2 dm_region_hash,dm_mirror
dm_mod 124407 8 dm_log,dm_mirror
Some output has been omitted in the example above for brevity.
15.14 Step 14
Determine if the fat or vfat modules are currently loaded into memory by executing the following command:

lsmod | grep fat


[root@centos ~]# lsmod | grep fat
[root@centos ~]#

The lack of output from the previous command indicates that neither the fat nor vfat module is currently loaded
into memory.

15.15 Step 15
Load the vfat module into memory by executing the following command:

modprobe vfat
[root@centos ~]# modprobe vfat
[root@centos ~]#

15.16 Step 16
Verify that the vfat module has been loaded by executing the following command:

lsmod | grep fat


[root@centos ~]# lsmod | grep fat
vfat 10584 0
fat 54992 1 vfat

15.17 Step 17
Try to remove the fat module from memory by executing the following command:

modprobe -r fat
[root@centos ~]# modprobe -r fat
modprobe: FATAL: Module fat is in use.
15.18 Step 18
Remove the vfat module from memory and verify by executing the following commands:
modprobe -r vfat
lsmod | grep fat
[root@centos ~]# modprobe -r vfat
[root@centos ~]# lsmod | grep fat
[root@centos ~]#
Chapter 16: The Boot Process

16.1 Introduction
Booting is the process of bringing the system from an off status to a running operating system. It is very important
to understand this process, in order to be able to fix boot problems when they occur and for modifying system
states called runlevels or on systemd devices, targets.

The boot process takes place in four main stages, some of which are modified by administrators, while for the
others, it is sufficient just to be aware of the actions taking place:

 Firmware Stage
 Bootloader
 Kernel Stage
 Init Stage
16.2 Firmware Stage
The firmware stage is the first stage to take place after the computer is powered on. At this point, the computer has
power but needs to start executing some software that will eventually get a full kernel booted.

Most PC firmware is referred to as the Basic Input/Output System (BIOS). The BIOS is stored on the
motherboard in non-volatile memory such as Read Only Memory (ROM) or flash memory.

The BIOS has three main jobs to perform as part of the first stage of the boot process:

 Execute a power-on self test (POST) in order to ensure the hardware of the system is functioning properly.
The POST runs some basic functional checks on the CPU, memory, and peripherals so that obvious errors,
such as missing memory chips or malfunctioning disk devices are found early in the boot cycle.
 Enumerate available hardware such as memory, disks, and USB devices.
 Find the proper boot drive from the available storage devices and load the Master Boot Record (MBR)
from that device. The Master Boot Record is the first sector (or 512 bytes) of the disk.

Consider This

Even on systems that have replaced the traditional BIOS with the Unified Extensible Firmware Interface
(UEFI), the system firmware is still often referred to as BIOS. Both are firmware, the hardware-embedded tiny
operating systems that manage the interface between hardware and the OS that you will be booting. BIOS is
considered to be dated because it is limited to 16-bit memory addressing, can only be a certain size and boots by
reading the first sector of a drive.UEFI uses a special partition on a drive called an EFI System Partition to store the
bootloader for an OS.

The BIOS and UEFI firmware have become more sophisticated over time. However, on most boot-ups, they are
there to perform the three main steps above in order to get to the bootloader stage.

16.3 Bootloader Stage


The Master Boot Record contains a partition table and a very small amount of executable code called the first stage
bootloader whose purpose is to load the more feature-rich second stage bootloader. The bootloader will perform
several operations, but the primary task is to load the Linux kernel into memory and execute it.

If a bootloader is able to fit entirely into the first 512 bytes of the Master Boot Record and to start the operating
system with this limited amount of code, it is considered a single stage bootloader. A second stage is necessary
when the code needed to initialize the system properly and start the operating system does not fit in the MBR. In
this case, the first stage bootloader is there to point to the second stage bootloader, which can be larger and will be
the bootloader that actually starts the operating system. Once that has occurred, the kernel takes over booting the
system.

The most common bootloader used on machines is the Grand Unified Bootloader (GRUB). The latest version of
GRUB supports booting Linux from a system using UEFI, interactive editing of the menu during bootup, and much
more.

UEFI systems give the firmware stage a lot more memory and capabilities so that it can handle much larger and
more complicated hardware.

Consider This
Outside of the IBM PC compatible architectures, there are additional bootloaders that are used. For Linux systems
to boot on Sparc hardware, there is Sparc Improved bootLOader (SILO), and for PowerPC hardware, there is
Yet Another BOOTloader (YABOOT).

⁠ It is also possible to boot off the network through the Preboot Execution Environment (PXE). In the PXE
system, a compatible motherboard and network card contain enough intelligence to acquire an address from the
network and use the Trivial File Transfer Protocol (TFTP) to download a special bootloader from a server.

As the bootloader is just some software that gets a kernel to run, it is possible to boot multiple operating systems at
different times off of one computer in a process known as dual or multi-booting. The kernel that the bootloader is
trying to run could be a Linux kernel, it could be a Microsoft Windows image, or it could be a bootable CD.

The bootloader can also pass parameters to the kernel, such as to boot into a maintenance mode or to enable or
disable certain hardware. This is done by manipulating the bootloader configuration. GRUB provides a reasonably
powerful command line interface that lets an administrator make changes to the kernel before it boots without
requiring that the configuration be written to disk.

The bootloader then loads the kernel from disk into memory and transfers control over. The system is now running
Linux and may finish booting.

16.4 Kernel Stage


Now that the bootloader has loaded the kernel into memory, there is much work to be done before programs can be
loaded. The kernel must initialize any hardware drivers and get the root / filesystem mounted for the next stage.
These two tasks are actually quite complicated because the facilities provided by the BIOS to access the hardware
are quite limited. Therefore, the kernel must boot the system in several phases.

The kernel itself is laid out much like a regular executable except that it must be self-contained. Shared libraries are
not available at this point in the boot process so the kernel itself is statically linked, meaning that the kernel can
only rely on information that was already compiled in the kernel at boot time and not on information in the shared
libraries. This kernel typically lives in the /boot partition which, on most hardware, is in a separate partition that’s
kept close to the beginning of the hard drive. This location is important for some BIOS and bootloader
combinations that can only access the first 1024 cylinders of the disk.

The /boot directory, alternatively the /boot/efi directory, is one of the most important directories in the File
Hierarchy Standard (FHS). Most modern systems use the UEFI standard for specifying the exact location where
the computer looks for the files it needs to start up. You may hear the term bootstrap used in this context, which
simply signifies the method for the computer BIOS to locate and load the first part of the operating system when
the computer powers up.

If the BIOS is not set correctly, the system cannot load its bootstrap programs, and the startup process will fail.
This parameter is normally set by interrupting the boot sequence at the beginning of startup (often with the F12 or
Esc key) and entering the built-in BIOS configuration program. See instructions from the hardware manufacturer
for the exact process and options available.

As the size of the kernel increased over time, developers found it better to compress the kernel to make it fit within
the limitations of the BIOS. Therefore, the executable comprising the kernel will decompress itself as it is loaded,
leading to the name of zImage for the kernel, with the letter z being associated with the zlib Unix compression
library.
Over time, the kernel grew even more in size, and it became a problem to load the whole kernel into a consecutive
block of memory. The bzImage kernel format came into being that allowed the kernel to be loaded into multiple
memory blocks, specifically higher memory.

Consider This

The b in bzimage stands for big. It is NOT an indication that bzip2 is being used for compression of the image,
gzip is still used for compression of the image.

⁠The Linux kernel must mount the root filesystem in order to get to the next step and to make the system useful.
However, it is possible that the root filesystem exists on a device that the kernel does not know how to support.
The solution to this is the initial RAM disk initrd. The kernel drivers necessary to continue the boot are bundled
into the filesystem that is stored beside the kernel itself in /boot. The kernel boots, mounts the initrd, loads the
drivers inside, and then remounts the real root filesystem using the new drivers. This allows drivers to be added to
the kernel easily and for the kernel to mount the root filesystem over almost any storage hardware—even if it’s via
a network.

As the kernel is booting, it is able to initialize recognized hardware and make detected devices available to the rest
of the operating system.

The kernel’s final job is to start the first process on the system. The first process will normally have a process id
(PID) of 1; on a System V system, the name of this process is init.

Note

On systemd systems, the /sbin/init file is a symbolic link to the /usr/lib/systemd/systemd file for purposes
of compatibility.

To show the first process, init, execute the ps command using the following non-BSD options, which will show
all processes running on a system in a hierarchical format:

sysadmin@localhost:~$ ps -ejH
PID PGID SID TTY TIME CMD
1 1 1 ? 00:00:00 init
32 32 32 ? 00:00:00 rsyslogd
37 37 37 ? 00:00:00 cron
39 39 39 ? 00:00:00 sshd
56 56 56 ? 00:00:00 named
69 1 1 ? 00:00:00 login
79 79 1 ? 00:00:00 bash
676 676 1 ? 00:00:00 ps

The first process is responsible for much of the operation of the system from here on in. For our purposes, we use
/sbin/init for consistency, keeping in mind that a different system may be running systemd instead of System V
for process management.

In some cases, such as embedded hardware, the init process could be a shell or a specialized daemon. In any case,
this first process will start the daemons that the rest of the system will use. This process will be the parent process
for any process that otherwise is missing a parent. This process persists for the life of the system.

16.5 The init Stage


The init stage finishes booting the system. The first process of the operating system (also called init) is started.
The init process has three important responsibilities:

 Continue the booting process to get services running, login screens displaying, and consoles listening.
 Start all other system processes.
 Adopt any process that detaches from its parent.

Until recently, this process followed a design that was established with the release of System V of Unix, which is
sometimes referred to as SysVinit. The actual process that is executed is the init process. Recently, other
programs have emerged to compete with and replace the traditional init process with Upstart and systemd.

If the system uses the traditional init program, then the /etc/inittab file is used to determine what scripts will
be executed to start the services that will be available on the system.

The inittab file points to other scripts that do the work, usually stored in the /etc/init.d directory. There will
be more discussion of these scripts later, but in general, each service the system will run has a script that can start,
stop, and restart a service, and init will cause each of these to be run in turn as needed to get the system to the
desired state.

If the traditional init has been replaced with Upstart, the scripts in the /etc/init directory are used to complete
system initialization.

If the traditional init has been replaced with Systemd, then the files in the /etc/systemd directory are used for
starting up and running the system.

Even if your system is using Systemd or Upstart as a replacement for the traditional init process, both
replacements use an executable named init with the /sbin/init path name. This is to maintain compatibility
with many legacy processes. So, while some of the behavior of Systemd and Upstart will be different, they have
some features that are similar to the traditional init process.

While your system will only use one of these booting technologies, it is important to understand all three. For
example, while your current system uses the SysVinit technique, you might find yourself working on a different
distribution in the future that makes use of Upstart. In any case, all three processes are testable topics on the LPIC
exams.

16.5.1 initramfs
Introduced in the 2.6 kernel timeframe, the initramfs is the initial root filesystem that a Linux system typically
has access to. Think of it as a temporary "starter" filesystem that provides the files and drivers that are necessary to
start the real root filesystem and continue the system startup.

The initramfs filesystem is a workaround to a "chicken or the egg" problem; something cannot happen before the
other, and vice-versa, ad infinitum. For example, the kernel may require a disk driver to access a disk, but that
driver is located on the disk it wants to access. The two workarounds to this dilemma are 1) use initramfs or 2)
compile the driver into the kernel.
However, compiling the driver into the kernel has its own problems, not the least of which is it's considered
somewhat inelegant and causes the kernel to be larger and take longer to load. The issue is compounded if the
driver needs to be updated as it's compiled into the kernel.

The situation becomes even more complex when the system has devices or filesystems that require a userspace
program be executed or a user interaction with a userspace program in order to load. Since the original location of
these userspace programs is the disk they are enabling to be loaded, it becomes a circular problem.

Consider This

User space and kernel space are the two regions of RAM that the Linux kernel manages. Programs running in
Kernel space have access to all the regions of RAM and when a program requests access to something, the kernel
will access it in a safe manner and return the information to the program. User space RAM has restrictions,
programs running there cannot access all of the kernel space RAM or RAM used by other programs, all access to
those regions must be made via system calls and be managed by the kernel.

The initramfs is a cpio archive, which can be inserted into a certain spot in the kernel, whose contents are
unpacked by the kernel and loaded into a RAM disk by the kernel for access. The kernel will note the initramfs
cpio archive has contents, create a temporary filesystem RAM disk called tmpfs, and unpack the contents of the
cpio archive into it.

After being unpacked, the kernel will launch the init script included in the root / filesystem of the initramfs
RAM disk, which will then load the necessary drivers and execute the required userspace programs needed to load
the real root filesystem for the system. (A typical use case would be Logical Volume Manager (LVM), RAID, or
encrypted filesystems.)

After the initramfs-included init script is done loading the appropriate drivers and loading the real root
filesystem, it transfers control the /sbin/init binary program on the real root filesystem to continue the
initialization of the system.

Once the kernel is fully booted and the real root filesystem is mounted, the memory allocated to the initial RAM
disk can be freed. This is the main advantage of placing drivers in initramfs instead of compiling them into the
kernel; if a driver in initramfs is not needed, it will not continue to occupy RAM after the boot stage.

The initramfs is built initially with the mkinitramfs utility, or updated by the update-initramfs utility, which
can also create a new initramfs. These commands will gather the needed files and userspace utilities from their
installed locations to a temporary directory, archived by cpio and then compressed with gzip.

Note

Creating an initramfs is out of the scope of the LPIC objectives and thus, this course.
16.6 Kernel Messages
The dmesg command can be executed after booting the system to see the messages generated by the kernel during
boot time. This is useful when the system doesn't appear to boot correctly; the messages displayed can help an
administrator troubleshoot the boot process.

⁠ Kernel messages are stored in a ring buffer of limited size; therefore, the messages that are generated at boot time
may be overwritten later as the buffer fills up. It is possible that some of the kernel messages generated at boot time
may be stored in the /var/log/dmesg file. Each time the system boots, the /var/log/dmesg file is overwritten
with the messages that were generated during the boot process.

It is common to execute the dmesg command upon connecting a new device to the system. This allows the
administrator to see how the kernel dealt with the new device and usually to see what path name the new device
has been assigned.

sysadmin@localhost:~$ dmesg | tail -n 20


[5974251.345037] br0: port 2(veth2) entered forwarding state
[5974264.554578] br0: port 1(vxlan1) entered forwarding state
[5974266.346778] br0: port 2(veth2) entered forwarding state
[5974312.446398] br0: renamed from ov-0044a8-d8912
[5974312.686393] vxlan1: renamed from vx-0044a8-d8912
[5974312.744241] device vxlan1 entered promiscuous mode
[5974312.807735] br0: port 1(vxlan1) entered forwarding state
[5974312.810025] br0: port 1(vxlan1) entered forwarding state
[5974313.419196] veth2: renamed from vethe3e05ea
[5974313.475445] device veth2 entered promiscuous mode
[5974313.513109] IPv6: ADDRCONF(NETDEV_UP): veth2: link is not ready
[5974313.513114] br0: port 2(veth2) entered forwarding state
[5974313.515380] br0: port 2(veth2) entered forwarding state
[5974313.788114] br0: port 2(veth2) entered disabled state
[5974314.346447] eth0: renamed from veth09f186c
[5974314.439047] IPv6: ADDRCONF(NETDEV_CHANGE): veth2: link becomes ready
[5974314.447452] br0: port 2(veth2) entered forwarding state
[5974314.450219] br0: port 2(veth2) entered forwarding state
[5974327.857296] br0: port 1(vxlan1) entered forwarding state
[5974329.457467] br0: port 2(veth2) entered forwarding state
16.7 The /var/log/messages File
Kernel messages and other system-related messages are typically stored in the /var/log/messages file. This file,
which is considered the main log file, is alternatively named /var/log/syslog in some distributions. The contents
of the /var/log/messages file will look like the following:

Note

The following examples represent a system that is different from this virtual machine. The example may not match
the output in our virtual environment.

[root@centos ~]# tail /var/log/messages


May 27 23:01:59 localhost named[1007]: validating @0x7f0d34433a50: .
DNSKEY: unable to find a DNSKEY which verifies the DNSKEY RRset and also
matches a trusted key for '.'
May 27 23:01:59 localhost named[1007]: validating @0x7f0d34433a50: .
DNSKEY: please check the 'trusted-keys' for '.' In named.conf .
May 27 23:01:59 localhost named[1007]: error (network unreachable)
resolving 'dlv.isc.org/DNSKEY/IN' : 2001:500:e::1#53
May 27 23:01:59 localhost named[1007]: error (network unreachable)
resolving 'dlv.isc.org/DNSKEY/IN' : 2001:500:e::1#53
May 27 23:01:59 localhost named[1007]: error (network unreachable)
resolving 'dlv.isc.org/DNSKEY/IN' : 2001:500:e::1#53
May 27 23:01:59 localhost named[1007]: error (network unreachable)
resolving 'dlv.isc.org/DNSKEY/IN' : 2001:500:e::1#53
May 27 23:01:59 localhost named[1007]: error (network unreachable)
resolving 'ns.iscafilias-nst.info/AAAA/IN' : 2001:500:e::1#53
May 27 23:01:59 localhost named[1007]: error (network unreachable)
resolving 'ns.iscafilias-nst.info/AAAA/IN' : 2001:500:e::1#53
May 27 23:01:59 localhost named[1007]: error (network unreachable)
resolving 'ns.iscafilias-nst.info/AAAA/IN' : 2001:500:e::1#53
May 27 23:01:59 localhost named[1007]: error (network unreachable)
resolving 'ns.iscafilias-nst.info/AAAA/IN' : 2001:500:e::1#53

 Traditionally, the primary log file is updated with new log entries by the combination of the syslogd and klogd
daemons. Replacements for these daemons include rsyslogd and syslog-ng daemons.

Note

A daemon is a process that automatically runs as a background process. System logging daemons such as syslogd,
klogd, rsyslogd, and other logging daemons are background processes that send system messages to log files.

As is customary in Linux, the letter “d” in the process name signifies it is a daemon. For example, syslogd is the
daemon that supports the syslog system logging protocol.

On a systemd-based system, the journald daemon is the logging mechanism, and it’s configured by the
/etc/systemd/journald.conf file. The format of a journald log file is binary, which is different from the more
traditional logging daemons mentioned previously. Use the following command to view the journald
configuration settings in the /etc/systemd/journald.conf file:

[root@centos ~]# cat /etc/systemd/journald.conf


#Seal=yes
#SplitMode=uid
#SyncIntervalSec=5m
#RateLimitInterval=30s
#RateLimitBurst=1000
#SystemMaxUse=
#SystemKeepFree=
#SystemMaxFileSize=
#RuntimeMaxUse=
#RuntimeKeepFree=
#RuntimeMaxFileSize=
#MaxRetentionSec=
#MaxFileSec=1month
#ForwardToSyslog=yes
#ForwardToKMsg=no
#ForwardToConsole=no
#ForwardToWall=yes
#TTYPath=/dev/console
#MaxLevelStore=debug
#MaxLevelSyslog=debug
#MaxLevelKMsg=notice
#MaxLevelConsole=info
#MaxLevelWall=emerg
#LineMax=48k
[root@centos ~]# _

The main log file on a systemd-based device is the /var/log/journal file for persistent logging or in the
/run/log/journal file for RAM-based and non-persistent logging.

The journald log files are viewed with the journalctl command, such as this one which shows similar output to
the dmesg command:

[root@centos ~]# journalctl -b


-- Logs begin at Tue 2019-06-04 16:21:58 UTC, end at Tue 2019-06-04 16:26:25 UTC
Jun 04 16:21:58 centos systemd-journal[84]: Runtime journal is using 4.0M (max a
Jun 04 16:21:58 centos kernel: Initializing cgroup subsys cpuset
Jun 04 16:21:58 centos kernel: Initializing cgroup subsys cpu
Jun 04 16:21:58 centos kernel: Initializing cgroup subsys cpuacct
Jun 04 16:21:58 centos kernel: Linux version 3.10.0-957.e17.x86_64 (mockbuild@kb
Jun 04 16:21:58 centos kernel: Command line: BOOT_IMAGE=/vmlinuz-3.10.0-957.e17.
Jun 04 16:21:58 centos kernel: e820: BIOS-provided physical RAM map:
Jun 04 16:21:58 centos kernel: BIOS-e820: [mem 0x0000000000000000-0x000000000009
Jun 04 16:21:58 centos kernel: BIOS-e820: [mem 0x000000000009fc00-0x000000000009
Jun 04 16:21:58 centos kernel: BIOS-e820: [mem 0x00000000000f0000-0x00000000000f
Jun 04 16:21:58 centos kernel: BIOS-e820: [mem 0x0000000000100000-0x000000001ffd
Jun 04 16:21:58 centos kernel: BIOS-e820: [mem 0x000000001ffe0000-0x000000001fff
Jun 04 16:21:58 centos kernel: BIOS-e820: [mem 0x00000000feffc000-0x00000000feff
Jun 04 16:21:58 centos kernel: BIOS-e820: [mem 0x00000000fffc0000-0x00000000ffff
Jun 04 16:21:58 centos kernel: NX (Execute Disable) protection: active
Jun 04 16:21:58 centos kernel: SMBIOS 2.8 present.
Jun 04 16:21:58 centos kernel: DMI: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
Jun 04 16:21:58 centos kernel: Hypervisor detected: KVM
Jun 04 16:21:58 centos kernel: e820: update [mem 0x00000000-0x00000fff] usable
Jun 04 16:21:58 centos kernel: e820: remove [mem 0x000a0000-0x000fffff] usable
Jun 04 16:21:58 centos kernel: e820: last_pfn = 0x1ffe0 max_arch_pfn = 0x4000000
Jun 04 16:21:58 centos kernel: MTRR default type: write-back
Jun 04 16:21:58 centos kernel: MTRR fixed ranges enabled:
Lines 1-24_

The journalctl command is the log file viewer for binary log files. The -b option makes the journalctl
command behave similarly to the dmesg command, by displaying only messages concerning the most recent
bootup, which can be useful for troubleshooting issues regarding the boot process.

Regardless of its format, the binary log files that systemd generates through journald can be read with the
journalctl command but are more difficult to read by standard means such as with the cat or less comands, and
other text file viewers. However, the benefits of the new logging data format make that less important.
On System V systems, the main log file, usually the /var/log/messages file, is a text-based file (or files), which
can be viewed with the traditional text file viewer commands. Whether in binary or text format, log files can be
helpful for analyzing why some services may not start correctly. They can also be helpful to determine why some
devices may not be functioning, as the kernel will place log entries in this log file if it can detect a device and as it
loads the appropriate kernel modules or drivers to support new devices.

Although the /var/log/messages file is considered the main log file, there are other log files in the /var/log
folder, which may need to be examined when trying to troubleshoot system service issues. For instance, the httpd
apache web server daemon manages its own log files in another location, like the /var/log/httpd/error_log
file. Traditionally, all log files are stored in the /var/log directory.
KEY TERMS

/etc/inittab
Configuration file read by init when it starts up to determine what process to start for various run levels.
Section 16.5.1
BIOS
An acronym for Basic Input Output System, is software that controls basic computer hardware functions.
BIOS is stored on a motherboard chip.
Section 16.2
SysVinit
The traditional service management package for Linux, containing the init program (the first process that is
run when the kernel has finished initializing) as well as some infrastructure to start and stop services and
configure them.
Section 16.5
UEFI
The Unified Extensible Firmware Interface (UEFI) is system firmware. UEFI uses a special partition on a
drive called an EFI System Partition to store the bootloader for an OS. ⁠
Section 16.3
bootloader
The first piece of software started by the BIOS or UEFI. It is responsible for loading the kernel with the
wanted kernel parameters, and initial RAM disk before initiating the boot process.
Section 16.3
dmesg
Displays the contents of the system message buffer
Section 16.6
init
The parent of all processes on the system, it is executed by the kernel and is responsible for starting all
other processes.
Section 16.5
initramfs
Iinitial RAM file system, used by Linux systems to prepare the system during boot before the operating
systems' init process starts.
Section 16.5.1
journalctl
The log file viewer for binary log files.
Section 16.7
kernel
The central module of an operating system. It is the part of the operating system that loads first, and it
remains in main memory.
Section 16.4
systemd
A full replacement for init with parallel starting of services and other features, used by many distributions.
Section 16.5
LAB 16
Chapter 17: Bootloaders

17.1 Introduction
The boot process for a computer goes through several distinct steps, starting from no power being applied and
completing with a fully-running operating system. The bootloader is a critical part of the system startup process,
essentially taking the computer from its reading of firmware for a boot device, to the point at which control is
transferred to the system initialization scheme for the operating system that is chosen to run the computer.

The two bootloaders most commonly used with Linux are the Grand Unified Bootloader (GRUB), or the Grand
Unified Bootloader 2 (GRUB 2), though the latter is the one that is used most often. Previously, the Linux
Loader (LILO) was the one most implemented, but it has fallen out of wide usage and is present mostly on older
or legacy systems.

Consider This

LILO was the first major bootloader to be used for running Linux on Intel PCs. Though a simple program, LILO is
still capable of multi-booting between different operating systems. The way LILO works is that rather than
analyzing the filesystems that may contain the kernel image, LILO stores this information when it installs itself. As
such, LILO doesn’t need to know about the underlying filesystem. However, as configuration changes are made,
LILO needs to be manually updated with the new information.

GRUB is a GNU project with the goal of making a bootloader that can boot many different kernels on a variety of
systems. GRUB can read filesystems and dynamically learn about the hardware. An administrator can boot into
GRUB, query the disks, then discover and boot a kernel image. Also, rather than replacing the bootloader
installation on disk each time a configuration change is made, the bootloader automatically reads configuration
files.

As a dynamic bootloader, GRUB also offers a command line interface that can override the settings from the
configuration file. The most typical use of this is to boot into a rescue mode by passing extra kernel parameters or
to specify limitations such as those used for memory troubleshooting.

When a distribution is installed, a bootloader is usually installed automatically, reflecting the hardware particulars
for the system. In most cases, the default bootloader will be either GRUB Legacy (version 0-0.9) or GRUB 2.
Typical customizations at the point of install are to add extra operating systems for multi-booting, changes to go
along with kernel upgrades, and booting into maintenance mode.

Consider This

A major difference between GRUB/GRUB2 and LILO is that the LILO bootloader needs to be updated after
changes are made to configuration files.

Note

In addition, please note that other hardware platforms have their own bootloaders, but they are not within the scope
of the LPIC-1 exam.
17.2 GRUB Legacy Bootloader
Due to the release of a newer version of the GRUB bootloader called GRUB 2, the older version of GRUB is now
called GRUB Legacy. This section will cover the particulars of GRUB Legacy.

17.3 GRUB Legacy Boot Steps


All bootloaders work in stages, as the location for the initial bootloader code is very small, under 512 KB, and
GRUB Legacy gets around this by utilizing 2.5 stages to load the entire bootloader and reach the main system’s
bootloader.

GRUB Legacy typically writes the stage 1 bootloader to the Master Boot Record (MBR), and that is just enough
code to get the stage 1.5 bootloader, which usually occupies the first 30KiB of the disk that directly follows the
MBR. The stage 1.5 loader has just enough code to load up the filesystem drivers needed to load the stage 2 loader
from the /boot/grub location.

The GRUB Legacy bootloading stages will then turn over the rest of the system initialization to the /sbin/init or
systemd equivalent for the continuation of the system boot.

17.4 GRUB Legacy Configuration


Within the GRUB Legacy configuration file, disks are referred to with a special syntax that does not differ based
upon the type of disk. This is different from how the Linux operating system refers to IDE disks.

In GRUB Legacy, the first disk detected is referred to as hd0, the second disk as hd1 and so on. Partitions on disks
are also numbered starting at zero. Therefore, use hd0,0 to refer to the first partition on the first disk, hd1,0 for the
first partition on the second disk, etc.

Note

Device files are used by the operating system to refer to hard drives and partitions. The naming convention is
different than GRUB Legacy's naming convention, which may lead to frustration.

For example, the first SATA device would have a device file name of /dev/sda. The first partition on this device
would be named /dev/sda1. The first IDE device would have a device file name of /dev/hda. So, the first
partition on this device would be named /dev/hda1.

Not only does GRUB Legacy not distinguish between SATA and IDE drives, it also doesn't number drives with
letters like the operating system does. For example, the first hard drive is 0, not a.

Additionally, the partition numbers are different. The operating system numbers the first partition of a drive 1,
while for GRUB Legacy it would be partition 0.

For example, the device /dev/sda1 might be referred to as hd0,0 in GRUB Legacy. The device /dev/hdb3 might
be hd1,2 in GRUB Legacy. The term "might be" is used because the drive number really depends on the order in
which GRUB Legacy "finds" the drives.
Disks and partitions are covered in greater detail in a later chapter.

The GRUB Legacy bootloader is typically installed as part of the installation process. In the event that the GRUB
Legacy bootloader needs to be reinstalled, then GRUB Legacy can be reinstalled by running the following
command:

Note

The following examples may not match the output in our virtual environment.

sysadmin@localhost:~$ grub-install '(hd0)'

The grub-install command shown above will install the GRUB Legacy bootloader to the first disk device in the
system. The grub-install command exists primarily to gather information about the system, its disks,
filesystems, and the location of the /boot/grub directory on disk, and then install the GRUB Legacy bootloader’s
image (with the necessary location information) files to the proper location(s) on the system’s disks/partitions.

Note

GRUB Legacy can have either or both of the following two main configuration files: the /boot/grub/menu.lst
and /boot/grub/grub.conf files. Depending on the distribution, one file is preferred over the other. Examples
include Red Hat distributions focusing on the grub.conf file, and SUSE distributions preferring to use the
menu.lst file. Many distributions simply have one of these files existing as a symbolic link to the other.

GRUB Legacy began life using the menu.lst file, with grub.conf appearing later in its history. For the sake of
clarity and reducing confusion, this section will focus on the newer and more common file location,
/boot/grub/grub.conf.

Because the default is to have a working version of the GRUB configuration file, /etc/grub.conf, generated and
installed by the installation routines, a user may not have to generate a new configuration by hand. However, it is
useful to know what the grub-mkconfig command can do for you in case your configuration is damaged or
somehow gets corrupted on disk.

The grub-mkconfig command will query the running system for the contents of the /boot directory, the contents
of the /etc/default/grub location if it exists, and any scripts that are located in the /etc/grub.d directory.

Next, it will output the properly-formatted configuration file to the specified location. For example, to generate the
/boot/grub/grub.cfg file, you would use the following command:

sysadmin@localhost:~$ grub-mkconfig -o /boot/grub/grub.cfg

In the example above, the -o option specifies the output location, which is the /boot/grub/grub.cfg file. That
file will contain the gathered information formatted accordingly and should be what the system needs to boot the
currently installed system properly.

While the location of grub.conf is the /boot/grub/grub.conf file, on some systems a symbolic link named
/etc/grub.conf makes it easier for the administrator to find:

sysadmin@localhost:~$ ls -l /etc/grub.conf
lrwxrwxrwx 1 root root 22 Jun 18 2012 /etc/grub.conf -> ../boot/grub/grub.conf

Keep in mind that only the root user can modify the /boot/grub/grub.conf file. A typical
/boot/grub/grub.conf file would look something like the following:
#global options
default=0
fallback=1
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
password notencypted

#bootable title sections


title CentOS (2.6.32-358.6.1.el6.i686)
root (hd0,2)
kernel /vmlinuz-2.6.32-358.6.1.el6.i686 ro root=/dev/mapper/vg_livecd-lv_root
rd_NO_LUKS LANG=en_US.UTF-8 rd_LVM_LV=vg_livecd/lv_swap rd_NO_MD rd_LVM_LV=vg_livecd/lv_root
SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
initrd /initramfs-2.6.32-358.6.1.el6.i686.img
title CentOS (2.6.32-358.2.1.el6.i686)
password --md5 $1$D20Ia1$iN6djlheGF0NQoyerYgpp/
root (hd0,2)
kernel /vmlinuz-2.6.32-358.2.1.el6.i686 ro root=/dev/mapper/vg_livecd-lv_root
rd_NO_LUKS LANG=en_US.UTF-8 rd_LVM_LV=vg_livecd/lv_swap rd_NO_MD rd_LVM_LV=vg_livecd/lv_root
SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
initrd /initramfs-2.6.32-358.2.1.el6.i686.img
title OtherOS (Windows)
rootnoverify (hd0,0)
chainloader +1

Comments can be added to the grub.conf file by beginning the lines with a hash # character.

Global options appear first, followed by title blocks, which contain at least three directives: root, kernel, and
initrd. These title blocks define an operating system to boot, as well as options to the kernel that indicate how
to boot the operating system.

Like hard drives, GRUB Legacy numbers each bootable title starting with the number zero. Directives such as
default and fallback are set to equal these values indicating the title to boot. For instance, default=1 will boot
the second title.

Directive Meaning
default= Specifies the title to attempt to boot by default after the timeout number of seconds has passed.
fallback= Specifies the title to attempt to boot if the default title fails to boot successfully.
timeout= Specifies the number of seconds to wait before automatically attempting to boot the default title.
splashimage= Specify a background graphic that appears behind the text of the menu.

hiddenmenu
Prevents GRUB Legacy from displaying all but the default bootable title until the user presses a
key. If the user presses a key, then all titles are displayed.
The title directive starts a new block of directives that form the directives necessary to boot the
title system. A title block ends when the next title directive appears or when the end of the file is
reached.
root Uses the special hard disk syntax to refer to the location of the /boot directory.
This line specifies the kernel image file, followed by all the parameters that are passed to the
kernel
kernel, such as ro for read-only and root=/path/to/rootfs.
This line should specify an initial ramdisk that matches the version and release of the Linux kernel.
initrd This file provides a minimal filesystem during kernel initialization prior to mounting the root
filesystem.
This option can be used as either a global option or a title option. When specified globally, this
password requires the user to submit the specified password before appending, editing, or using the GRUB
Legacy command line. As a title option, this requires the user to submit the password before GRUB
Directive Meaning
will attempt to boot the title.
rootnoverify This directive is used to specify a bootable partition for a non-Linux operating system.
Used to specify a path to another bootloader or +1 if the bootloader is located in the first sector of
chainloader
the partition specified by the rootnoverify directive.

The password that is specified can be specified as clear text, like in the example /boot/grub/grub.conf file
shown earlier in this section:

password notencrypted

For an encrypted the password, use the --md5 option for the password directive:

password --md5 $1$D20Ia1$iN6djlheGF0NQoyerYgpp/.

To generate the encrypted password, use the grub-md5-crypt command or execute the grub command and then at
the grub prompt, type the md5crypt command:

sysadmin@localhost:~$ grub-md5-crypt
Password:
Retype password:
$1$eRsrb1$v1p5us79Harrku4vbJgKF0
17.5 Interacting with GRUB Legacy
When a system first starts up with GRUB Legacy installed as the bootloader, it may only display the default title
and the timeout time counting down to zero as the hiddenmenu directive may be specified in the
/boot/grub/grub.conf file. If the hiddenmenu directive is not specified, then GRUB Legacy will display all the
titles and the timeout time counting down to zero. If no interaction occurs before the countdown reaches zero, then
GRUB Legacy will attempt to boot the default title.

⁠ If any key except Enter is pressed, then the time stops counting down, and a title must be selected manually to
attempt a boot. The Up ↑ and Down ↓ arrow keys can be used to select one of the available titles. After selecting a
title, the user can press Enter to attempt to boot the selection.

If the global password directive has been used, then the P key must be pressed, followed by the password to
unlock the ability to use GRUB Legacy 's append, edit, and the GRUB command prompt features. Notice the
message at the bottom of the following graphic:

If a title password is in use, then GRUB Legacy will prompt for this password when a title is selected from the
GRUB Legacy menu.

If the global password directive has not been used or GRUB Legacy has been unlocked by providing the
password, then the screen should look similar to the following graphic:
Notice the following options available at the bottom of the previous graphic:

 If the A key is pressed, then GRUB Legacy will allow additional kernel parameters to be appended. This is
commonly used to specify the runlevel number to take the system to, instead of the default runlevel.
 If the E key is pressed, then any of the directives that are included within the selected title can be edited; the
root, kernel, or initrd values can be changed in order to be able to boot the system in a different
manner. The changes that are made at the GRUB Legacy menu are not permanently edited into the
/boot/grub/grub.conf file.
 If the C key is pressed at the GRUB Legacy menu, then the GRUB command prompt will be provided. At
this command prompt, any GRUB Legacy directives can be added, including specifying custom root,
kernel, and initrd directives. If entered correctly, followed by the boot directive, then the system will
boot correctly.

One of the most common tasks performed interactively with GRUB Legacy is to boot to a different runlevel. A
runlevel is a status that defines how many services are currently running on a system. There are multiple runlevels,
and they are based on what services will be active when the system is booted. or this next example, we will
introduce the single user runlevel. The single user runlevel is when a system has limited services running and is
used only to perform administrative tasks.

Note

Runlevels will be covered in greater detail in a later chapter.

In the event that there is a serious system problem, the single user runlevel can be very useful. In this runlevel, only
the root user has access to the system, and most system daemons are not running.
Additionally, when the system boots to the single user runlevel, the root password is not required to log in because
the system automatically logs in as the root user. This makes the single user runlevel useful for things like
recovering or replacing a forgotten root password.

To go to the single user runlevel, use the Up and Down arrow key to select the correct title from the GRUB Legacy
menu. Then, use the A key to add to the kernel line. The screen should now look something like this:

[ Minimal BASH-like line editing is supported. For the first word, TAB
lists possible command completions. Anywhere else TAB lists the possible
completions of a device/filename. ESC at any time cancels. ENTER
at any time accepts your changes.]

<c KEYTABLE=us rd_NO_DM rhgb quiet_

The kernel line is quite long, so initially only the very end of the line can be seen. The Left ← and Right → arrow
keys can be used to move the cursor. Use the Left arrow key to see the rest of the line, then add the single
parameter to the end:

[ Minimal BASH-like line editing is supported. For the first word, TAB
lists possible command completions. Anywhere else TAB lists the possible
completions of a device/filename. ESC at any time cancels. ENTER
at any time accepts your changes.]

<c KEYTABLE=us rd_NO_DM rhgb quiet single_

After single has been typed, press the Enter key. The system will boot, and the console will appear with the
system in the single user runlevel.

When finished working at the single user runlevel, Ctrl+D can be used to boot normally.

17.6 GRUB 2
The new GRUB, GRand Unified Bootloader 2, offers several advantages:

 Dynamically loaded modules


 Non-ASCII character support
 Ability to boot from partitions inside of Logical Volume Management (LVM) or RAID devices
 Ability to work with architectures that don't have a PC BIOS
17.7 GRUB 2 Boot Steps
When a GRUB 2 system is powered on, the first stage loader boot.img is either read from the first 440 bytes of
the Master Boot Record (MBR), or alternatively read from the Partition Boot Record (PBR), (like a Master Boot
Record for a partition).

From the first stage loader, the location of the second stage loader is found. The second stage loader
diskboot.img is used as the first sector of the third stage loader, and this points directly to the third stage.

The third stage loader core.img uncompresses itself, accesses its own GRUB 2 kernel and filesystem drivers and
attempts to access the actual root filesystem’s /boot/grub directory.

If it can access the /boot/grub directory on disk, it then loads the appropriate fourth stage module normal.mod
which then reads the /boot/grub/grub.cfg file and presents either a GUI for GRUB 2 or the CLI menu so the
user can choose an image to boot.

17.8 GRUB 2 Configuration


Although both the Fedora and Ubuntu distributions are now using GRUB 2, they each use a different location for
the main configuration file. Fedora uses the /boot/grub2/grub.cfg file instead of the /boot/grub/grub.cfg file
that is used by Ubuntu-based distributions.

While it is possible to edit the main configuration file, any changes made to it will be lost upon updating the kernel
or if an administrator executes the update-grub command (for Ubuntu-based systems) or the grub2-mkconfig
command (for Fedora-based systems). This is because the GRUB 2 configuration file is designed to be
automatically regenerated any time a kernel file is added or removed from the /boot directory.

While GRUB Legacy expects the main configuration file will be edited, GRUB 2 expects any customizations to
occur in the /etc/grub.d directory or the /etc/default/grub file.

With GRUB Legacy, the files for GRUB were kept in the /boot/grub directory. Now, GRUB 2 uses several
locations for its files:

File Location Details


 Contains many module files.
 Contains the grub.cfg file, a configuration file which should not be edited
/boot/grub2 manually.
 Contains the grubenv file, a configuration file which should not be edited manually

 Contains the entries for creating a default boot entry; typically where customization
/etc/default/grub by administrators will be performed.

 Contains scripts that are run by GRUB 2.


 Scripts can be customized or added to this directory.
/etc/grub.d  Contains the following executable scripts by default:

/etc/grub.d/00_header
File Location Details
/etc/grub.d/10_linux

/etc/grub.d/20_linux_xen

/etc/grub.d/30_os-prober

/etc/grub.d/40_custom

/etc/grub.d/41_custom

/etc/grub.d/90_persistent
 Stores a couple of library files.
/usr/lib/grub

/sbin/grub2-  Command used to regenerate the /boot/grub2/grub.cfg file.


mkconfig

This following demonstrates a typical /etc/default/grub file (this one was copied from a Fedora 16 system):

GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_SAVEDEFAULT=true
# GRUB_TERMINAL="serial console"
# GRUB_SERIAL_COMMAND="serial --unit=0 --speed=9600"
GRUB_CMDLINE_LINUX="quiet rhgb"
GRUB_DISABLE_RECOVERY="true"

The new GRUB 2 allows the user to choose a new default menu item. By adding the following settings in the
/etc/default/grub file and regenerating the configuration file, whatever title the user chooses from the menu
becomes “saved” and will be the default the next time the menu is displayed:

GRUB_DEFAULT=saved
GRUB_SAVEDEFAULT=true

After modifying the /etc/default/grub file, execute either the update-grub command (for Ubuntu-based
systems) or the grub2-mkconfig command (for Fedora-based systems) to update the actual configuration file used
by GRUB 2 at boot time.

To manually specify which kernel image to boot, use these settings in the /etc/default/grub file:

GRUB_DEFAULT=0
GRUB_SAVEDEFAULT=false

⁠These settings mean use the first menu entry found in the configuration file as the default to boot. The menu entries
are created by GRUB 2 by searching for kernel images in the /boot directory. These menu entries are numbered
starting at zero for the most recent version, one for the next most recent version, and so forth.

The GRUB_DEFAULT= setting establishes the number of the menu entry to use by default, and
GRUB_SAVEDEFAULT=false means don’t save a new default when the user chooses from the menu.

The /etc/default/grub file can also be modified for the administrator automatically by executing the grub-set-
default command with the menu entry to set as default. For example, to make the second menu entry the default
menu entry, an administrator would execute:
root@localhost:~# grub-set-default 1

The GRUB_TIMEOUT value found in the /etc/default/grub file establishes how many seconds to wait before the
system is automatically booted to the default menu entry. If the user presses any key except the Enter key, then the
timeout is aborted, and the user can select a menu entry manually.

If GRUB 2 needs to be installed or reinstalled, then an administrator would execute:

root@localhost:~# /sbin/grub2-install /dev/sda

After installing GRUB 2, the configuration file needs to be generated for the first time. In a Fedora-based
distribution, an administrator would execute:

[root@localhost]# grub2-mkconfig -o /boot/grub2/grub.cfg

On an Ubuntu-based distribution, an administrator would execute:

root@localhost:~# update-grub

Consider This

Additional documentation of GRUB 2 configuration can be found at gnu.org, the GNU website.
Key Terms

grub-install
Utility to install GRUB on the hard drive.
Section 17.6
grub-mkconfig
Utility used to generate a configuration file for GRUB.
Section 17.8
grub.cfg
GRUB configuration file.
Section 17.8
grub.conf
GRUB configuration file on Red Hat Linux.
Section 17.6
menu.lst
configuration file for GRUB legacy.
Section 17.4
LAB 17

17.0 Introduction
In order to provide the functionality required for this lab, the companion VM may require a minute or two to load.

The boot process starts with the bootloader, the program that loads the kernel into memory and executes
instructions to boot the system. Typically, administrators do not find it necessary to make many changes to the
bootloader, but you should know how to modify some of the key GRUB configurations, as well as know how to
interact with the bootloader interactively when the system is booting.

17.1 Step 1
Please use the Ubuntu image to complete the following steps. Select the Ubuntu PC by clicking on the tab in the
window on the right side of the screen.

Log in to the system using the root account. When prompted, provide the root password:

root
netlab123
Ubuntu 18.04.2 LTS ubuntu tty1
ubuntu login: root
Password:
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-45-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage

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.

root@ubuntu:~#
17.2 Step 2
This system supports GRUB2. View the first 10 lines of the /boot/grub/grub.cfg file by executing the following
command:

head /boot/grub/grub.cfg
root@ubuntu:~# head /boot/grub/grub.cfg
#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by grub-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#
### BEGIN /etc/grub/d/00_header ###
if [ -s $prefix/grubenv ]; then
set have_grubenv=true

17.3 Step 3
Notice that this file is not designed to be edited directly. Instead, you modify settings in the /etc/default/grub
file. To edit this file, first launch the vi editor:

vi /etc/default/grub
root@ubuntu:~# vi /etc/default/grub
17.4 Step 4
Next, we will change the value of GRUB_TIMEOUT_STYLE to menu and GRUB_TIMEOUT to 30. Execute the following
vi commands ([ESC] means press the Escape key and the 0 character is zero):

7G
$
xxxxxx
a
menu
[ESC]
[Down Arrow Key]
x
a
30
[ESC]
:wq
[Enter]
17.5 Step 5
Next, execute the following command to verify your changes. They should look like the following graphic:

root@ubuntu:~# head /etc/default/grub


# If you change this file, run 'update-grub' afterwards to update
# /boot/grub/grub.cfg.
# For full documentation of the options in this file, see:
# info -f grub -n 'Simple configuration'

GRUB_DEFAULT=0
GRUB_TIMEOUT_STYLE=menu
GRUB_TIMEOUT=30
GRUB_DISTRIBUTOR='lsb_release -i -s 2> /dev/null || echo Debian'
GRUB_CMDLINE_LINUX_DEFAULT=“quiet”

17.6 Step 6
Notice that the first line of the /etc/default/grub file indicates that the update-grub command must be
executed after modifying this file. Execute that command, then reboot the system and watch the screen for the
countdown:

update-grub
root@ubuntu:~# update-grub
Sourcing file „/etc/default/grub‟
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-4.15.0-45-generic
Found initrd image: /boot/initrd.img-4.15.0-45-generic
done
root@ubuntu:~# reboot
17.7 Step 7
When the system boots, you should see a countdown at the bottom of the screen. Before it reaches 0, press the
Escape key:

[ESC]

17.8 Step 8
After pressing the Escape key, you will be presented with the following menu:
17.9 Step 9
Press the Down Arrow key once and then press the Enter key to select Advanced options for Ubuntu. This
will display another menu, which includes the ability to boot to a recovery mode:

Press Down Arrow


[Enter]

17.10 Step 10
Press the Down Arrow key once so the "...(recovery mode)" option is selected and press the e key to enter the
edit mode:

Press Down Arrow


e
17.11 Step 11
This option will boot the system to a recovery runlevel where an administrator can fix system problems:

17.12 Step 12
Press the Escape key twice to return to the primary menu:

[ESC]
[ESC]

17.13 Step 13
Press the Enter key to boot the system:

[Enter]
17.14 Step 14
Please use the CentOS image to complete the remaining steps. Select the CentOS PC by clicking on the tab in the
window on the right side of the screen.

Note

This lab requires an older version of CentOS in order to practice using Grub Legacy, which is unavailable on
modern systems.

Log in to the system using the root account. When prompted, provide the root password:

root
netlab123
CentOS release 6.10 (Final)
Kernel 2.6.32-754.el6.x86_64 on an x86_64

centos login: root


Password:
Last login: Wed Aug 20 08:17:32 on tty1
[root@centos ~]#

17.15 Step 15
This system supports traditional GRUB. View the /boot/grub/grub.conf file by executing the following
command:

cat /boot/grub/grub.conf
[root@centos ~]# cat /boot/grub/grub.conf

The timeout value determines how long the user has before the system starts booting to the default OS. In this
example, there is only one OS, defined by the title directive. The hiddenmenu directive indicates that the GRUB
menu is not displayed by default during the countdown provided by the GRUB before booting the system.

17.16 Step 16
Modify the /boot/grub/grub.conf file by executing the following command:

vi /boot/grub/grub.conf
[root@centos ~]# vi /boot/grub/grub.conf
17.17 Step 17
Next, change the timeout to 60 and "comment out" the hiddenmenu directive by executing the following vi
commands ([ESC] means press the Escape key):

11G
$
x
a
60
[ESC]
Enter
Press Down Arrow
I
#
[ESC]
:wq

17.18 Step 18
Verify your changes by viewing the /boot/grub/grub.conf file by executing the following command:

cat /boot/grub/grub.conf
In traditional GRUB, changes to the configuration file do not require running any commands after editing the file

17.19 Step 19
Reboot the system and watch the screen during the boot process for the countdown to begin:

[root@centos ~]# reboot

17.20 Step 20
When the system boots, you should see the GRUB menu countdown at the bottom of the screen. Before it reaches
0, press the Escape key:

[ESC]
17.21 Step 21
After pressing the Escape key, you will be presented with the following menu:
17.22 Step 22
Type the letter e to edit the current title:

You will be provided with the following screen:

The line that you would most likely edit is the kernel line. By adding (or removing) arguments on this line, you
can affect how the system will boot. Keep in mind that any changes made here are not permanent. To make them
permanent, you must edit the /boot/grub/grub.conf file after booting the system.
17.23 Step 23
Press the Down Arrow key once and then press the letter e to edit the kernel line:

Press Down Arrow


e

17.24 Step 24
You will be placed in edit mode at the end of the kernel line:

[ Minimal BASH-like line editing is supported. For the first word, TAB
lists possible command completions. Anywhere else TAB lists the possible
completions of a device/filename. ESC at any time cancels. ENTER
at any time accepts your changes.]

<=VolGroup/lv_root KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet_

The rhgb argument stands for Red Hat Graphical Boot. Instead of displaying text messages during boot, a
graphical progress bar is displayed. While more user-friendly, this doesn't help the administrator troubleshoot boot
problems.

The quiet argument suppresses many of the text messages that are displayed if the rhgb argument isn't used.
Again, this may be more user-friendly, but an administrator should remove this setting when troubleshooting boot
problems.

17.25 Step 25
Press the Backspace key 10 times to remove the rhgb and quiet settings. Then, type single:

Press Backspace Key 10x


single

By adding single to the end of the kernel line, the system will be booted to the single user runlevel.

17.26 Step 26
Your screen should look like the following:

[ Minimal BASH-like line editing is supported. For the first word, TAB
lists possible command completions. Anywhere else TAB lists the possible
completions of a device/filename. ESC at any time cancels. ENTER
at any time accepts your changes.]

<=VolGroup/lv_root KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM sin


17.27 Step 27
Press the Enter key to accept the changes:

Enter

17.28 Step 28
You will be presented the edit screen again:
17.29 Step 29
Press the b key to boot the system. Notice how the boot messages are displayed (your system may appear different
from what you see in the following graphic).

17.30 Step 30
Notice that when the system finishes booting, you are automatically logged in as the root user:

Remounting root filesystem in read-write mode: [ OK ]


Mounting local filesystems: [ OK ]
Enabling local filesystem quotas: [ OK ]
Enabling /etc/fstab swaps: [ OK ]
[root@centos /]#
17.31 Step 31
Type the runlevel command to verify that you are at runlevel S (or single user):

[root@centos /]# runlevel


N S

At the single user runlevel, very few processes are running, and only the administrator can access the system. The
purpose of this runlevel is to troubleshoot critical system problems.

17.32 Step 32
Let’s pretend you have fixed whatever problem prompted you to go to the single user runlevel. To boot the system
to the default runlevel, Press Ctrl+D (hold down the Control key and press the letter d):

Ctrl+d
Chapter 18: Runlevels

18.1 Introduction
Linux uses the concept of different runlevels to define what services or processes will be running. Although the
Linux kernel can recognize runlevel values from 0 to 9, typically only runlevels 0 through 6 are used.
Traditionally, init and Upstart used these runlevels to define which services were started according to the needs
of a particular runlevel. Being able to define a specific runlevel is essential for troubleshooting systems when
software components, such as hardware drivers, are causing the kernel to crash.

Recently, these programs have been replaced on many distributions by systemd, a service and system manager
originally designed by Red Hat. It does something similar to runlevels called targets, which are shown in the
following table with their runlevel equivalent.

The Linux Standards Base 4.1 defines the purpose of each runlevel like this:


Runlevel Purpose systemd Target
0 Halt or shut off the system poweroff.target
1 Single-user mode for administrative tasks rescue.target
2 Multi-user mode without configured network interfaces or network services multi-user.target
3 Normal startup of the system multi-user.target
4 User-definable multi-user.target
5 Start the system normally with a graphical display manager graphical.target
6 Restart the system reboot.target

While these runlevels are considered "standard", not all distributions use them for the same purposes. Check the
documentation that comes with your distribution to confirm the purpose of each runlevel. In fact, for systems that
no longer use the traditional init process, the use of runlevels may only be provided for maintaining compatibility
with processes that may expect them.
18.2 Default Runlevel
Systems using traditional init can specify the default runlevel by modifying the /etc/inittab file entry that
looks like the following:

id:5:initdefault:

In this example, the default runlevel indicated is for the system to go to runlevel 5, which is typical for a desktop or
laptop system that will be running a GUI, and will, most likely, be used by an end user. For most Linux systems,
runlevel 5 provides the highest level of functionality, including providing a GUI interface.

Servers typically don't offer a GUI interface, so the initdefault entry might look like:

id:3:initdefault:

As previously discussed, the default runlevel can be overridden at boot time by interacting with the bootloader. In
the case of GRUB Legacy, either append to the kernel line or use the editing feature to add a runlevel number. For
example, adding 5 would take the system to runlevel 5 and the word single (or the uppercase or lowercase letter
s, as well as the numeral 1) would take the system to the single user runlevel.

Note

Bootloaders are covered in greater detail previously in the course.

If the system is using Upstart instead of the traditional init process, then the default runlevel may also be set in
the /etc/inittab file, as is the case with distributions derived from Red Hat Enterprise Linux 6. On the other
hand, distributions like Ubuntu (the distribution that developed Upstart) can be changed by setting the
DEFAULT_RUNLEVEL environmental variable in the /etc/init/rc-sysinit.conf file.

systemd doesn't natively use runlevels, but it has something similar called targets. For example, the
graphical.target is similar to the standard runlevel 5, where the GUI is running; the multi-user.target is
similar to the standard runlevel 3, where the system is normally running without a GUI.

To set a default target, create a symbolic link from the target definition found in the /lib/systemd directory to the
/etc/systemd/system/default.target file. This file is a symbolic link that controls where the system first
boots into.

Note

Recall that to create a soft link file, use the ln command with the -s option. The first argument is the original file
name, and the second argument is the name of the link to be created:

ln -s target link_name

Links are covered in greater detail earlier in the course.

To change how the system boots, remove the former default target and then create a new symbolic link as shown
below:

Note

The su command requires the root password netlab123 in our virtual environment.
sysadmin@localhost:~$ su -
Password:
root@localhost:~# rm -f /etc/systemd/system/default.target
root@localhost:~# ln -sf /lib/systemd/system/graphical.target
/etc/systemd/system/default.target

The previous example sets the default target to graphical.target, so the system would come up to a state like
runlevel 5.

18.3 Viewing Current Runlevel


Despite having a default runlevel, a system may be at a different runlevel either because it was overridden at boot
time or it may have been changed after the system booted.

One of the commands that displays the current runlevel is the runlevel command, which shows the previous
runlevel first, followed by the current runlevel. If no previous runlevel was achieved, then it will show N for the
previous runlevel. This means the system was booted into the current runlevel directly and has not switched.

Note

The following examples represent a system that is different from the virtual machine in this module. The examples
may not match the output in our virtual environment.

The following example demonstrates executing the runlevel command when the system has just booted to
runlevel 5:

root@ubuntu:~# runlevel
N 2

The who -r command also displays the current system runlevel. One benefit of this technique is that it will display
the date and time that the current runlevel was reached:

root@ubuntu:~# who -r
run-level 2 2019-05-29 14:25

Although systemd doesn't actually use runlevels, it transparently translates its current target as a runlevel for
compatibility with the runlevel and who -r commands. If a system has reached the multi-user.target, then
that will be translated to runlevel 3; if a system has reached the graphical.target, then that is translated to
runlevel 5.
18.4 Changing Runlevels and Targets
Both the traditional SysVinit and Upstart support passing runlevels to the kernel as parameters from the bootloader
to override the default runlevel.

To specify a different runlevel at boot time on a system that uses systemd, append to the kernel parameters an
option with the following syntax where DESIRED.TARGET is one of the systemd targets:

systemd.unit=DESIRED.TARGET

The root user can also change runlevels while the operating system is running by using several commands,
including the init and telinit commands, which allow the desired runlevel to be specified. There are also
several commands that don't directly specify the runlevel number but are designed to make the system change
runlevels.

The init and telinit Commands

To directly specify the runlevel to go to, either use init or telinit. The telinit command in some distributions
has a -t option, which allows for a time delay in seconds to be specified; otherwise, the init and telinit
commands are functionally identical. In fact, on some systems, the telinit command may be simply a link to the
init command.

To use these commands, simply specify the desired runlevel as an argument. For example, to reboot the system,
use either the init 6 command or the telinit 6 command. Or, to go to runlevel 5, use either init 5 or telinit
5.

Important

Changing runlevels will affect the applications or services you are running and can cause data loss or connection
interruption for users accessing the system for those services.

With the systemd replacement for init, the init command can still be used to modify the runlevel; systemd will
translate the desired runlevel to a target. For example, if init 5 is executed, then systemd would attempt to change
to the graphical.target state.

To have systemd natively switch to a target state, with root privileges execute:

systemctl isolate DESIRED.TARGET

For example, to take the system to runlevel 1 execute the systemctl isolate rescue.target command.
Likewise, to natively go to runlevel 5, execute the systemctl isolate graphical.target command.

The halt, poweroff, reboot, and shutdown Commands

To bring the system down to runlevel zero, execute the halt, poweroff, or shutdown command.

While the halt and poweroff commands will begin shutting down the system immediately, the shutdown
command requires a time argument to indicate when the shutdown should begin. Formats of this time argument can
be the word now, a countdown time in the HH:MM format, or the number of minutes to delay in the +M format. A
message that will appear in the terminals of all users can also be specified with the shutdown command. For
example:
Note

The example below may not match the output in our virtual environment.

root@localhost:~# shutdown now "System going down for repairs"

The message System going down for repairs would be displayed in the terminal window of each user who is
currently logged in.

Oddly enough, if an option is not specified, then the shutdown command will actually take the system down to
runlevel 1. The shutdown command used with the -r option is similar to using the reboot command and will
cause the system to go to runlevel 6. The shutdown command used with the -h option is similar to using the halt
command and will cause the system to go to runlevel 0.

Consider This

It isn't always necessary to go to runlevel 5 (in most distributions) in order to be able to use the Graphic User
Interface (GUI). The GUI that is usually provided by software known as X Windows can also be started by the
startx command.

After using the graphical environment, use the graphical logout to end the X Windows session.

Using the startx command doesn't require root privileges the way that the init 5 or systemctl isolate
graphical.target commands do.
18.5 The wall Command
Sometimes the system administrator needs to send messages regarding a pending event to all users. While it is
possible to send a message using the shutdown command:

root@localhost:~# shutdown now "System going down for repairs"

There are instances when the notification may not require the imminent shutdown of the system. This is what the
wall command is used for. The wall command can be used to display a message or the contents of a file to all
users on the system. For example, the following message is being piped to the wall command from the echo
command:

root@localhost:~# exit
logout
sysadmin@localhost:~$ echo -e "The server will be offline on Saturday
from\n6:00PM to 12:00PM for scheduled maintenance" | wall
Broadcast message from sysadmin@localhost (console) (Wed May 29 22:13:59
2019):

The server will be offline on Saturday from


6:00PM to 12:00PM for scheduled maintenance

The wall command accepts standard input or the name of a file. To display a file, the wall command either
requires the user to have root privileges or the contents to be piped in from another command, such as the cat
command. Without either, the wall command will display an error message:

Note

The sudo command requires the root password netlab123 in our virtual environment.

sysadmin@localhost:~$ cd Documents
sysadmin@localhost:~/Documents$ wall letters.txt
wall: will not read letters.txt - use stdin.
sysadmin@localhost:~/Documents$ sudo wall letters.txt
[sudo] password for sysadmin:

Broadcast message from sysadmin@localhost (console) (Wed May 29 22:15:23


2019):

a
b
c
d
e

sysadmin@localhost:~/Documents$ cat letters.txt | wall

Broadcast message from sysadmin@localhost (console) (Wed May 29 22:17:44


2019):

a
b
c
d
e

The -n option can be used by the wall command to suppress the leading banner:
sysadmin@localhost:~/Documents$ sudo cat letters.txt | wall -n
wall: --nobanner is available only for root

Broadcast message from sysadmin@localhost (console) (Wed May 29 22:18:24


2019):

a
b
c
d
e

18.6 Managing System Services


As the administrator of a system, it is possible to control which services will be provided by the various daemons
(processes that run in the background of the system). If you want to test services out or have them temporarily
enabled or disabled, then you could manually manage them.

Typically, administrators will want to automate the management of services, so when the system is taken to a
specific runlevel or target state, they will know what services should automatically be available.

If a system is using the traditional init process to manage system services, then the scripts in the
/etc/rc.d/init.d directory are used to manage the state of those system services. For convenience, this directory
will usually have a symbolic link from the /etc/init.d file. The scripts in this directory are often referred to as
init scripts.

To manually manage the state of a service, such as a web server, use the appropriate script in the
/etc/rc.d/init.d directory to start, stop, or otherwise change the state of the web server. To manage a service
with these scripts, run the script with an argument which specifies what the script is supposed to do.

For example, on a Red Hat Enterprise Linux distribution, the script to manage the web server has a path name of
/etc/rc.d/init.d/httpd. So, to manually start the web server, you would execute the following command as the
root user:

Note

The following examples represent a system that is different from the virtual machine in this module. The examples
may not match the output in our virtual environment.

[root@localhost ~]# /etc/rc.d/init.d/httpd start


Starting httpd:

To manually stop a running web server, execute:

[root@localhost ~]# /etc/rc.d/init.d/httpd stop


Stopping httpd:

Instead of having to type the full path name to the script, many systems provide a service script that allows the
init script to be executed without having to type the full path to the script; instead, simply provide the init
program name and the function the script should do as arguments. For example, to start and stop the web server,
use:

[root@localhost ~]# service httpd start


[root@localhost ~]# service httpd stop

It is also possible to stop and start the web server daemon by typing:

[root@localhost ~]# service httpd restart

Consider This

While the service command may seem easier than typing the full path name, this isn't always the case. Command
name completion using the Tab key can often make typing the full path name quicker. For example,
/etc/init.d/httpd stop could be typed quickly by using the Tab key.

For the httpd script, this may be considered a wasted effort when compared to simply using the service
command. But consider a path like /etc/init.d/blk-availability; if this is used with the service command,
you need to type completely (and remember the exact name) blk-availability.

Using the full path may be easier because the shell can auto-complete most of the name (if you remember what it
starts with).

Different scripts have different capabilities or functions that they can perform. To discover what a script can do,
execute the script without any argument. For example:

[root@localhost ~]# /etc/init.d/httpd


Usage: httpd {start|stop|restart|conderestart|try-restart|force-reload|reload|status|fullst
atus|graceful|help|configtest}

The following table explains the purpose of these functions of the httpd script, which many other scripts can also
implement:

Argument Function
start If the service is not running, then attempt to start it.
stop If the service is running, then attempt to stop it.
restart
Stop and then start the service over. If a major configuration change is made to a service, it may have
to be restarted to make the change effective.
condrestart Restart the service on the condition that it is currently running.
try-restart Same as condrestart.
Read and load the configuration for the service. Reloading the configuration file of a service is
reload normally a less disruptive way to make configuration changes to a service effective, but may not be
successful for major changes.
Show whether the service is stopped or the process id (PID) if the service is running. Note: It is also
status
possible to use the service --status-all command to see the status of all daemons.
fullstatus For the Apache web server, displays the URL /server-status.

graceful
For the Apache web server, it gracefully restarts the server. If the server is not running, then it is
started. Unlike a normal restart, open connections are not aborted.
help Displays the usage of the script.
configtest
Checks the configuration files for correctness. For some services, if the configuration file is
modified, then this can be used to verify that the changes have no syntax errors.
18.7 Runlevel Directories
Even though it is possible to start up services manually, most services are automatically started up by whatever
init process the system uses.

With the traditional init process, specific directories are used to manage which services will be automatically
started or stopped at different runlevels. In many Linux distributions, these directories all exist within the /etc
directory and have the following path names:

 rc0.d
 rc1.d
 rc2.d
 rc3.d
 rc4.d
 rc5.d
 rc6.d

The number in the directory name represents the runlevel that it manages; for example, rc0.d is for runlevel 0 and
rc1.d is for runlevel 1. To demonstrate, the directories that are used to manage which services will be
automatically started or stopped at different runlevels in our VM can be found in the /etc directory. To display
these directories, execute the following command:

sysadmin@localhost:~$ cd /etc
sysadmin@localhost:/etc$ ls -d rc*
rc0.d rc1.d rc2.d rc3.d rc4.d rc5.d rc6.d rcS.d

To have a service started in a runlevel, a symbolic link to the init script in the /etc/rc.d/init.d directory can
be created in the appropriate runlevel directory. This link name must start with the letter S, followed by a number
from one to ninety-nine, and the name of the init script that it is linked to.

sysadmin@localhost:/etc$ cd rc2.d
sysadmin@localhost:/etc/rc2.d$ ls
S01bind9 S01cron S01irqbalance S01rsync S01ssh
S01console-setup.sh S01dbus S01plymouth S01rsyslog S01uuidd
sysadmin@localhost:/etc/rc2.d$ cd

For example, when the web server is set to start on a Linux system in runlevel 5, there is a symbolic link in the
/etc/rc.d/rc5.d directory named S85httpd that is linked to the /etc/rc.d/init.d/httpd script:

Note

The following examples represent a system that is different from the virtual machine in this module. The examples
may not match the output in our virtual environment.

[root@localhost ~]# ls -l /etc/rc.d/rc5.d/S85httpd


lrwxrwxrwx 1 root root 19 Jun 27 16:53 /etc/rc.d/rc5.d/S85httpd ->
../init.d/httpd

To manually create this link, you would execute the following command:

[root@localhost ~]# ln -s /etc/rc.d/init.d/httpd /etc/rc.d/rc5.d/S85httpd

Just as the S file links in a runlevel directory will indicate that a service is supposed to be started, the K file links in
a runlevel directory will indicate that a service is supposed to be stopped (killed).
Using the web server as an example again; to have the web server stopped at runlevel 5, create a symbolic link in
the /etc/rc.d/rc5.d directory that would start with the letter K, followed by a number from one to ninety-nine,
and the name of the init script that it is linked to:

[root@localhost ~]# ls -l /etc/rc.d/rc5.d/K15httpd


lrwxrwxrwx 1 root root 19 Jun 27 16:53 /etc/rc.d/rc5.d/K15httpd -> ../init.d/httpd

If the link was manually created, the start link would have to be removed before the stop link could be created:

[root@localhost ~]# rm /etc/rc.d/rc5.d/S85httpd


[root@localhost ~]# ln -s /etc/rc.d/init.d/httpd /etc/rc.d/rc5.d/K15httpd

Consider This

The K scripts sometimes confuse beginning administrators. They often wonder, "Why should I stop a service when
the system is brought to a runlevel?" This confusion typically stems from the thought that runlevels are only a
"boot thing", but as previously mentioned, an administrator can change the system from one runlevel to another.

Imagine the httpd service as available at runlevel 5, but not at runlevel 3. When the system is taken from runlevel
5 to runlevel 3, then the httpd service should be stopped. Hence the K scripts.

But what if the service isn't running when the K script is called? In that case, the K script is written in such a way to
realize this and do nothing.

The reason that both start and stop links have a number after the letter S or K is to ensure that services are started or
stopped in the correct sequence. The scripts are started (or stopped) in order, so K15httpd would be executed
before K35vncserver.

If services are not started or stopped in the correct order, then they may not work properly because some services
depend on other services to work. For example, in order for a web server to work the way it should, the network
service must already be running. Giving the network service a lower starting number than the web server means
init will start the network service before it tries to start the web service.

So, what number is supposed to be provided to a specific script for S and K? Look at the script itself for the line that
contains chkconfig:

[root@localhost ~]# grep chkconfig /etc/init.d/httpd


# chkconfig: - 85 15

The second to last number 85 of the chkconfig line is the S number to place on this script, the last number 15 is
the K number.

In reality, the days of having to manage symbolic links manually in the different runlevel directories have long
been gone. Today there are numerous command line and graphical tools for managing these symbolic links.
18.8 The chkconfig Command
The chkconfig command can be used to view what services will be started for different runlevels. This command
can also be used to turn on or turn off a service for specific runlevels. On Linux distributions that are not Red Hat-
derived, this tool may not be available.

To view all the services that are set to start or stop automatically, the administrator can execute the chkconfig --
list command and the output would look something like the following (although there would be many more lines
of output):

Note

The following examples represent a system that is different from the virtual machine in this module. The examples
may not match the output in our virtual environment.

[root@localhost ~]# chkconfig --list


auditd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
crond 0:off 1:off 2:on 3:on 4:on 5:on 6:off
httpd 0:off 1:off 2:off 3:off 4:off 5:off 6:off
iptables 0:off 1:off 2:on 3:on 4:on 5:on 6:off
netconsole 0:off 1:off 2:off 3:off 4:off 5:off 6:off
netfs 0:off 1:off 2:off 3:on 4:on 5:on 6:off
network 0:off 1:off 2:on 3:on 4:on 5:on 6:off
quota_nld 0:off 1:off 2:off 3:off 4:off 5:off 6:off
rdisc 0:off 1:off 2:off 3:off 4:off 5:off 6:off
restorecond 0:off 1:off 2:off 3:off 4:off 5:off 6:off
rsyslog 0:off 1:off 2:on 3:on 4:on 5:on 6:off
saslauthd 0:off 1:off 2:off 3:off 4:off 5:off 6:off
sendmail 0:off 1:off 2:on 3:on 4:on 5:on 6:off
sshd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
udev-post 0:off 1:on 2:on 3:on 4:on 5:on 6:off

The output for each line shows the name of the script file found in the /etc/rc.d/init.d directory, followed by
each runlevel number, a colon, and whether the service is set to be on or off. For example, based on the output
from the previous graphic, the auditd service is started at runlevels 2, 3, 4, and 5.

To view a single service's settings, use the chkconfig --list SCRIPT command where SCRIPT is the name of a
script file found in the /etc/rc.d/init.d directory. For example, to view the web server script, execute:

[root@localhost ~]# chkconfig --list httpd


httpd 0:off 1:off 2:off 3:off 4:off 5:off 6:off

To enable the service to start for most runlevels, use the chkconfig SERVICE on command, where the SERVICE is
the name of a script file found in the /etc/rc.d/init.d directory. Thus, to enable the web server to start at most
runlevels, execute the chkconfig httpd on command:

[root@localhost ~]# chkconfig httpd on


[root@localhost ~]# chkconfig --list httpd
httpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off

For most services, if the chkconfig command is used to enable the service, it will be started automatically in
runlevels 2 through 5 and automatically stopped in runlevels 0, 1, and 6. This may vary slightly based on the
contents of the script itself.

In the /etc/rc.d/init.d/httpd script, there is a line that contains the following:


[root@localhost ~]# chkconfig: - 85 15

The - indicates that the service is not enabled in any runlevels automatically when it is first added to chkconfig
management. In other words, this service is not set to start automatically unless an administrator uses the
chkconfig httpd on command.

Some scripts have a different chkconfig value; for example, the etc/rc.d/init.d/atd script has the following
line:

[root@localhost ~]# chkconfig: 345 95 5

The 345 means that atd defaults to being enabled in runlevels 3, 4, and 5.

To turn on or off services for a non-default level, the --level option can be used with the chkconfig command.
For example, the following two commands would ensure that the atd service was available in runlevels 2 and 4,
but not available in runlevels 3 and 5:

[root@localhost ~]# chkconfig --level 24 atd on


[root@localhost ~]# chkconfig --level 35 atd off

Two other chkconfig options should also be mentioned, although they are rarely used directly. The chkconfig
options --add and --del can be used manually, but normally they are automatically used when an administrator
either installs a new service software package or removes a service software package.

If an administrator were to create an init script named serviced and store it in the /etc/rc.d/init.d directory,
the chkconfig --add SERVICE command would need to be executed first before using either the chkconfig
SERVICE on or chkconfig SERVICE off command. A command similar to this is executed when a new software
package containing a service is installed.

The chkconfig --del SERVICE command would remove any links in the runlevel directories and services would
not be started or stopped automatically at any runlevel. A command similar to this is executed when an existing
software package for a service is removed.
18.9 The /etc/init Directory
For users of Debian-derived Linux distributions, the /etc/init directory is used to store Upstart scripts. These
scripts will start or stop different services based upon different events, including going to a specific runlevel.

For Debian and its derivatives (like Ubuntu), know that the runlevels that are used vary slightly from those defined
by the Linux Standard Base 4.1. Runlevels 0, 1, and 6 are the same as the standard. However, runlevel 2 is
considered the default runlevel; this runlevel is configured for multiple users with the GUI running, much like the
standard runlevel five. Runlevels 3, 4, and 5 are initially the same as runlevel 2.

If an administrator wants to change the runlevels of a service, the configuration file for that service can be modified
in the /etc/init directory. For example, in an installation of Ubuntu which includes the Apache web server, this
directory normally contains the /etc/init/apache2.conf Upstart configuration file. Within the
/etc/init/apache2.conf file should be two lines which define the runlevels to start and stop the server:

start on runlevel [2345]


stop on runlevel [!2345]

In this case, the service would be started up in runlevels 2 through 5 and would be stopped in runlevels that are not
2 through 5 because the ! character indicates "not these". To change the service to only be available in runlevels 2
and 3, change the lines to be like the following:

start on runlevel [23]


stop on runlevel [!23]

To disable a service without uninstalling it, an override file can be created in the /etc/init directory. This file
should have the same name as the service configuration file, but ending in .override instead of .conf. This is the
preferred technique over commenting out the "start on" lines.

The contents of the .override file should simply be the word manual, which means that the service will ignore any
"start on" lines from the configuration file. For example, to override the apache2 configuration file and disable the
web server, execute the following command:

[sysadmin@localhost ~]$ sudo 'echo manual > /etc/init/apache2.override'


18.10 The systemctl Command
The systemctl command is used in systems that have systemd as a replacement for the traditional init process.
This one command can be used to manually control the state of services, enable or disable automatic starting of
services, as well as change system targets.

The systemctl command looks in the /usr/lib/systemd directory for information about which symbolic link
enables a specific service. This directory is where a service’s files are originally placed when it is installed.

It is also possible to edit service files in order to modify the service; however, these changes should be made to
service files found in the /etc/systemd directory instead.

To manually control the state of a service, use the systemctl command to start, stop, or check the status of that
service. For example, to start a service like the web server, execute the following:

systemctl start httpd.service

To shut down the service:

systemctl stop httpd.service

To check the state of the service:

systemctl status httpd.service

To view the status of all services:

systemctl -a
systemctl --all

To configure a service to start automatically, execute the following:

systemctl enable httpd.service

To configure a service not to start automatically, execute the following:

systemctl disable httpd.service

As previously mentioned, it is possible to change to a different runlevel with the systemctl command:

systemctl isolate DESIRED.TARGET

The systemctl command can also manage the low or no power states of the system with command lines such as:

systemctl hibernate
systemctl suspend
systemctl poweroff
systemctl reboot

When enabling a service with systemd by executing a command such as the following, a symbolic link is created
within the target level that “wants” to have that service running:

[root@localhost ~]# systemctl enable named.service


In this example, the previous systemctl command runs the following command:

[root@localhost ~]# ln -s /usr/lib/systemd/system/named.service


/etc/systemd/system/mulit-user.target.wants/

The reason that multi-user.target wants the named.service to be running is based on a line within the
named.service file that contains the following:

WantedBy=multi-user.target

In essence, this line sets the only target that will normally start up this service automatically. If the administrator
modifies the target that WantedBy is set to, then the next time that service is enabled, the symbolic link that enables
the service will be made to the new target that wants the service.

For example, if the line for the named.service in the /usr/lib/systemd/system/named.service file is updated
to be the following:

WantedBy=graphical.target

Then, after executing the systemctl disable named.service and systemctl enable named.service
commands, the link to start the named service is created in the /etc/systemd/system/graphical.target.wants
directory and the service will be started when the system is going to the graphical.target instead of the multi-
user.target.

Similar to the chkconfig --list command, all the services that are supposed to be enabled for a specific target
within systemd can be viewed by using a systemctl list-dependencies command for that target, such as:

[root@localhost ~]# systemctl list-dependencies graphical.target

The partial output below shows each level of wanted services below a target and the dependencies between each
target indented. You see services like atieventsd.service and gdm.service are wanted by the
graphical.target.

Also, the graphical.target depends on the multi-user.target and the multi-user.target wants the
services abrt-ccpp.service and abrt-oops.service.

The actual output shows many more services and targets.

[root@localhost ~]# systemctl list-dependencies graphical.target


graphical.target
├─atieventsd.service
├─gdm.service
├─jexec.service
├─systemd-readahead-collect.service
├─systemd-readahead-replay.service
├─systemd-update-utmp-runlevel.service
├─abrt-ccps.service
├─abrt-oops.service

Consider This

Because there are three different types of boot systems, traditional init, Upstart and systemd, the logical question
is, "Which one does my system use?" The easy answer to this question is to check for the existence of two
directories: the /etc/init and the /etc/systemd directory.
If your system has a /etc/init directory, then your system is using Upstart. If your system has a /etc/systemd
directory, then your system is using systemd. Otherwise, your system is using traditional init.

18.11 Boot Target


Many modern systems use systemd rather than init for setting boot targets. The following table shows the
runlevel equivalents for boot targets.


Runlevel Purpose systemd Target
0 Halt or shut off the system poweroff.target
1 Single-user mode for administrative tasks rescue.target
2 Multi-user mode without configured network interfaces or network services multi-user.target
3 Normal startup of the system multi-user.target
4 User-definable multi-user.target
5 Start the system normally with a graphical display manager graphical.target
6 Restart the system reboot.target

To check the current runlevel on a Linux system, list the /etc/systemd/system/default.target file using the
ls -l command:

Note

The following examples represent a system that is different from the virtual machine in this module. The examples
may not match the output in our virtual environment.

[sysadmin@localhost ~]$ su - root


Password:
[root@localhost ~]# ls -l /etc/systemd/system/default.target
lrwxrwxrwx 1 root root 37 Dec 4 14:39 /etc/systemd/system/default.target -
>/lib/systemd/system/multi-user.target

If you need to set the system to boot into single-user mode for troubleshooting or recovery operations, use the
systemctl enable rescue.target command, followed by systemctl set-default rescue.target
command:

[root@localhost ~]# systemctl enable rescue.target


Created symlink /etc/systemd/system/kbrequest.target, pointing to
/usr/lib/systemd/system/rescue.target.
[root@localhost ~]# systemctl set-default rescue.target
Removed /etc/systemd/system/default.target.
Created symlink /etc/systemd/system/default.target, pointing to
/usr/lib/systemd/system/rescue.target.

To change the system to graphical mode after booting, use the systemctl isolate graphical.target
command:

[root@localhost ~]# systemctl isolate graphical.target


Failed to get D-Bus connection: Operation not permitted
18.12 acpid
Linux systems use the Advanced Configuration and Power Interface (ACPI) event daemon acpid to notify user-
space programs of ACPI events. The ACPI allows the kernel to configure hardware components and manage the
system’s power settings, such as battery status monitoring, temperature, and more.

One example of using acpid for power management would be having the system shut down after the user presses
the power button. On modern systems, acpid is normally started as a background process during bootup and opens
an event file in the /proc/acpi directory. For example, the wakeup file in the /proc/acpi directory below
displays the following information:

sysadmin@localhost:~$ su -
Password:
root@localhost:~# ls -l /proc/acpi
total 0
-rw-r--r-- 1 root root 0 May 28 21:09 wakeup
root@localhost:~# cat /proc/acpi/wakeup
Device S-state Status Sysfs node
PCI0 S5 *disabled no-bus:pci0000:00
root@localhost:~#

When the kernel sends out an ACPI event, acpid will determine the next steps based on rules defined in
configuration files in the /etc/acpi directory. Administrators can create rules scripts in the /etc/acpi directory
to control the actions taken by the system.

The acpi command is used to display information about system hardware ACPI settings, it’s not installed on our
VM, but the above example shows a basic acpi script in the /proc/acpi directory that controls waking the
machine up after being suspended. There are many options available to the acpi command to display various
information for power management. The table below summarizes some of the options available to the acpi
command:

Option Purpose
-b
Displays battery information
--battery
-a
Displays ac adapter information
--ac-adapter
-t
Displays thermal information
--thermal
-c
Displays cooling device information
--cooling
-s
Displays non-operational devices
--show-empty
-f
Uses Fahrenheit as the temperature unit instead of the default, Celsius
--fahrenheit
-i
Displays additional details if they are available; battery capacity and temperature trip points
--details
Note

The acpi command does not exist in our virtual environment.


Key Terms

/etc/init.d/
Contains scripts used by the System V init tools (SysVinit)
Section 18.6
/etc/inittab
Configuration file read by init when it starts up to determine what process to start for various run levels.
| Section 18.2
/etc/systemd/
The location of various unit files that control services controlled by systemd.
Section 18.11
/usr/lib/systemd/
The location of services provided by installed packages.
Section 18.11
init
The parent of all processes on the system, it is executed by the kernel and is responsible for starting all
other processes.
| Section 18.4
shutdown
Arranges for the system to be brought down in a safe way. All logged-in users are notified that the system
is going down and, within the last five minutes of TIME, new logins are prevented.
Section 18.4
systemctl
The interface to systemd, the init system used by many Linux distributions. It combines the functionality of
both service and chkconfig into a single tool that you can use for instance to enable/disable services
permanently or only for the current session.
Section 18.11
systemd
A full replacement for init with parallel starting of services and other features, used by many distributions.
| Section 18.1
telinit
Signal init to change the system's runlevel. telinit is actually just a link to init, the ancestor of all processes.
Section 18.4
wall
Displays a message, or the contents of a file, or otherwise its standard input, on the terminals of all
currently logged in users.
LAB 18
18.0 Introduction
In order to provide the functionality you need to apply these concepts, this VM may require a minute or two to
load.

Having different runlevels provides a means to fine-tune your operating system. You can have specific services
running at different runlevels, providing an easy way to change the state of the system.

In this lab, you will explore two distributions, which both make use of the Upstart service to different degrees:
CentOS and Ubuntu.

18.1 Step 1
Please use the Legacy CentOS image to complete the remaining steps. Select the CentOS PC by clicking on the tab
in the window on the right side of the screen.
This portion of the lab requires an older version of CentOS in order to practice using Grub Legacy, which is
unavailable on modern systems.

Click on the CentOS PC tab and log in to the system using the root account. When prompted, provide the root
password:

root
netlab123
CentOS release 6.10 (Final)
Kernel 2.6.32-754.el6.x86_64 on an x86_64

centos login: root


Password:
[root@centos ~]#

18.2 Step 2
List the contents of the /etc/init.d directory:

ls /etc/init.d
[root@centos ~]# 1s /etc/init.d

auditd halt killall multipathd quota_nld saslauthd


blk-availability ip6tables lvm2-lvmetad netconsole rdisc single
crond iptables lvm2-monitor netfs restorecond sshd .
functions iscsi mdmonitor network rsyslog udev-post
haldaemon iscsid messagebus postfix sandbox
[root@centos ~]#
18.3 Step 3
Execute the following command to see the current status of the sshd service:

/etc/init.d/sshd status
[root@centos ~]# /etc/init.d/sshd status
openssh-daemon (pid 984) is running...
[root@centos ~]#
The Process ID (pid) in the terminal above may be different in our virtual environment.

18.4 Step 4
Execute the following commands to stop the sshd service and verify that it is stopped:

/etc/init.d/sshd stop
[root@centos ~]# /etc/init.d/sshd stop
Stopping sshd: [ OK ]
[root@centos ~]#

18.5 Step 5
Execute the following commands to start the sshd service and verify that it is started:

/etc/init.d/sshd start
/etc/init.d/sshd status
[root@centos ~]# /etc/init.d/sshd start
Starting sshd: [ OK ]
[root@centos ~]# /etc/init.d/sshd status
openssh-daemon (pid 1295) is running...
[root@centos ~]#

18.6 Step 6
Execute the following commands to restart the sshd service and verify that it is started:

/etc/init.d/sshd restart
/etc/init.d/sshd status
[root@centos ~]# /etc/init.d/sshd restart
Stopping sshd: [ OK ]
Starting sshd: [ OK ]
[root@centos ~]# /etc/init.d/sshd status
openssh-daemon (pid 1315) is running...
[root@centos ~]#
18.7 Step 7
Execute the following command to determine which arguments can be passed to the /etc/init.d/sshd
command:

/etc/init.d/sshd
[root@centos ~]# /etc/init.d/sshd
Usage: /etc/init.d/sshd {start|stop|restart|reload|force-reload|condrestart|try-
restart|status}
[root@centos ~]#
A common question that beginning Linux users have is "what does this script really do?". The next step of this lab
focuses on how you can figure out by looking at the script itself.

18.8 Step 8
Use the more command to display the contents of the /etc/init.d/sshd file:

more /etc/init.d/sshd
#!/bin/bash
#
# sshd Start up the OpenSSH server daemon
#
# chkconfig: 2345 55 25
# description: SSH is a protocol for secure remote shell access. \
# This service starts up the OpenSSH server daemon.
#
# processname: sshd
# config: /etc/ssh/ssh_host_key
# config: /etc/ssh/ssh_host_key.pub
# config: /etc/ssh/ssh_random_seed
# config: /etc/ssh/sshd_config
# pidfile: /var/run/sshd.pid

### BEGIN INIT INFO


# Provides: sshd
# Required-Start: $local_fs $network $syslog
# Required-Stop: $local_fs $syslog
# Should-Start: $syslog
# Should-Stop: $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start up the OpenSSH server daemon
--More--(14%)

Note that the third line of this file, Start up the OpenSSH server daemon, describes what this script does. The
description line provides more details and the processname line provides the exact name of the process that this
script starts and stops.

Suppose the description provided isn't really enough for you to understand what this service actually does. To learn
more, you could look at the man page for sshd (although in this lab environment, the man pages don't exist, so this
would be more of a "real world" solution).

To quit the more command, type Q.

q
18.9 Step 9
Execute the following commands to view a list of the scripts that are started when the system is brought to runlevel
3:

cd /etc/rc.d/rc3.d
1s S*
[root@centos ~]# cd /etc/rc.d/rc3.d
[root@centos rc3.d]# ls S*

S02lvm2-monitor S11auditd S15mdmonitor S26udev-post S90crond


S07iscsid S12rsyslog S25blk-availability S55sshd S99local
S10network S13iscsi S25netfs S80postfix
[root@centos rc3.d]#

18.10 Step 10
Execute the following command to view a list of the scripts that are stopped when the system is brought to runlevel
3:

1s K*
[root@centos rc3.d]# ls K*
K10saslauthd K87restorecond K89rdisc K92iptables
K87multipathd K89netconsole K92ip6tables
[root@centos rc3.d]#

18.11 Step 11
Execute the following command to see the chkconfig information for the sshd script:

grep chkconfig /etc/init.d/sshd


[root@centos rc3.d]# grep chkconfig /etc/init.d/sshd
# chkconfig: 2345 55 25
[root@centos rc3.d]#

Recall that the first value (2345) is the runlevel that the sshd service should be run by default. The second value
(55) is the start number for the script, and the third value (25) is the stop value for the script.
18.12 Step 12
Execute the following command to display when the sshd is started:

chkconfig --list sshd


[root@centos rc3.d]# chkconfig --list sshd
sshd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
[root@centos rc3.d]#

Based on the output from the previous command, the ssh should start when the system goes to runlevels 2,3,4, and
5. Conversely, the ssh services should be stopped at runlevels 0,1,and 6.

18.13 Step 13
Execute the following command to verify that runlevels 2, 3, 4, and 5 contains start scripts for the sshd service:

1s /etc/rc.d/rc[0-6].d/S*sshd
[root@centos rc3.d]# ls /etc/rc.d/rc[0-6].d/S*sshd
/etc/rc.d/rc2.d/S55sshd /etc/rc.d/rc4.d/S55sshd
/etc/rc.d/rc3.d/S55sshd /etc/rc.d/rc5.d/S55sshd
[root@centos rc3.d]#

18.14 Step 14
Execute the following command to verify that runlevels 0, 1, and 6 contain stop scripts for the sshd service:

1s /etc/rc.d/rc[0-6].d/K*sshd
[root@centos rc3.d]# ls /etc/rc.d/rc[0-6].d/K*sshd
/etc/rc.d/rc0.d/K25sshd /etc/rc.d/rc1.d/K25sshd /etc/rc.d/rc6.d/K25sshd
[root@centos rc3.d]#

18.15 Step 15
Execute the following commands to have the sshd script stopped at all runlevels and confirm:

chkconfig sshd off


chkconfig --list sshd
[root@centos rc3.d]# chkconfig sshd off
[root@centos rc3.d]# chkconfig --list sshd
sshd 0:off 1:off 2:off 3:off 4:off 5:off 6:off
[root@centos rc3.d]#
Execute the following commands to have the sshd script started only at runlevel 3 and confirm:

chkconfig --level 3 sshd on


chkconfig --list sshd
[root@centos rc3.d]# chkconfig --level 3 sshd on
[root@centos rc3.d]# chkconfig --list sshd
sshd 0:off 1:off 2:off 3:on 4:off 5:off 6:off
[root@centos rc3.d]#

18.17 Step 17
Execute the following command to verify the runlevels that contain stop scripts for the sshd service:

1s /etc/rc.d/rc[0-6].d/K*sshd
[root@centos rc3.d]# ls /etc/rc.d/rc[0-6].d/K*sshd
/etc/rc.d/rc0.d/K25sshd /etc/rc.d/rc2.d/K25sshd /etc/rc.d/rc5.d/K25sshd
/etc/rc.d/rc1.d/K25sshd /etc/rc.d/rc4.d/K25sshd /etc/rc.d/rc6.d/K25sshd
[root@centos rc3.d]#

18.18 Step 18
Execute the following command to display the current runlevel:

runlevel
[root@centos rc3.d]# runlevel
N 3
[root@centos rc3.d]#

18.19 Step 19
Execute the following command to view the default runlevel

tail /etc/inittab
[root@centos rc3.d]# tail /etc/inittab
# Default runlevel. The runlevels used are:
# 0 - halt (Do NOT set initdefault to this)
# 1 - Single user mode
# 2 - Multiuser,without NFS (The same as 3, if you do not have networking)
# 3 - Full multiuser mode
# 4 - unused
# 5 - X11
# 6 - reboot (Do NOT set initdefault to this)
#
id:3:initdefault:
[root@centos rc3.d]#
18.20 Step 20
Use the vi command to modify the /etc.inittab file in order to change the default runlevel:

vi /etc/inittab
[root@centos rc3.d]# vi /etc/inittab

18.21 Step 21
Use the Down Arrow to move to the last line and then use the vi command to replace the value of 3 with a value
of 2:

Down Arrow
Right Arrow
i
Delete
2
Esc
:wq!

Before

# ADDING OTHER CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.


#
# System initialization is started by /etc/init/rcS.conf
#
# Individual runlevels are started by /etc/init/rc.conf
#
# Ctrl-Alt-Delete is handled by /etc/init/control-alt-delete.conf
#
# Terminal gettys are handled by /etc/init/tty.conf and /etc/init/serial.conf.
# with configuration in /etc/sysconfig/init.
#
# For information on how to write upstart even handlers, or how
# upstart works, see init(5), init(8), and initctl(8).
#
# Default runlevel. The runlevels used are:
# 0 - halt (Do NOT set initdefault to this)
# 1 - Single user mode
# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)
# 3 - Full multiuser mode
# 4 - unused
# 5 - X11
# 6 - reboot (Do NOT set initdefault to this)
#
id:3:initdefault:

After

# ADDING OTHER CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.


#
# System initialization is started by /etc/init/rcS.conf
#
# Individual runlevels are started by /etc/init/rc.conf
#
# Ctrl-Alt-Delete is handled by /etc/init/control-alt-delete.conf
#
# Terminal gettys are handled by /etc/init/tty.conf and /etc/init/serial.conf.
# with configuration in /etc/sysconfig/init.
#
# For information on how to write upstart even handlers, or how
# upstart works, see init(5), init(8), and initctl(8).
#
# Default runlevel. The runlevels used are:
# 0 - halt (Do NOT set initdefault to this)
# 1 - Single user mode
# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)
# 3 - Full multiuser mode
# 4 - unused
# 5 - X11
# 6 - reboot (Do NOT set initdefault to this)
#
id:2:initdefault:

18.22 Step 22
Verify these changes by typing the following command

tail /etc/inittab
[root@centos rc3.d]# tail /etc/inittab
# Default runlevel. The runlevels used are:
# 0 - halt (Do NOT set initdefault to this)
# 1 - Single user mode
# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)
# 3 - Full multiuser mode
# 4 - unused
# 5 - X11
# 6 - reboot (Do NOT set initdefault to this)
#
id:2:initdefault:
[root@centos rc3.d]#

18.23 Step 23
Reboot the machine:

reboot
[root@centos rc3.d]# reboot
18.24 Step 24
After the system is finished booting, log in to the system using the root account. When prompted, provide the root
password:

root
netlab123
CentOS release 6.10 (Final)
Kernel 2.6.32-754.el6.x86_64 on an x86_64

centos login: root


Password:
Last login: Mon Nov 3 13:45:47 on tty1
[root@centos ~]#

18.25 Step 25
Execute the following command to view the previous and current runlevel:

runlevel
[root@centos ~]# runlevel
N 2
[root@centos ~]#

18.26 Step 26
Execute the following command to verify the status of the sshd daemon:

/etc/init.d/sshd status
[root@centos ~]# /etc/init.d/sshd status
openssh-daemon is stopped
[root@centos ~]#

18.27 Step 27
Execute the following system to runlevel 3 by executing the following command:

telinit 3
[root@centos ~]# telinit 3

[root@centos ~]# Mounting filesystems: [ OK ]


Retrigger failed udev events [ OK ]
Starting sshd: [ OK ]
You may need to press Enter for the prompt to appear after the command has executed.
18.28 Step 28
Wait for the process to comment and verify that the telinit command took the system to runlevel 3 by executing
the following command:

runlevel
[root@centos ~]# runlevel
2 3
[root@centos ~]#

18.29 Step 29
Verify that the sshd daemon started by checking the status:

/etc/init.d/sshd status
[root@centos ~]# /etc/init.d/sshd status
openssh-daemon (pid 1203) is running...
[root@centos ~]#

18.30 Step 30
View the contents of the /etc/init directory:

1s /etc/init
[root@centos ~]# ls /etc/init
control-alt-delete.conf quit-plymouth.conf serial.conf
init-system-dbus.conf rc.conf splash-manager.conf
kexec-disable.conf rcS.conf start-ttys.conf
plymouth-shutdown.conf rcS-emergency.conf tty.conf
prefdm.conf rcS-sulogin.conf
[root@centos ~]#
Recall that the /etc/init directory is used by Upstart. If this distribution purely used Upstart (and no traditional
init scripts), then there would be more files in this directory to define when services would start.
18.31 Step 31
View the contents of the /etc/init/control-alt-delete.conf file:

more /etc/init/control-alt-delete.conf
[root@centos ~]# more /etc/init/control-alt-delete.conf
# control-alt-delete - emergency keypress handling
#
# This task is run whenever the Control-Alt-Delete key combination is
# pressed. Usually used to shut down the machine.
#
# Do not edit this file directly. If you want to change the behaviour,
# please create a file control-alt-delete.override and put your changes there.

start on control-alt-delete

exec /sbin/shutdown -r now "Control-Alt-Delete pressed"


[root@centos ~]#

If you look at the last line of this file, you will see that is someone performs a Control-Alt-Delete, the shutdown
command would be executed. The system would be rebooted immediately after the shutdown command sends
everyone the message Control-Alt-Delete pressed.

Note that you should not modify this file directly. Instead, create a file called control-alt-delete.override and
specify your customizations in that file.

18.32 Step 32
To modify the behavior of the system when someone performs a control-alt-delete key sequence, first make a copy
of the /etc/init/control-alt-delete.conf file:

cd /etc/init
cp control-alt-delete.conf control-alt-delete.override
[root@centos ~]# cd /etc/init
[root@centos init]# cp control-alt-delete.conf control-alt-delete.override
[root@centos init]#

18.33 Step 33
Change the shutdown command so it doesn't happen immediately, but rather that it waits 5 minutes to allow
everyone the time to save work and log off. First, open the file in the vi editor:

vi control-alt-delete.override
[root@centos init]# vi control-alt-delete.override
18.34 Step 34
Use vi commands to make the change to the file:

Down Arrow
Right Arrow
i
Delete x3
+5
Esc
:wq!

Before

# control-alt-delete - emergency keypress handling


#
# This task is run whenever the Control-Alt-Delete key combination is
# pressed. Usually used to shut down the machine.
#
# Do not edit this file directly. If you want to change the behaviour,
# please create a file control-alt-delete.override and put your changes there.

start on control-alt-delete

exec /sbin/shutdown -r now "Control-Alt-Delete pressed"

After

# control-alt-delete - emergency keypress handling


#
# This task is run whenever the Control-Alt-Delete key combination is
# pressed. Usually used to shut down the machine.
#
# Do not edit this file directly. If you want to change the behaviour,
# please create a file control-alt-delete.override and put your changes there.

start on control-alt-delete

exec /sbin/shutdown -r +5 "Control-Alt-Delete pressed"

By replacing now with a +5, the shutdown command will wait 5 minutes before rebooting the system.

Do not attempt to perform a control-alt-delete after finishing the previous step. This was just a demonstration
of how to create the file, not something designed to be tested in this virtual machine.
18.35 Step 35
Please use the Ubuntu image to complete the following steps. Select the Ubuntu PC by clicking on the tab in the
window on the right side of the screen.

Click on the Ubuntu PC tab and login with the username root and the password:

root
netlab123
Ubuntu 18.04.2 LTS ubuntu tty1
ubuntu login: root
Password:
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-45-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage

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.

root@ubuntu:~#

18.36 Step 36
Execute the following command to view the contents of the /etc/init directory:

1s /etc/init.d | more
root@ubuntu:~# ls /etc/init.d | more

apparamor
console-setup.sh
cron
dbus
grub-common
hwclock.sh
irqbalance
keyboard-setup.sh
kmod
lvm2
lvm2-lvmetad
lvm2-lvmpolld
plymouth
plymouth-log
proccps
quota
quotarpc
rsync
rsyslog
ssh
udev
ufw
uuid
18.37 Step 37
Recall that the configuration files in the /etc/init.d directory determine which services are started at different
run levels. For example, execute the following command to see which runlevels the ssh service starts:

grep runlevel /etc/init.d/ssh


root@ubuntu:~# grep runlevel /etc/init.d/ssh
([ "$previous" ] && [ "$runlevel" ]) || [ "$runlevel"= S ]

Note in the output above, the string "$runlevel"= S indicates that the runlevel is single user mode

18.38 Step 38
While Ubuntu mostly uses Upstart, there are a few traditional init scripts that you can see in the
/etc/init.ddirectory:

1s /etc/init.d
root@ubuntu:~# ls /etc/init.d
apparmor grub-common kmod plymouth quotarpc udev
console-setup.sh hwclock.sh lvm2 plymouth-log rsync ufw
cron irqbalance lvm2-lvmetad procps rsyslog uuid
dbus keyboard-setup.sh lvm2-lvmpolld quota ssh
Most of these init scripts are for backward compatibility for older services. An example would be the ssh service
functionality even though it is configured as an Upstart service.

18.39 Step 39
Execute the following command to restart the ssh service:

/etc/init.d/ssh restart
root@ubuntu:~# /etc/init.d/ssh restart
[ ok ] Restarting ssh (via systemctl): ssh.service.
Chapter 19: Designing a Scheme

19.1 Introduction
A well-thought-out disk partitioning scheme is vital to optimizing the use of system resources. While it is
technically possible to make post-installation changes to partitions, this may be challenging and require system
downtime. Therefore, it is important to consider how the system will be used before you begin creating partitions.

There are many components to take into consideration when creating a partitioning strategy. The focus of this
chapter is to provide a firm understanding of these components, key terms, and important concepts regarding
partitions

19.2 Understanding Partitioning


For many people who are new to Linux, the concept of partitioning may be foreign because desktop operating
systems like Microsoft's Windows and Mac OS X don't normally expose users to complex partitioning schemes.
Before learning how to partition, it is important to understand what partitioning is and the purpose behind
partitioning, as well as terminology related to partitioning.

Partitioning is necessary in order to optimally use the space that hard drives (hard disks) provide. A new hard drive
is like a completely empty building, with no internal walls or floors. As it is, such a building wouldn't be useful,
but populating the building with walls and floors would provide the structure needed to make use of the building.

There are three steps in the process of making and using partitions:

1. Divide the hard drive into partitions.


2. Create and format filesystems inside the partitions.
3. Mount the filesystem into the directory tree.

This chapter will focus on defining partitions, filesystems, and mounting. The following chapters will focus on the
steps to perform these tasks on a Linux system.

19.2.1 Understanding Partitions


Consider a situation in which a school official needs to organize a library at a university. This library will cater to
the needs of three different groups of students: law students, engineering students, and general education students.
The administrator determines that it would be beneficial to separate the library books into three physical locations
based on these groups, but there is only one physical building available. A solution would be to place all of the law
books on the first floor, all of the engineering books on the second floor, and all other books on the third floor.
This is the concept of partitioning. The hard drive is a storage container that is capable of storing all of the system’s
files. However, there are benefits to breaking this large container into smaller containers.

Within the library building, the separation would be easy to see, as this could be done by floor or by constructing
walls between sections of the building. With a hard drive, it is important first to understand how a hard drive is
physically constructed. Consider the following graphic:

A typical hard disk drive (HDD) consists of multiple platters, which store data in magnetic form. Heads are able to
read and write on both sides of each platter. The platters are connected to the spindle and spin at the same speed.
The boom moves back and forth, allowing each head to read from or write to the same location on each platter
simultaneously.

One complete rotation around one side of a platter is called a track. The same track on both sides of all of the
platters forms a cylinder:
A typical hard drive may have thousands of cylinders. Multiple consecutive cylinders can be assigned to a
partition. For example, consider the following graphic:
The first partition would be from cylinder 1 to cylinder 544. The second partition would be from cylinder 545 to
cylinder 1040. The last partition would be from cylinder 1041 to 1600.

Creating these partitions is accomplished by a partitioning tool, such as the fdisk utility that will be covered in a
later chapter.

So, to summarize, a hard disk is broken into partitions by assigning consecutive cylinders to specific partitions.
Each partition will then have a filesystem formatted on it to give the operating system a way to organize files and
directories.
19.2.2 Partition Naming
In order to distinguish one partition from another, each partition is given a unique name. Recall that everything in
Linux is treated as a file, so the names of devices, such as drives and partitions, are stored in the /dev directory.

There are two different types of drive interfaces:⁠⁠ 

Device Type Name Example


/dev/sda
Drives that start with sd are either SATA (Serial ATA), SCSI (Small Computer System /dev/sd*
Interface) or USB drives. /dev/sdb
/dev/hda
Drives that start with hd are PATA (Parallel ATA), also known as IDE (Integrated Drive /dev/hd*
Electronics) drives. /dev/hdb

Partitions are then given names based on the drive they reside on. A number is added to the end of the drive name
to distinguish one partition from another. For example, the partitions located on drive sda would be named sda1,
sda2, etc. Partitions located on drive sdb would sdb1, sdb2, etc. The following output shows the device files for a
SATA hard drive with nine partitions:

sysadmin@localhost:~$ cd /dev
sysadmin@localhost:/dev$ ls sd*
sda sda1 sda2 sda3 sda4 sda6 sda7 sda9

Similarly, partitions on drive hda would be hda1, hda2, etc., while partitions on hdb would be hdb1, hdb2, etc.

Note

It is not critical that you understand the difference between SATA, IDE, etc. It is, however, critical that you
understand that the files used to refer to hard drives are stored in the /dev directory and begin with either sd or hd.
19.2.3 Partition Limitations
Historically, the number of partitions a system can have is limited by the Master Boot Record (MBR). Recall that
the MBR is usually contained within the first sector or 512 bytes of the disk and contains a bootloader program, as
well as the partition table. The partition table contains the definition of each partition on the hard drive, including
the starting cylinder, ending cylinder, and size.

Note

Bootladers are covered in greater detail earlier in the course.

Traditional disks using MBR partitioning can have a maximum of four primary partitions. For example, on a
traditional SATA drive, four partitions can be created with device names of /dev/sda1, /dev/sda2, /dev/sda3,
and /dev/sda4:
For non-Linux operating systems, multiple partitions are rarely needed, so the maximum of only four partitions per
drive is not a serious limitation. However, on Linux servers, more than four partitions are often necessary. As a
result, modern hardware allows the administrator to make one of the four partitions an extended partition. An
extended partition acts as a container for additional partitions called logical partitions. Consider the following:

The /dev/sda4 partition is an extended partition. The only things that are placed in this extended partition are
additional partitions, logical partitions. In this example, /dev/sda5, /dev/sda6, /dev/sda7, /dev/sda8, and
/dev/sda9 are logical partitions. By allowing /dev/sda4 to be an extended partition, more than four partitions are
possible on this one hard drive. Depending upon the type of hard disk and kernel configuration, Linux can access a
maximum of either 15 or 63 total partitions when extended partitions are used.

Partitions are typically used to store filesystems. However, for extended partitions, a filesystem is never placed
directly on the partition, but rather on each logical partition within the extended partition. Accidental placement of
a filesystem directly on an extended partition can result in complete data loss of every logical partition contained
within. Modern cloud computing can add complexity to partitioning as some filesystems can now span multiple
connected data centers.

Up until now, we’ve only discussed MBR partitioning; however, some hard drives make use of another partitioning
type called the GUID Partition Table (GPT). A globally unique identifier (GUID) is a universally unique 128-bit
number used to identify information on a computer system. This partitioning scheme was designed to replace the
traditional MBR partitioning in use since PC DOS 2.0 was introduced in 1983 and is available on systems that
support the Unified Extensible Firmware Interface (UEFI).

GPT supports very large disks, up to 9ZB in size. Extended and logical partitions are not used with GPT; instead,
all partitions are the same, and GPT supports a maximum of 128 partitions per disk. Creating GPT partitions is
accomplished using a partitioning tool called gdisk, which is similar to the fdisk utility that is used for MBR
partitions.

In addition to MBR and GPT partition tables, there are other methods for dividing up the disk, including Berkeley
Software Distribution (BSD) Unix Labels, Apple Partition Maps, and others. Also, there are tools to use
partitions in more flexible and dynamic ways, like Logical Volume Management (LVM).

Note

Recall that UEFI is a replacement for the traditional BIOS standard which specifies the boot partition. Almost all
systems built after 2010 support UEFI and it has become the de facto standard since drives larger than 2TB are
now common. Systems using UEFI, use the Extensible Firmware Interface (EFI) specification that was
originally released by Intel in 1998 to overcome the limitations of BIOS boot partitions. The EFI, also called EFI
System Partition (ESP), is the partition that stores the bootloader for an operating system.
19.2.4 Filesystem
Next, we'll examine the concept and purpose of the filesystem in regards to partitioning. In order to place files and
directories on a partition, a filesystem needs to be created. This is accomplished by formatting the partition. A
filesystem provides the operating system with a way to organize the files and directories. Moreover, a filesystem
stores information about files, such as the permissions of the files, the owner of the files, and the file type.

An analogy that may help in understanding filesystems is to consider the library example previously mentioned. A
library has thousands of books (think files) that need to be organized in a manner that makes it easy to find a
specific book. In order to do this, the books are organized into categories (think directories). However, just putting
books into directories isn't sufficient since a single category can contain hundreds or even thousands of books.

To better organize all of the books in the library, a system such as the Dewey Decimal System is used. This system
provided a central catalog of index cards, normally located in a cabinet at the front of a section where individuals
could determine the exact location of a specific book. Included in the catalog is metadata about each book, such as
publication date, author, publisher, etc. A key component of this metadata is a unique identification number for
each book.

A filesystem performs the same functions of the Dewey Decimal System for files and directories. Each file will
have an entry in the filesystem database, similar to a library catalog, although the database is often referred to as a
table.

Metadata about the file will be contained in this entry, which includes file attributes like ownership, timestamps,
data block locations, and everything about the file except for its contents. The entry also includes a unique
identification number for the file, called an inode number and pointers (or links) that inform the operating system
of the location in the filesystem (where on the hard drive) the file's data is stored.

Keep in mind that there is more than one way to organize books in a library. For example, in addition to the Dewey
Decimal System, there is a system called the Library of Congress Classification system that performs the same
function as the Dewey Decimal System but uses a different technique. The same holds true for the filesystems
available for Linux; there is more than one type available, and each uses a different technique. Some of the more
common filesystem types include:

Type Name Advantages Disadvantages


Second No journaling capability, making it
Works well with small and solid-state disk
ext2 Extended susceptible to data loss in the event of
filesystems
Filesystem power loss.
Can be upgraded from existing ext2 filesystem
Writes more to disk than ext2 because of
Third Extended without data loss. This filesystem performs
ext3 journaling, making it slower. Does not
Filesystem journaling, which allows for data recovery after a
support very large filesystems.
crash.
Fourth Support for very large disk volumes and file sizes.
Not a huge improvement over ext3. No
ext4 Extended Can operate with or without a journal. Backwards
dynamic inode creation.
Filesystem compatible with ext3 and ext2.
Works very efficiently with large files. Compatible
Extents with the IRIX operating system from SGI.
xfs The filesystem cannot be shrunk.
Filesystem Announced to be the default filesystem for RHEL
7.
Unable to support very large disks or
File Allocation Supported by almost all operating systems.
vfat files. Microsoft's intellectual property
Table Commonly used for removable media.
claims.
Type Name Advantages Disadvantages
The International Organization for Standardization Multiple levels and extensions
iso ISO 9660 standard for optical disc media that is supported by complicate compatibility. Not designed
almost all operating systems. for rewritable media.
Designed to replace ISO 9660 and adopted as the
Universal Disc Write support is limited to support
udf standard format for DVDs by the DVD
Format revision 2.01 of the standard.
Consortium.

This is only a partial list of the filesystem types available in Linux and just a brief summary of the differences
between them. A full description of the differences would be much more complex and beyond the scope of this
course and the LPIC exam.

Consider This

One of the features mentioned in the preceding table is the journaling. While a complete discussion of journals is
beyond the scope of this course, the following describes the basics of filesystem journals.

As files are changed, metadata is not initially stored on the hard drive, but rather in memory. This speeds up the
filesystem since writing these changes to the hard drive for every single file change would result in a lot of hard
drive writes.

At specific intervals, this metadata is written to the hard drive in large chunks; this process is called syncing.
Normally this poses no problems, but if the system were to crash or lose power before a sync occurred, all of that
metadata would be lost.

A filesystem recovery program, like the fsck command, can often resolve these problems, but this can take quite a
bit of time for large filesystems.

A journaling filesystem enhances filesystem recovery. For every change made to a file, a journal entry is stored on
the hard drive. While this does increase filesystem writes, a journal entry has much less impact on hard drive
performance than writing the metadata directly to the hard drive for each file change.

In a nutshell, a journaling filesystem aids in recovering corrupted filesystems while allowing for reduced hard drive
writes.
19.2.5 Linux Filesystem Components
When talking about Linux the term filesystem often refers to the ext2/ext3/ext4 family of filesystems. While there
are differences between these filesystems, they are similar enough when it comes to core filesystem components.

A full discussion of filesystem components is beyond the scope of this course, and also presents somewhat of a
moving target with virtualization and cloud computing gaining prominence. However, since Linux still operates by
the kernel communicating with external resources, all system administrators need to be familiar with the key
filesystem components described below:

Component Description
At the beginning of the filesystem is an area called the superblock. This area is used to store important
information about the filesystem, including the size of the filesystem, the type of filesystem, and
Superblock
which data blocks (where file data is stored) are available. The superblock is a key component of the
filesystem; a corrupted superblock would make the filesystem inaccessible.
Group The filesystem is divided into smaller sections called groups. The group block serves to hold data
Block about the group. Each group block also contains a backup copy of the superblock.
Each file is assigned a unique inode number for the filesystem. This inode number is associated with a
Inode Table
table that stores the file's metadata.

19.2.6 Physical vs. Virtual Filesystems


So far, the discussion regarding filesystems has been specific to physical filesystems. A physical filesystem is the
database structure installed on a partition to organize files and directories.

Suppose an operating system consists of five partitions. In order to be able to access these partitions easily, their
filesystems need to be merged together into a virtual structure.

On Microsoft Windows, this is accomplished by assigning drive letters to each partition. The first partition is
typically referred to as the C: drive (which is poorly named as it is actually a partition, not an entire drive). Newer
Microsoft Windows systems may come with multiple partitions, resulting in partitions such as D:, E:, and F:. Note
that A: and B: were previously used for floppy drives and are not typically used for hard drive partitions.

To understand this better, consider the following diagram of the Disk Management component of Microsoft's
Computer Management tool:
For this system, there are two hard drives named Disk 0 and Disk 1. Disk 0 has five partitions: three hidden, one
assigned C: and another assigned D:. Disk 1 has two partitions one assigned E: and another assigned F:. Note that
the tool also indicates that the type of filesystem that is installed on these partitions is NTFS.

In Linux, there are no drive letters. Instead, each partition is assigned a device file name as mentioned previously:

Device Types Partition Name Example


/dev/sda1
SATA, SCSI, USB /dev/sda*
/dev/sda2
/dev/hda1
PATA/IDE /dev/hda*
/dev/hda2

Users do not access the files that are stored on these partitions by directly using these device file names. After all,
it's not convenient to remember what files are located on /dev/sda1 versus what files are stored on /dev/sda2.
Instead, these device files are merged into the directory structure by mounting the partition's filesystem under a
directory tree. To understand what this means, first consider the following diagram:
From a regular user point of view, all of the directories in the previous graphic appear to be from a single hard
drive. However, these directories could represent a collection of separate filesystems merged together into a single
directory structure, which is called the virtual filesystem. Consider the following diagram:
⁠ 

As demonstrated from the previous graphic, all of the files under the /home directory are really stored in the
filesystem that is on the /dev/sda3 partition. All of the files under the /var directory are stored in the filesystem
that is on the /dev/sda2 partition. This makes /home and /var mount point directories. The / directory is also a
mount point directory, likely for the filesystem on the /dev/sda1 partition.

The process of placing a filesystem under a mount point is called mounting. This is accomplished either
automatically at boot or manually with the mount command.

Note

Mounting is covered in greater detail later in the course.

The concepts of the virtual filesystem can be a bit difficult to comprehend at first, so consider this. If the
administrator were to unmount the /dev/sda3 filesystem from the previous example, then the virtual filesystem
would look like the following:
Notice that now there is nothing under the /home directory. This is normal because a mount point directory should
be empty, as anything originally contained in a mount point directory will be replaced by the contents of the
mounted partition's filesystem, and therefore be inaccessible. If the /dev/sda3 filesystem is mounted under the
/home directory, then the bob and sue directories would again be available. Another way of thinking about it:
19.3 Why Create Partitions?
So why create partitions? To begin with, at least one partition needs to be created. Regardless of the operating
system, whether Linux, Microsoft Windows, or Mac OSX, at least one single partition needs to be created because
filesystems are stored within partitions, not entire hard disks.

There are several reasons why an administrator will choose to create multiple partitions when installing a Linux
operating system:

Supporting Multiple Operating Systems

Some systems may contain Linux as well as a Microsoft Windows operating systems; these are called dual boot
systems. Because the filesystems that are used with Microsoft Windows are different than Linux, this requires
multiple partitions.

Home Directories

A separate partition for the user home directories is common and typically provides many advantages, including:

 It is easier to backup or restore an entire filesystem than it is to manage each user's home directory. Recall
that each partition has a separate filesystem.
 When home directories are separated from the root filesystem, upgrades of the operating system can be
performed much more safely and efficiently.
 Filesystems can have features enabled on them, such as disk quotas. A disk quota allows the administrator
to limit how much space a user uses in a filesystem. Being able to create a disk quota for the home
directories that doesn't affect the rest of the operating system can be an advantage.

Common Writable Directories

Some directories, such as the /tmp and /var/tmp directories, are world writable. This means that any user can
store files in these directories without any limitations, by default. Unfortunately, that can cause problems if these
directories are not placed on separate filesystems.

If the /tmp and /var/tmp directories are not mount points, then files placed in these directories will go on the same
partition as the / filesystem. If a user creates a very large file, then he could end up filling up the entire /
filesystem. This would make the operating system unusable by all other users (except the root user for whom some
space is reserved).

Separating the /tmp and /var/tmp directories allows the administrator to enable disk quotas to limit how much
space can be used by each user in those directories. Even if no quotas are put into effect, having directories on a
separate partition means if a regular user fills up the partition(s) /tmp or /var/tmp are located on, the root
filesystem or other critical filesystems are not affected.

Consider This

The /tmp and /var/tmp directories must be world writable for all users, in order for the operating system to
function correctly.
Security

Using separate partitions may enhance security. Since each partition has separate inodes and data blocks,
corruption to a single partition will be contained to its mount point within the virtual filesystem. Therefore,
spreading files across multiple partitions is safer than having one partition that contains everything under the root
directory.

Sometimes a collection of files, perhaps old databases, need to be stored but shouldn't be modified. By placing
them on a separate filesystem, that partition can be mounted as read-only to prevent any alteration.

Heavily Active

If running out of space is a concern due to heavy activity within a directory, it may be desirable to have it mounted
on a separate partition. This is often the case for directories like the /var/log directory where the system adds log
file data on a regular basis.

When system processes (as opposed to regular users) write to the disk, quotas are not usually used to limit the
space. Instead, these types of directories are mounted on separate filesystems so that if they fill up then it won't fill
up the root / filesystem. While this may be bad because log files aren't generated, it is better than filling up the root
/ filesystem and making the operating system unusable for regular users.

Another type of partition that is useful in making system tasking more efficient is swap space. To describe the
concept of swap space, we will use another analogy of a physical library. In a library, there are always new books
coming in and old ones going out. These books are usually kept in a storage room or basement, still organized but
separate from the main shelves. If a book is being transferred, it is pulled from this storage and sent to another
library where it will be used. In a computer filesystem, this area is called swap space. This is a location on the
physical drive where data is stored while programs are using it. It emulates random access memory (RAM) and
frees up the actual physical memory for other processing tasks. This allows the operating system to quickly provide
information in files without having to read and write it to the main storage areas. When the user is finished with
this data, it is written to the appropriate area on the drive, and the swap space is freed up for the next task. Swap
space on an operating system can take the form of a dedicated partition (swap partition), a file (swap file), or both.
19.4 Partitioning Layout
There are some requirements in the way partitions will map to the directories that they mount on. These
requirements are documented in what is called the Filesystem Hierarchy Standard (FHS). The following table
summarizes the FHS requirements, and provides some other suggestions:

Directory Purpose Suggested Size


500MiB-50GiB+
The root filesystem holds the files essential to the operation of the system. It
/ must contain the following directories or symbolic links: bin, boot, dev, etc,
Depends on what is
lib, media, mnt, opt, sbin, srv, tmp, usr, and var.
mounted separately
/boot The /boot directory contains the Linux kernel and the boot loader files. 500MiB-2GB
/home The /home directory is where user home directories are normally created. 500MiB+ per user
Minimum of 5 GB +
The /tmp directory is used to create temporary files for the system and users.
/tmp If this directory is too small, it may prevent applications from functioning
500MiB+ per user
correctly.
actively logged in
100MiB+
/opt
The /opt directory is where third-party software is often installed. Some
examples include Google Chrome and Google Earth. Depends on how many
packages are installed
Swap is virtual memory that is not mounted on a directory. This virtual Up to 2 times the
swap memory is used when the actual memory of the system is low. On systems physical memory of
with large amounts of memory, swap is less important. the system
/usr
The /usr directory contains the bulk of the operating system's files, including
2GiB-10GiB+
most of the commands and system software.
100MiB+
/usr/local
This directory is used for locally installed software that should not be
upgraded or updated with the operating system. Size depends on local
needs
100MiB+
/var
There are many directories that may have heavy activity under /var for
services like mail, ftp, http, and printing. Depending on the
volume of activity
/boot/efi
The /boot/efi directory contains the Linux kernel and the boot loader files.
100MB-250MB
It is typically set up automatically by the installer.
Chapter 20: Creating Partitions

20.1 Introduction
The creation of partitions can be accomplished either during the installation process or at any time after the
installation is complete. Typically, users find that creating the partitions during the installation is easier because
most installation programs provide a GUI-based program, while the technique to create partitions after the
installation is typically a CLI-based program.

Additionally, the installation program will automatically create a filesystem for the new partition as well as
configure it to be mounted automatically during the boot process. When creating a partition after the installation,
these steps must be manually executed by the administrator.

However, there are some cases in which the system administrator may want to create partitions post-install. For
example, the system administrator may not have access to all resources during the installation. This could happen
when a second hard drive is added to the system at a later date.

The installation program, while easier, also doesn't provide as much flexibility in how the partition or filesystem is
created. The CLI-based commands that can be used post-install are much more powerful and flexible, providing
another benefit to waiting until after the installation to create any additional partitions.

It is important to note that some partitions need to be created during the installation process to provide a location to
install the operating system files. As a result, post-install partitions are typically created for non-system critical
features, such as a place to store additional software or to store a large database.
20.2 Creating Partitions During Installation
The installation process can vary quite a bit from one distribution to another. In the examples provided, the screen
captures are from the CentOS 6.5 installer program named Anaconda.

One step of the installation process essentially asks: How much of the hard drive space should be used to install the
operating system?

When choosing one of these options, the following should be taken into consideration:

 Use All Space: Use this option when there is no need to save any data from the existing hard drive. This
option will remove all traces of any previous hard drive data, including previous installations of other
operating systems.
 Replace Existing Linux Systems: Use this option when the system is a dual boot system, typically a
system with both a Linux operating system and a Microsoft Windows operating system. Realize that all
Linux operating systems will be replaced by this new installation. However, the Microsoft Windows
operating system should not be impacted.
 Shrink Current System: This option would be used to recover hard drive space from an existing Linux
operating system. The recovered space could then be used to install a second Linux operating system for a
dual boot system. This is an advanced installation method, and all data from the existing Linux operating
system should be backed up prior to using this method.
 Use Free Space: This option assumes that a previous operating system (Microsoft Windows or Linux) has
already been installed and there is still unpartitioned space available on the hard drive. This is usually the
case when creating a dual boot system as Microsoft Windows should be installed first without using all of
the hard drive space. The remaining space is used by the Linux Installer to install the Linux operating
system.
 Create Custom Layout: This option is used for advanced installations. The administrator is provided with the
opportunity to remove existing partitions and create new partitions to meet the needs of the customized
installation.

If the Create Custom Layout option is chosen, the distribution installer will provide a graphical tool for creating
partitions, such as the following:
Components of this graphic:

 Mount Point: The directory where the filesystem for this partition will be mounted.
 File System Type: The type of filesystem to place on this partition. The exact types that will be available
during the installation will depend on what specific Linux operating system is being installed.
 Allowable Drives: This area provides a list of available hard drives. If only one hard drive is present, then
it is greyed out. If multiple hard drives are present, then the individual who is performing the installation
can choose which hard drive to place this partition on.
 Size (MB): The size in megabytes of the partition. Note that this relates to the next field.
 Additional Size Options:
 Fixed Size: The partition will be the size specified by the Size (MB) field.
 Fill all space up to (MB): The partition will be at least the size specified by the Size MB field but
can be as large as this field. For example, if the Size (MB) field is 500, and the Fill all space up to
(MB) field is 800, then partition size will be between 500MB and 800MB. This is useful when the
individual that is performing the installation creates partitions, and there is extra space left over. The
installer will automatically take this extra space and assign it to partitions that make use of this field.
 Fill to maximum allowable size: The partition will be at least the size specified by the Size (MB)
field. Any additional unpartitioned space will be given to this partition. If multiple partitions have
this option, the unpartitioned space is divided equally between these partitions.

To better understand the Additional Size Options fields, consider the following scenarios:

Scenario #1

Hard Drive: 2400 MB

Mount Point Size Additional Size

Partition 1 / 1000 MB Fixed Size

Partition 2 /var 500 MB Fixed Size

Partition 3 /home 200 MB Fixed Size


Result:

 / is 1000MB
 /var is 500MB
 /home is 200MB
 700MB of space is unused

Scenario #2

Hard Drive: 2400 MB

Mount Point Size Additional Size

Partition 1 / 1000 MB Fill all space up to 1200 MB

Partition 2 /var 500 MB Fixed Size

Partition 3 /home 200 MB Fixed Size

Result:

 / is 1200MB
 /var is 500MB
 /home is 200MB
 500MB of space is unused

Scenario #3

Hard Drive: 2400 MB

Mount Point Size Additional Size

Partition 1 / 1000 MB Fill all space up to 1200 MB

Partition 2 /var 500 MB Fill to maximum allowable size

Partition 3 /home 200 MB Fill to maximum allowable size


Result:

 / is 1200MB
 /var is 750MB
 /home is 450MB

Consider This

To boot to both Windows and Linux, the system administrator should install Windows first and then Linux. This is
necessary because the bootloader (the program that boots the system) for Windows can't boot Linux, but the
bootloader for Linux can boot Windows.

Consumer-based systems that are purchased in a store will already have Windows installed, but it will be using the
entire disk. In the Windows Control Panel, Administrative Tools folder, find the Computer Management tool,
which can be used to manage partitions within the Windows operating system. If Windows is using the entire disk,
use this tool to shrink the partition that Windows is using, to make space for a Linux installation.

Many Linux distributions will also query the user during installation on an existing Windows disk scheme and
allow for the shrinking of the Windows partition to leave room for Linux partitions
20.3 Creating Partitions After Installation
Originally, hard disks were called fixed disks because they were not removable. Coincidentally, the most common
command line tool for editing the partition tables on disks is called fdisk. This command can be used to create,
modify, and list the partitions on a hard drive.

One of the benefits of the fdisk tool is that it is very forgiving; if a mistake is made while using the tool, simply
quit the program, and nothing will be changed on the system. Only when changes are written (saved) before
quitting will the program update the partition table.

The fdisk program can be used in two ways: interactive and non-interactive. The interactive mode is used to
modify the partitions, and the non-interactive mode is used to list partitions. In either mode, the fdisk program
requires root privileges to run.

A couple of options can affect the output of the program when working with it in either mode. The units option -u
will list the starting and ending locations for each partition in sectors instead of cylinders. Since Linux technically
partitions by sector, it may be beneficial to use this option. If cylinders are used, the fdisk utility will translate into
sectors, so using the -u option is only really required for fine tuning of partition sizes and to avoid seeing the
following error message, highlighted below:

root@localhost:~# fdisk -l /dev/sda


Disk /dev/sda: 11.3 GB, 11261706240 bytes
255 heads, 63 sectors/track, 1369 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000ee7d2

Device Boot Start End Blocks Id System


/dev/sda1 * 1 64 512000 83 Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2 64 1306 9972736 Linux LVM
/dev/sda3 1306 1319 102400 82 Linux swap / Solaris
Partition 3 does not end on cylinder boundary.
⁠ 

Consider This

On almost every Linux distribution, the default fdisk output is displayed in cylinders. One exception is Ubuntu,
which displays output in sectors by default. To display the output in cylinders, use the -u=cylinders option.

When using the fdisk utility, a warning will occur by default:

Warning
DOS-compatible mode is deprecated. It's strongly recommended to switch off the mode and
change the display units to sectors.

The -c option disables the warning regarding compatibility issues with the MS-DOS operating system. Although it
is very unlikely that compatibility with this operating system will be an issue since DOS has not been available as a
product for nearly twenty years, a warning will be issued if the -c option is not used.
20.3.1 Displaying Partitions
To use fdisk in its non-interactive mode, add the -l option. To demonstrate, the following command will display
a list of all partitions of all hard disk devices:

root@localhost:~# fdisk -cul


Disk /dev/sda: 21.5 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000571a2

Device Boot Start End Blocks Id System


/dev/sda1 * 1 2481 19921920 83 Linux
/dev/sda2 2481 2611 1046529 5 Extended
/dev/sda5 2481 2611 1046528 82 Linux swap / Solaris

It isn't critical that you understand the entire output of this command. The following describes the key components
of the output that a system administrator should understand in order to manage partitions effectively:

 Device Info

Disk /dev/sda: 10.7 GB, 10737418240 bytes

The device name and size of the device in bytes.

 Columns
 Device Boot Start End Blocks Id System
 /dev/sda1 * 1 2481 19921920 83 Linux
 /dev/sda2 2481 2611 1046529 5 Extended
 /dev/sda5 2481 2611 1046528 82 Linux swap / Solaris

Device
The specific partition that the row is describing. For example, /dev/sda1 is the first partition on
the first SATA hard drive.
Start The starting sector of the partition.
End The ending sector of the partition.
Blocks The size of the partition in blocks.
An identifier which is used to tell the kernel what type of filesystem should be placed on this
Id partition. For example, the value 83 indicates that this partition should have an ext2, ext3, or etx4
filesystem type.
System
A human-readable name that indicates the type of filesystem the Id column refers to. For example,
83 is a Linux filesystem.

To see the partitions of a specific hard disk, add the pathname for the disk as an argument to the previous
command.

Note

The example below may not match the output in our virtual environment.

root@localhost:~# fdisk -c=dos -u=sectors -l /dev/sdb


Disk /dev/sdb: 505 MB, 505413632 bytes
5 heads, 52 sectors/track, 3796 cylinders, total 987136 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x7f08b2c3

Device Boot Start End Blocks Id System


/dev/sdb1 2552 987135 492292 6 FAT16

Note

The partition table described above is stored permanently in the MBR. When the system is booted, a copy is
created in memory. This copy is used by the kernel for various system tasks. The kernel can't look directly at a
filesystem to determine what type it is. So, the partition table stores this information for the benefit of the kernel.
When the partition is created, it is the responsibility of the system administrator to indicate what type of filesystem
will be placed on that partition by providing the partition type.

The commands used to create the filesystems are covered in greater detail later in the chapter.

Consider This

A useful tip for using fdisk in interactive mode is that a copy of the output of the fdisk -l command can be sent
to a file on disk. Anyone who has ever made a mistake when partitioning a disk and needs to refer to the previous
setup will appreciate having a copy of the exact cylinders and filesystems to refer to.

root@localhost:~# fdisk -l /dev/sda > mydisklayout.txt


20.3.2 fdisk Interactive Mode
In the interactive mode, a system administrator can use the fdisk command to create and modify partitions. To
enter the interactive mode, do not use the -l option, but still use -c and -u options. The pathname for the disk to
edit is required. For example, to edit the partitions for the first SATA /dev/sda hard drive, execute the following
command to display a prompt:

Note

The following examples may not match the output in our virtual environment.

root@localhost:~# fdisk -cu /dev/sda


Command (m for help):

The m command will display a menu or help screen:

Command (m for help): m

Command action
a toggle a bootable flag
b edit bsd disklabel
c toggle the dos compatibility flag
d delete a partition
l list known partition types
m print this menu
n add a new partition
o create a new empty DOS partition table
p print the partition table
q quit without saving changes
s create a new empty Sun disklabel
t change a partition's system id
u change display/entry units
v verify the partition table
w write table to disk and exit
x extra functionality (experts only)

Before creating any partitions, it is a good idea to print the partition table by choosing the p command action. Note
that this doesn't really send output to a printer, but to the screen instead. The output will look very much like the
output of the fdisk -l command.

Command (m for help): p

Disk /dev/sda: 11.3 GB, 11261706240 bytes


255 heads, 63 sectors/track, 1369 cylinders, total 21995520 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000ee7d2

Device Boot Start End Blocks Id System


/dev/sda1 * 2048 1026047 512000 83 Linux
/dev/sda2 1026048 20971519 9972736 8e Linux LVM

Note that based on the output from the previous command, there is some unpartitioned space on the /dev/sda
device. The ending sector of the last partition /dev/sda2 is 20971519, and the /dev/sda device has a total of
21995520 sectors. This means that there are 1024001 sectors that haven't been partitioned. Given that a sector is
512 bytes, 1024001 sectors is approximately 500MB.
20.3.3 Creating Partitions
In order to create a new partition, the n command action should be chosen:

Command (m for help): n

This command will prompt the system administrator to answer several questions, as described below.

Type of Partition

Command Action
e extended
p primary partition (1-4)

The choices that are available to answer this question will vary, depending on what partitions already exist:⁠⁠ 

 If no extended partition has been created, the choices will be e for an extended partition or p for a primary
partition.
 If the extended partition has been created, the fdisk utility will automatically create a logical partition
within the free space of the extended partition.

Recall that there can be only four primary partitions or three primary partitions with one extended. If there are
already three existing primary partitions, be very careful; while there is nothing wrong with making the fourth
partition a primary partition, per se, this will result in not being able to create any additional partitions.
Additionally, if the fourth partition doesn't make use of the remaining free space on the hard drive, that space will
go to waste.

The best choice is to create an extended partition if there are already three primary partitions. For this extended
partition, allocate all of the remaining free sectors. Then, logical partitions can be created within the extended
partition.

Partition Number

Partition number (1-4): 3

When creating a primary partition, the fdisk utility will prompt for a partition number. Again, it is helpful to
display the partition table to identify what the last partition number was and a numeric value of one higher. For
example, if the last partition number was 2, then the next partition should be numbered 3.

When creating logical partitions, the fdisk utility will not prompt for a partition number and will assign a number
by default.

Starting Sector

First sector (20971520-21995519, default 20971520):

The next question asks where to start the new partition. Allocating this first sector should be extremely easy
because the fdisk utility knows which sector is the next available. Pressing the Enter key accepts this value.

First sector (20971520-21995519, default 20971520):


Using default value 20971520
It is possible to type the sector number, but this is generally not recommended, as it may create unusable ranges of
sectors.

Partition Size

Last sector, +sectors, or +size{K,M,G} (20971520-21995519, default 21995519):

The last question asks what size the partition should be. There are three different techniques for assigning the last
sector: last sector, +sectors, or +size:

 Using the last sector technique can be the hardest because there are a couple of calculations required.
Sectors of a disk are generally 512 bytes in size, so to make a new 100 MB partition requires approximately
200,000 sectors. To calculate the last sector, add 200,000 to the value of the starting sector. Typically, the
last sector technique is only used to utilize the rest of the available space. In that case, accept the default
value by pressing the Enter key:
 Last sector, +sectors, or +size{K,M,G} (20971520-21995519, default 21995519):
 Using default value 21995519
 Using the +sectors technique takes one less calculation than the last sector technique. With this technique,
calculate the number of sectors needed and prefix it with the + plus sign. For example, to create a partition
that is approximately 100MB, enter the value as +200000:
 Last sector, +sectors, or +size{K,M,G} (20971520-21995519, default 21995519): +200000
 The final technique +size is normally preferred since no calculations are needed. Use the + plus sign, the
size to make the partition, and a suffix to indicate the unit. For example, to specify the 100 MB size
partition, enter the value for the ending sector as +100M:
 Last sector, +sectors, or +size{K,M,G} (20971520-21995519, default 21995519): +100M

The following is an example of an interaction with fdisk to create a new 100 MB partition using these steps:

1. The current partition table is displayed with the p command.


2. The n command indicates a new partition is being created.
3. The user enters p to create a primary partition.
4. The partition is assigned as number 3.
5. The default value for the first sector is chosen by pressing the Enter key.
6. For the size, the user chooses +100M for a one-hundred-megabyte partition

Command (m for help): p

Disk /dev/sda: 11.3 GB, 11261706240 bytes


255 heads, 63 sectors/track, 1369 cylinders, total 21995520 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000ee7d2

Device Boot Start End Blocks Id System


/dev/sda1 * 2048 1026047 512000 83 Linux
/dev/sda2 1026048 20971519 9972736 8e Linux LVM

Command (m for help): n


Command Action
e extended
p primary partition (1-4)
p
Partition number (1-4): 3
First sector (20971520-21995519, default 20971520):
Using default value 20971520
Last sector, +sectors, or +size{K,M,G} (20971520-21995519, default 21995519): +100M
After creating a partition, verify that it was correctly created by displaying the partition table:

Command (m for help): p

Disk /dev/sda: 11.3 GB, 11261706240 bytes


255 heads, 63 sectors/track, 1369 cylinders, total 21995520 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000ee7d2

Device Boot Start End Blocks Id System


/dev/sda1 * 2048 1026047 512000 83 Linux
/dev/sda2 1026048 20971519 9972736 8e Linux LVM
/dev/sda3 20971520 21176319 102400 83 Linux

When verifying this data, pay close attention to the Start and End sectors. Notice in the previous output that the
starting sector of the /dev/sda3 partition is one value higher than the ending sector of the /dev/sda2 partition.
Any overlap would result in data loss and should be avoided.

No changes have been made to the MBR, so it is possible to quit now in the event that any errors are displayed in
the new partition table. To quit without saving changes, use the q command.

Warning

The fdisk command is a destructive partitioning tool. Any changes to your partition structure may overwrite
existing partition information and make data inaccessible.

In the next example, a fourth partition is added as an extended partition, and then two logical partitions are created
within the extended partition. Notice that once the extended partition has been created, the fdisk utility skips the
first two steps, since the partition is automatically designated as logical and assigned a number.

Command (m for help): n


Command Action
e extended
p primary partition (1-4)
e
Partition number (1-4): 4
First sector (21176320-21995519, default 21176320):
Using default value 21176320
Last sector, +sectors, or +size{K,M,G} (21176320-21995519, default 21995519):
Using default value 21995519
Command (m for help): n
First sector (21178368-21995519, default 21178368):
Using default value 21178368
Last sector, +sectors, or +size{K,M,G} (21178368-21995519, default 21995519): +100M
Command (m for help): n
First sector (21385216-21995519, default 21385216):
Using default value 21385216
Last sector, +sectors, or +size{K,M,G} (21385216-21995519, default 21995519):
Using default value 21995519

Notice that the logical partitions use starting and ending sectors that are within the extended partition:

Command (m for help): p

Disk /dev/sda: 11.3 GB, 11261706240 bytes


255 heads, 63 sectors/track, 1369 cylinders, total 21995520 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000ee7d2

Device Boot Start End Blocks Id System


/dev/sda1 * 2048 1026047 512000 83 Linux
/dev/sda2 1026048 20971519 9972736 8e Linux LVM
/dev/sda3 20971520 21176319 102400 83 Linux
/dev/sda4 21176320 21995519 409600 5 Extended
/dev/sda5 21178368 21383167 102400 83 Linux
/dev/sda6 21385216 21995519 305152 83 Linux

Delete partitions by using the d command. Be careful to avoid deleting necessary existing partitions, as this may
result in an unusable system.
20.3.4 Changing the Filesystem Type
By default, the fdisk utility sets the filesystem type to Id 83 (Linux) for primary and logical partitions. For
extended partitions, the Id should be 5 and should never be changed.

To change the filesystem type, use the t command:

Command (m for help): t

The fdisk utility will prompt for the number of the partition to be changed:

Partition number (1-6): 6

Lastly, the user will be prompted to enter a hexadecimal value for the Id. In the following example output, the user
enters a value of 82, which changes the partition Id to Linux swap/Solaris:

Hex code (type L to list codes): 82

Changed system type of partition 6 to 82 (Linux swap / Solaris)

While at the Hex Code prompt, the user can display a list of the hex codes that are available by typing the L
character:

Hex code (type L to list codes): L

0 Empty 24 NEC DOS 81 Minix / old Lin bf Solaris


1 FAT12 39 Plan 9 82 Linux swap / So c1 DRDOS/sec (FAT-
2 XENIX root 3c PartitionMagic 83 Linux c4 DRDOS/sec (FAT-
3 XENIX usr 40 Venix 80286 84 OS/2 hidden C: c6 DRDOS/sec (FAT-
4 FAT16 <32M 41 PPC PReP Boot 85 Linux extended c7 Syrinx
5 Extended 42 SFS 86 NTFS volume set da Non-FS data
6 FAT16 4d QNX4.x 87 NTFS volume set db CP/M / CTOS / .
7 HPFS/NTFS 4e QNX4.x 2nd part 88 Linux plaintext de Dell Utility
8 AIX 4f QNX4.x 3rd part 8e Linux LVM df BootIt
9 AIX bootable 50 OnTrack DM 93 Amoeba e1 DOS access
a OS/2 Boot Manag 51 OnTrack DM6 Aux 94 Amoeba BBT e3 DOS R/O
b W95 FAT32 52 CP/M 9f BSD/OS e4 SpeedStor
c W95 FAT32 (LBA) 53 OnTrack DM6 Aux a0 IBM Thinkpad hi eb BeOS fs
e W95 FAT16 (LBA) 54 OnTrackDM6 a5 FreeBSD ee GPT
f W95 Ext'd (LBA) 55 EZ-Drive a6 OpenBSD ef EFI (FAT-12/16/
10 OPUS 56 Golden Bow a7 NeXTSTEP f0 Linux/PA-RISC b
11 Hidden FAT12 5c Priam Edisk a8 Darwin UFS f1 SpeedStor
12 Compaq diagnost 61 SpeedStor a9 NetBSD f4 SpeedStor
14 Hidden FAT16 <3 63 GNU HURD or Sys ab Darwin boot f2 DOS secondary
16 Hidden FAT16 64 Novell Netware af HFS / HFS+ fb VMware VMFS
17 Hidden HPFS/NTF 65 Novell Netware b7 BSDI fs fc VMware VMKCORE
18 AST SmartSleep 70 DiskSecure Mult b8 BSDI swap fd Linux raid auto
1b Hidden W95 FAT3 75 PC/IX bb Boot Wizard hid fe LANstep
1c Hidden W95 FAT3 80 Old Minix be Solaris boot ff BBT
1e Hidden W95 FAT1

There are technically dozens of filesystem types as demonstrated by the previous output. However, only a handful
of these filesystems can realistically be used on a Linux operating system. Many of the filesystems that are listed in
the previous graphic are older. Each Linux distribution can support different filesystems as this is actually a feature
of the kernel, so it is best to look at the system's documentation to determine which filesystem types work on a
particular distribution.
In the following example, the /dev/sda6 partition is changed to 82, a swap partition, using the same steps
described above.

Command (m for help): t


Partition number (1-6): 6
Hex code (type L to list codes): 82
Changed system type of partition 6 to 82 (Linux swap / Solaris)

It is always a good idea to double-check the new Id by printing the partition table:

Command (m for help): p

Disk /dev/sda: 11.3 GB, 11261706240 bytes


255 heads, 63 sectors/track, 1369 cylinders, total 21995520 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000ee7d2

Device Boot Start End Blocks Id System


/dev/sda1 * 2048 1026047 512000 83 Linux
/dev/sda2 1026048 20971519 9972736 8e Linux LVM
/dev/sda3 20971520 21176319 102400 83 Linux
/dev/sda4 21176320 21995519 409600 5 Extended
/dev/sda5 21178368 21383167 102400 83 Linux
/dev/sda6 21385216 21995519 305152 82 Linux swap / Solaris

20.3.5 Saving Changes


If the changes that have been made to the in-memory partition table are correct, commit changes to disk with w,
followed by Enter. The fdisk utility will write the in-memory changes to the actual MBR and exit. However, it is
also possible to quit the fdisk utility without making any changes to the disk by using the q command.

Note the following possible error after saving changes:

The partition table has been altered!

Calling iotctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table. The table will be used at the next reboot or after you
run partprobe(8) or kpartx(8)
Syncing disks.

This error is the result of the kernel being unable to read the new partition table into memory from the MBR,
something that the ioctl() function is responsible for. As mentioned in the output of this error, the partprobe or
kpartx command can be executed to fix this issue if these commands are installed on the system. If not, then the
system will need to be rebooted before the new partitions can be used.
20.3.6 The sfdisk Command
There is a scriptable fdisk-like program called sfdisk. Not only can this program be used to automate
partitioning, it is also capable of backing up and restoring the current partition table.

To back up the partition table, first, determine the names of the disk devices. The sfdisk command will list the
disk(s) and their sizes when provided the -s option. If the system contained only one 500 GB disk, then the output
of the command may appear something like the following, with the pathname of the device and its size:

Note

The following examples may not match the output in our virtual environment.

root@localhost:~# sfdisk -s
/dev/sda: 500088608

Before partitioning the disk, it would be a good idea to back up the current partition table data by using the -d
option to the sfdisk command:

root@localhost:~# sfdisk -d /dev/sda > sda.disk

In the event that a mistake is made while using partition editing tools, the partition table can be restored to the
original partition table by executing the sfdisk command with the -f option:

root@localhost:~# sfdisk -f /dev/sda < sda.disk

Beware that using the wrong file may corrupt the partition table, which could result in a total loss of data.
20.4 Managing GPT
Some hard drives make use of a partitioning technology called Master Boot Record (MBR) while others make
use of a partitioning type called GUID Partitioning Table (GPT). The MBR type of partitioning has been used
since the early days of the personal computer (PC), and the GPT type has been available since the year 2000.

The GPT disks use a newer type of partitioning, which allows the user to divide the disk into more partitions than
what MBR supports. GPT also allows having partitions, which can be larger than two terabytes (MBR does not).
The tools for managing GPT disks are named similarly to the fdisk counterparts: the gdisk, cgdisk, and sgdisk
programs.

20.4.1 Managing GPT


To create and manage GPT partitions from the command line, you can use the gdisk utility, also called GPT
fdisk. It operates in a similar fashion to fdisk except it operates on GPT partitions and requires the device to be
specified in order to work.

sysadmin@localhost:~$ sudo gdisk /dev/sdb1


GPT fdisk (gdisk) version 1.0.3

Partition table scan:


MBR: not present
BSD: not present
APM: not present
GPT: not present

Creating new GPT entries.

Command (? for help): ?


b back up GPT data to a file
c change a partition's name
d delete a partition
i show detailed information on a partition
l list known partition types
n add a new partition
o create a new empty GUID partition table (GPT)
p print the partition table
q quit without saving changes
r recovery and transformation options (experts only)
s sort partitions
t change a partition's type code
v verify disk
w write table to disk and exit
x extra functionality (experts only)
? print this menu

When you specify a blank disk, it will scan the device and report back no partition information. Typing a question
mark ? character returns a list of command options available, type n to add a new partition.

Command (? for help): n


Partition number (1-128, default 1):
First sector (34-62529502, default = 2048) or {+-}size{KMGTP}:
Last sector (2048-62529502, default = 62529502) or {+-}size{KMGTP}:
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300):
Changed type of partition to 'Linux filesystem'
It returns information about the new partition that was just created; you can also type p to print the partition table
information.

Command (? for help): p


Disk /dev/sdb1: 62529536 sectors, 29.8 GiB
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): 78F1C87E-5159-4AD8-89BA-A5F79B854835
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 62529502
Partitions will be aligned on 2048-sector boundaries
Total free space is 2014 sectors (1007.0 KiB)

Number Start (sector) End (sector) Size Code Name


1 2048 62529502 29.8 GiB 8300 Linux filesystem

The v command will verify the partition to ensure it is free from errors.

Command (? for help): v

No problems found. 2014 free sectors (1007.0 KiB) available in 1


segments, the largest of which is 2014 (1007.0 KiB) in size.

The o command allows you to create a new empty partition; it verifies that you want to delete existing partitions
before proceeding.

Command (? for help): o


This option deletes all partitions and creates a new protective MBR.
Proceed? (Y/N): y

The p command again prints information about the new partition.

Command (? for help): p


Disk /dev/sdb1: 62529536 sectors, 29.8 GiB
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): 4876B7C5-0ADB-4281-AA77-A3FFAEC5F2AF
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 62529502
Partitions will be aligned on 2048-sector boundaries
Total free space is 62529469 sectors (29.8 GiB)

Number Start (sector) End (sector) Size Code Name

The w command writes the partition data to the disk and will exit. Once again, it verifies that you want to proceed
with overwriting (deleting) the existing partitions.

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): y


OK; writing new GUID partition table (GPT) to /dev/sdb1.
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot or after you
run partprobe(8) or kpartx(8)
The operation has completed successfully.
20.5 GNU Parted
So far, you have learned to use the fdisk and gdisk commands to create, list, and delete partitions. Another
available tool for creating and resizing partitions on a hard drive is the GNU Parted program. The GNU Parted
program includes the parted command line tool and the gparted graphical interface tool. One benefit of using
GNU Parted is that unlike the gdisk and fdisk tools, which are destructive partitioners, GNU Parted will non-
destructively resize a partition as well as the filesystem on top of it.

The parted program can be used in two ways: command line mode and interactive mode. When using parted in
either mode, a device must be specified. To do this, the following syntax must be used:

parted DEVICE

The DEVICE argument is used to specify the hard drive to modify, for instance, /dev/sdb. If this argument is not
used, a default device will be chosen for you, or an error message may be displayed. To use parted in command
line mode, the DEVICE argument must be followed by options to create or modify a partition. To see a list of
options available for parted, use the --help option:

root@localhost:~# parted --help


Usage: parted [OPTION]... [DEVICE [COMMAND [PARAMETERS]...]...]
Apply COMMANDs with PARAMETERS to DEVICE. If no COMMAND(s) are given, run in
interactive mode.

OPTIONs:
-h, --help displays this help message
-l, --list lists partition layout on all block devices
-m, --machine displays machine parseable output
-s, --script never prompts for user intervention
-v, --version displays the version
-a, --align=[none|cyl|min|opt] alignment for new partitions

COMMANDs:
align-check TYPE N check partition N for TYPE(min|opt)
alignment
help [COMMAND] print general help, or help on
COMMAND
mklabel,mktable LABEL-TYPE create a new disklabel (partition
table)
mkpart PART-TYPE [FS-TYPE] START END make a partition
name NUMBER NAME name partition NUMBER as NAME
print [devices|free|list,all|NUMBER] display the partition table,
available devices, free space, all found partitions, or a particular partition
quit exit program
rescue START END rescue a lost partition near START
and END
resizepart NUMBER END resize partition NUMBER
Output Omitted...

Note

Traditional short and long options, such as -l or --list, must be used when using parted in command line mode.

To view the disks on the system, use the lsblk command:

root@localhost:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 3.7T 0 disk
|-sda1 8:1 0 512M 0 part
|-sda2 8:2 0 3.5T 0 part /etc/hosts
`-sda3 8:3 0 128G 0 part [SWAP]
sdb 8:16 0 20G 0 disk

The sdb disk noted in the output above is the target device for the partitioning examples below. It is an empty disk
that is the second device on the IDE device bus.

Next, to view any existing partition information with the parted command, use the following:

root@localhost:~# parted /dev/sdb print


Model: ATA VMware Virtual I (scsi)
Disk /dev/sdb: 21.5GB
Sector size (logical/physical): 512B/512B
Partition Table:
Disk Flags:

Number Start End Size Type File system Flags

Note in the output above, that there is no partition information listed on the /dev/sdb device, as it’s currently
blank.

To make the disk partitionable, a disklabel (partition table) must be created. This is done with the following
command:

root@localhost:~# parted /dev/sdb mklabel msdos


You may need to update the /etc/fstab

Note

If a disk has an existing partition table, the command may query the user about overwriting the current partition
table, and in that case, the user would type the Y key and then press Enter.

Now that a partition table is written to the disk, partitions can be created on the disk. To create a primary partition
that takes up the first 50% of the disk, use the following command:

root@localhost:~# parted /dev/sdb mkpart primary 0% 50%


You may need to update the /etc/fstab

Once the command executes, the user can verify the partition was created with the command:

root@localhost:~# parted /dev/sdb print


Model: ATA VMware Virtual I (scsi)
Disk /dev/sdb: 21.5GB
Sector size (logical/physical): 512B/512B
Partition Table:
Disk Flags:

Number Start End Size Type File system Flags


1 1049kB 10.7GB 10.7GB primary

While it is possible to format the resulting partition with a filesystem during the parted mkpart process,
experience has indicated that the partitioning process is best done by parted and the creation of a filesystem by the
appropriate mkfs command.

At this point, 3 more primary partitions can be written to the disk or an extended partition that encompasses the rest
of the space and then logical partitions inside that.
The parted utility’s interactive mode can also be used to create or resize partitions. To begin using interactive
mode, simply use the parted command with a device argument to specify the drive:

root@localhost:~# parted /dev/sdb


GNU Parted 3.2
Using /dev/sda
Welcome to GNU Parted! Type ‘help to view a list of commands.
(parted)

Note in the example above that the prompt will change to (parted). The h command will display a menu or help
screen:

(parted) h
align-check TYPE N check partition N for TYPE(min|opt) alignment
help [COMMAND] print general help, or help on COMMAND
mklabel,mktable LABEL-TYPE create a new disklabel (partition table)
mkpart PART-TYPE [FS-TYPE] START END make a partition
name NUMBER NAME name partition NUMBER as NAME
print [devices|free|list,all|NUMBER] display the partition table, available devices,
free space, all found partitions, or a particular partition
quit exit program rescue START END rescue a lost
partition near START and END
resizepart NUMBER END resize partition NUMBER
rm NUMBER delete partition NUMBER
select DEVICE choose the device to edit
disk_set FLAG STATE change the FLAG on selected device
disk_toggle [FLAG] toggle the state of FLAG on selected device
set NUMBER FLAG STATE change the FLAG on partition NUMBER
toggle [NUMBER [FLAG]] toggle the state of FLAG on partition NUMBER
uni5 UNIT set the default unit to UNIT
version display the version number and copyright
information of Gnu Parted

Notice that many of the commands used in command line mode such as the mkpart, mklabel, and print
commands are available in the interactive mode. The process of creating and modifying partitions using parted in
interactive mode is similar to using fdisk or gdisk in interactive mode.

20.5.1 gparted
Modern systems which use the Unified Extensible Firmware Interface (UEFI) specification and GPT partitions to
boot have their own graphical and command line tools for managing storage. One powerful graphical tool is the
gparted tool, the GUI front end of the GNU Parted program. Gparted (Gnome Partition Editor) is a free, multi-
platform graphical tool for managing hard disks. It works with Linux, Windows, and MacOS and allows the
creation, reorganization, and deletion of system partitions. With this tool, you can resize existing partitions to make
space for a new operating system, enable and disable partition flags like boot and hidden, and perform many other
partitioning tasks easily with its intuitive graphical interface.

In the image below, we have a blank disk that needs to be partitioned and a filesystem created on it before it can be
used (mounted) onto the system. Partitioning defines the space on the device so that it is visible to the operating
system. Then, a high-level format is performed, which defines the filesystem to be used. Finally, the filesystem is
mounted so that data can be written to it by the operating system.
Using the gparted utility, we can create a new GPT partition table. There are several methods that can be used
when creating a table. For example, a common partitioning method is making space on an existing disk to install
another operating system by resizing the existing partition. In addition to performing disk management tasks, the
gparted tool can also attempt recovery on a corrupted partition, and copy an existing partition for backup or image
creation.
Parameters for the new partition can be entered into the dialog box such as size, name, whether it’s a primary
partition (where an operating system can be installed), and filesystem type.
To see details about the partition to be created, you would select device information from the View menu. In the
image below, at the bottom of the window, you can see there is one operation pending. When you click the green
checkmark below the menu bar, it will perform the specified action and create the new partition. There will be a
dialog confirming that you want to proceed with the action, and one confirming success.
20.6 Logical Volume Management
Logical Volume Management (LVM) is a method of managing hard disk space that provides more flexibility
than traditional partitioning of disks. LVM was developed specifically to address some of the limitations of
traditional partitioning. To understand this, consider the following scenarios:

Scenario #1

Synopsis: A system administrator performs a fresh installation of what will become a production machine. The
administrator chooses to implement the following partitioning scheme: / is 2000MB, /var is 500MB, and /home is
1000MB.

The intent behind this partitioning scheme was to provide plenty of space for the four users who will be using the
system. By making /home a separate partition, the administrator is also able to implement disk quotas.

The Problem: For the first few months, the system performs perfectly. However, errors start to occur. Users are
unable to print. After some research, the administrator discovers that the /var partition is now full of log file
entries. Unfortunately, this is also where print jobs are sent prior to being sent to the printer.

The obvious solution is to make the /var partition bigger. With traditional partitions, this can be a nightmare that
may require downtime for the system and perhaps even a reinstallation. One of the great benefits of LVM is the
ability to increase the size of the partition, referred to as a volume in LVM, as needed without the necessity for
system downtime.

Scenario #2

Synopsis: A system administrator adds two new hard drives to the system. One hard drive is 40GB and the second
is 20GB. The requirements for this system are to place a very large database on a single partition that is at least
60GB in size. This isn't possible with traditional partitions in this scenario because a partition must reside on a
single hard drive.

With LVM, a volume (think partition) can span over multiple hard drives. This provides a great deal more
flexibility over traditional partitions and is necessary for today's big data environments.

Scenario #3

Synopsis: A system administrator wants to back up the data in the /home partition. In order to get a clean backup,
all users must be signed off the system, and the /home partition needs to be unmounted, resulting in downtime.
This is due to the way that filesystem backup programs work: they back up the filesystem metadata first, then back
up the file contents. With a live filesystem, changes to files during the backup results in possibly corrupted backups
that may be worthless.

The solution is to make use of a feature called an LVM snapshot. An administrator can use this snapshot to back up
a filesystem that will appear to be static, but won't require any system downtime.

Note

Logical Volume Management is a wide and varied topic, and a complete discussion is well beyond the scope of
this class. The focus of this section will be to cover Logical Volume Management to the extent of possible LPIC-1
exam questions.
Understanding what Logical Volume Management is, the advantages of Logical Volume Management over
traditional partitioning, and basic Logical Volume Management is necessary not only for a junior system
administrator but also for anyone taking the LPIC-1 exam.

20.6.1 LVM Concepts


The steps to implement LVM include the following:

1. Connect the physical devices to the system.


2. Use pvcreate to convert the desired devices into physical volumes, which will allocate them for inclusion
in the LVM scheme. This will write a header to the physical device and make them visible to the LVM
process.
3. Use vgcreate to incorporate all of the desired physical volumes into a virtual collection called a volume
group. The volume group now will act as a multi-disk equivalent of a physical volume on which
partitioning can occur.
4. Use lvcreate to create the LVM version of disk partitions (called logical volumes) in the volume group
created previously. The logical volumes act like partitions in that the user can create filesystems on them,
mount them, and in general use them as a traditional partition.

The main advantages of using LVM in general and logical volumes, in particular, is the ability to group together
space from multiple physical devices, resize them (as well as the filesystems on them), and much more.

To develop a better understanding of how these steps work, consider a situation in which three new hard drives are
added to the system: /dev/sdb, /dev/sdc, and /dev/sdd.

At this point, they are just three hard drives that don't have anything on them, including a partition table. To use
these as part of LVM, first execute the pvcreate command on each one:

root@localhost:~# pvcreate /dev/sdb


root@localhost:~# pvcreate /dev/sdc
root@localhost:~# pvcreate /dev/sdd
Initially, these hard drives won't appear to be any different. However, there is now a small block of data, called a
header, in the very beginning of each that defines each device as a physical volume.

The next step is to create a volume group that consists of these three physical volumes. This can be accomplished
with the following command:

root@localhost:~# vgcreate vol1 /dev/sdb /dev/sdc /dev/sdd

What this now means, is that all of the space from all three physical volumes can be used to create logical volumes.
If /dev/sdb is 50GB, /dev/sdc is 20GB, and /dev/sdd is 10GB, a single logical volume could be created that is
80GB in size. Additionally, if another physical volume was added to the system (add a new hard drive, use the
pvcreate command, and then a command called vgextend), then this new space could be used to create more
logical volumes or add to the size of existing logical volumes.

Any of the space in the vol1 volume group can be used to create a logical volume with a command like the
following:
root@localhost:~# lvcreate -L 200M -n logical_vol1 vol1

The -L option is used to specify the size of the logical volume. The value of 200M means create a 200MB logical
volume. The -n option is used to provide a name to the logical volume. The resulting name of the logical volume
created by the previous command will be logical_vol1. The last argument, vol1, is the name of the volume
group from where the logical volume will obtain its physical space. The previous lvcreate command would result
in a new device name of /dev/vol1/logical_vol1 that could be used just like a traditional partition.

For Red Hat-based systems, the graphical tool system-config-lvm not only simplifies the process of working
with LVM, it also helps to visualize what is happening:
Keep in mind that this tool may not be available as it is not part of the base operating system, but may be part of an
optional add-on software package
20.7 Creating a Filesystem
If the fdisk command is used to create a partition, then the filesystem will have to be created separately.

The mkfs command can be used to create a filesystem. To make a vfat type filesystem, which is compatible with
multiple operating systems, including Microsoft Windows, execute the command like the following:

root@localhost:~# mkfs -t vfat /dev/sdb1

The mkfs command is a wrapper that executes another command, which will actually make the correct filesystem.
When provided the -t vfat option, the mkfs command will call the mkdosfs command to make the actual
filesystem. This is important to know because the mkfs command provides generic options while the underlying
command may have options specific to the filesystem that it creates. Consult the documentation, such as the man
pages, to see these additional options.

A very common filesystem is the Fourth Extended Filesystem, ext4, the default filesystem on many Linux
distributions. To create this type of filesystem, execute a command like the following:

root@localhost:~# mkfs -t ext4 /dev/sdb1

In this case, the mkfs command would end up calling the mke2fs command, which is capable of creating ext2,
ext3, and ext4 type filesystems.

Note

When creating a filesystem, the partition is written to, so previously held data on the partition will be lost. As a
result, be very careful when executing the mkfs command.

Fortunately, the mkfs command will not work if the partition is currently in use, meaning it's mounted.

Each filesystem has many options to modify features about the filesystem. To use these options, execute the
filesystem creation command directly, rather than the mkfs command.

For example, the mke2fs command has several options that will modify how the filesystem will behave after it has
been created. Some of these features can be changed after the filesystem has been created, but others cannot. The
following table describes a few of the common features that a system administrator may change for ext2/etx3/ext4
filesystems:

Option Description
-b
Specifies the block size of the filesystem. While the default is typically fine for normal filesystems, for
filesystems with large databases, a larger block size is more ideal.
Specifies the number of inodes. Recall that each file needs an inode, so this value is an important one. By
default, the mke2fs command uses a formula based on filesystem size to determine how many inodes to
create.
-N
Typically, this generates a huge number of inodes, which on filesystems with only a handful of large files
results in wasted spaces since these inodes take space even if they are not in use.

The number of inodes can't easily be changed after the filesystem has been created.
-m Specifies what percentage of the filesystem is reserved for system use. Consider the partial output of the df
Option Description
command shown below:

Filesystem Size Used Avail Use% Mounted on


/dev/sda2 485M 114M 346M 25% /

There appears to be something wrong with this output. If 114M of a 485M filesystem is used, then there
should be 368M available, not 346M! Also, the Use%, which displays how much space has been used, is
inaccurate. It should be closer to 23%.

The reason why these numbers are inaccurate is that 5% of the filesystem is reserved for system use.
Regular users can't use this space, so it is considered to be unavailable; as a result, the df command takes
that into consideration when reporting available space.

To specify a different percentage of reserved space, use the -m option. This is a useful option for
filesystems that the root user doesn't typically use, like the /home filesystem.

The df command will be covered in greater detail later in the course.

Consider This

The mkfs command will create the appropriate filesystems for all, except ISO 9660 and Universal Disc Format.
ISO 9660 is the format placed on CD-ROM discs and Universal Disc Format is used to format DVDs. To create an
ISO 9660 filesystem, use the mkisofs command. In order to create a Universal Disc Format filesystem, use the
mkudffs command.
20.8 exFAT
The exFat (Extended File Allocation Table) filesystem is a proprietary, lightweight filesystem created by Microsoft
in 2006 for use with flash memory storage systems like SD cards and USB thumb drives. It was designed to
replace the FAT32, and it greatly expands the amounts allowed for files and directories. Linux does not natively
support exFAT, and when trying to access data on devices formatted with it, users will be shown an error dialog
box like this one.

Fortunately, Samsung published a GPL driver for exFat so Linux users can share data with the other operating
systems which support it such as Windows 10 and MacOS.

To demonstrate how to install the necessary packages in order to access the exFat drive, consider the image below,
which shows a 63gb USB drive with the Ubuntu Disks application.
From the command line, you will need to make sure the proper repository, in this case, the universe repository, is
installed. To ensure that the repository is installed, the add-apt command can be used. In the example below, the
output of the add-apt command establishes that the repository is already present on the system. However, if it was
not, the add-apt command could be used to install it:

sysadmin@localhost:~$ sudo add-apt-repository universe


[sudo] password for sysadmin:
'universe' distribution component is already enabled for all sources.

Note

A repository is a collection of data stored on a server. In Linux, repositories are used to store system updates and
applications that can be downloaded.

The add-apt command is part of the Advanced Package Tool (APT) used for package management.

Repositories and package management are covered in greater detail later in the course.

Next, the apt update command can be used to confirm that everything in the repository is up-to-date:
sysadmin@localhost:~$ sudo apt update
Hit:1 http://us.archive.ubuntu.com/ubuntu cosmic InRelease
Get:2 http://us.archive.ubuntu.com/ubuntu cosmic-updates InRelease [88.7 kB]
Get:3 http://us.archive.ubuntu.com/ubuntu cosmic-security InRelease [88.7 kB]
Hit 4: http://us.archive.ubuntu.com/ubuntu cosmic-backports InRelease
Fetched 177 kB in 1s (139 kB/s)
Reading package lists… Done
Building dependency tree
Reading state information… Done
11 packages can be upgraded. Run ‘apt list —upgradable’ to see them.

Next, the needed exfat-fuse and exfat-utils packages will need to be installed using the apt install
command.

Lastly, mount the drive (this step can also be done from the file manager).
20.9 BTRFS
BTRFS (sometimes pronounced b-tree FS or butter FS) is a Linux native filesystem created by Oracle and
developed by multiple companies as well as many individual contributors to address the limitations of previous
filesystems.

Copy-On-Write

BTRFS is a copy-on-write (COW) system. While a complex technical feature, the main point of copy on write is
that BTRFS will not overwrite an existing file with updates, which traditional non-COW filesystems do routinely.

For example, if you have a file named datafile1.txt and you make updates to the file’s contents, on a traditional
non-COW filesystem, the file would be overwritten with the new data, making retrieval of the original version of
the file something that could only be done by restoring from backup. Instead of BTRFS overwriting
datafile1.txt, it will leave that file in place, untouched, and writes the new or changed portions of the file
elsewhere, and then changes the file’s metadata to encompass the change.

Copy-on-write is one reason why BTRFS has a significant advantage of recovery time from hardware failure,
power outage, or other forms of catastrophe. The original version of the file will remain intact, and continue to be
available even as follow-on versions or changes are written elsewhere. This has the added benefit of acting as a
journal of sorts because transactions (updates) are either completed or not, and if not, the already written to disk
portions of the file are safe and sound on disk.

Snapshots

BTRFS’s use of copy-on-write also makes snapshots possible and very useful to the system operator. A traditional
snapshot is effectively a filesystem/volume copy that is made and time-stamped. BTRFS does this differently, it
declares a reference to the original as a snapshot and if nothing is changed, effectively takes no additional space.

When a change is made after a snapshot, the changes are noted and logged, but only that change is actually made
as a copy, all of the rest of the filesystem does not need to be copied too. This is a tremendous space-saving
measure, allowing the use of snapshots for even the smallest changes to be something that will not cause space
issues.

To demonstrate, suppose that after installation, the system operator performs a snapshot of the filesystem/volume
and then creates the datafile1.txt file. The initial snapshot does not include the datafile1.txt file, but a
second or subsequent snapshot would. Therefore, a comparison of the first and second snapshots would show that
the only difference between them is the addition of the datafile1.txt file.

Traditional cloning, backups or even some implementations of snapshots would copy all or some of the original
filesystem or volume, but a BTRFS snapshot uses the original filesystem as a base, and subsequent snapshots only
contain the differences between the original state and the previous snapshot, thus making snapshots extremely
efficient on space.

Subvolumes

Another very important feature of BTRFS is its volume management, which is handled by the BTRFS volume
manager. Those familiar with Logical Volume Manager, or LVM, will understand the basic concept of BTRFS
being able to base its volumes/filesystems on multiple physical devices. Any volume can be based on one or more
physical disks, and can also contain subvolumes, which are effectively portions of a volume that are used as a
virtual disk.
Consider This

Virtual storage is represented logically. Logical computing basically means represented as software rather than
hardware. The reason for creating logical storage is that it can be merged together to create one large storage pool.
To get from hardware to software, the physical storage capacity from all the storage devices needs to be pooled
together to form one large virtual disk.

One of the main areas where subvolumes can be helpful is in the application of updates to a system. To do this, a
subvolume is created that encompasses the main volume, the updates are applied, then the system is inspected for
any issues with the updates, and if no issues are found, everything continues on as normal. If any issues are found,
the system updates can be rolled back to the original volume’s state.

Compression

BTRFS also features compression options that can be turned on via mounting options, with the compress option
using several levels or types, or no compression at all. There is even a compression option that will force
compression of file types that do not compress well. It’s important to note that compression typically takes at least
a minimal amount of processing to accomplish, so extremely large filesystems with hard-to-compress files will
produce more system load than usual.

As you move forward in your learning, it will become clear that Linux is an ever-changing system being improved
and modified as needs arise. Partitions and filesystems are no exception, in fact, they are rapidly evolving, even as
you progress through this course. Each system improves on the last, and a strong understanding of prior systems is
needed not only for fundamental knowledge but also because Linux systems can operate for years or even decades.
Accomplished system administrators will be called on to maintain, troubleshoot, and migrate older systems to
newer technologies as business needs evolve.
20.10 Creating Swap Space
Consider a situation in which a system has a total of 8GB of RAM. Initially, this system functions properly,
however, as time goes on and new software is added to the system, Insufficient RAM errors start occurring.
Running out of usable RAM has been an issue for operating systems since RAM was first introduced.

While the best solution might be to add more RAM to the system, this isn't always possible. Hardware limitations
or budget constraints may necessitate another solution. Swap space is designed to provide a solution to this
problem.

Swap space (also called virtual memory) is hard drive space that can be used by the kernel and memory
management routines to store data that is normally stored in RAM. When RAM starts to become full, the kernel
will take some of this data and swap it to the hard drive. At a later time, as it’s needed, the data will be swapped
back to RAM.

Even if the system has plenty of RAM, creating a swap space is still useful because if the system ever crashes,
swap space is used to store a crash dump file which is used by advanced system administrators to determine why
the system crashed. As a result, typically the size of the swap space is at least equal to the size of RAM.

Consider This

The rule of “swap space should be equal to RAM” works up to a point; however, there is much discussion about
what to do when a system has a very large amount of RAM as it seems wasteful to dedicate 128, 256, or 512 GB of
disk space to swap.

It is best to research the distribution vendor or organizer’s recommended amounts of swap space. The major
supported distributions will have support and recommendations for swap amounts in their documentation.

There are two types of swap spaces that can be created:

 Swap Partition: The more common of the two, a swap partition is a partition that doesn't have a regular
filesystem on it, and is not mounted. During installation, a swap partition is created, but additional swap
partitions can be created at a later time.
 Swap File: In the event that there is no unpartitioned space left on the hard drive, a swap file can be used.
Swap partitions are typically faster than swap files as they are a filesystem, not a file, that is located on top
of another filesystem. Swap files are more flexible and can be created on the fly without the need to
repartition the hard drive.
20.10.1 Creating a Swap Partition
The steps to creating a swap partition are:

1. Create a partition with an Id of 82 using fdisk as previously described:


2. Command (m for help): n
3. Command Action
4. e extended
5. p primary partition (1-4)
6. p
7. Partition number (1-4): 3
8. First sector (20971520-21995519, default 20971520):
9. Using default value 20971520
10. Last sector, +sectors, or +size{K,M,G} (20971520-21995519, default 21995519): +100
11.
12. Command (m for help): t
13. Partition number (1-6): 3
14. Hex code (type L to list codes): 82
15. Changed system type of partition 3 to 82 (Linux swap / Solaris)
16. Convert the partition to swap space with the mkswap command.
17. root@localhost:~# mkswap /dev/sda3
18. Setting up swapspace version1, size = 102396 KiB
19. no label, UUID=59aaf06e-7109-471f-88a5-e81dd7c82d76
20. Enable the partition as current swap space with the swapon command:
21. root@localhost:~# swapon /dev/sda3
⁠ 

The -s option to the swapon command will display currently used swap space:

root@localhost:~# swapon -s
Filename Type Size Used Priority
/devdm-1 partition 1015800 0 -1
/dev/sda3 partition 102392 0 -2

Note

The swapon command only temporarily enables a swap partition. If the system is rebooted, the swap partition will
still exist, but it will not be enabled as swap space. The administrator needs to either execute the swapon command
again or make use of a mounting feature that is demonstrated later in the course.
20.10.2 Creating a Swap File
The steps to create a swap file:

1. Create a large file using the dd command. In order to determine which filesystem has room for the swap
file, the df command was executed. The / filesystem has plenty of room, so the swap file was placed in the
/var directory:
2. root@localhost:~# df -h
3. Filesystem Size Used Avail Use% Mounted on
4. /dev/sda9 58G 7.7G 49G 14%
5. tmpfs 7.9G 0 7.9G 0% /dev
6. shm 64M 0 64M 0% /dev/shm
7. /dev/sda9 58G 7.7G 49G 14% /etc/hosts
8. root@localhost:~# dd if=/dev/zero of=/var/extraswap bs=1M count=100
9. 100+0 records in
10. 100+0 records out
11. 104857600 bytes (105 MB) copied, 0.320096 s, 328 MB/s

Note that the resulting file is approximately 100MB in size, 100 blocks of 1MB in size. The options
bs=100M and count=1 would have resulted in the same size. The file is full of binary zero values that came
from the /dev/zero file. What is actually in the file doesn't really matter; the size of the file is what is
important.

12. Convert the file to swap space with the mkswap command:
13. root@localhost:~# mkswap /var/extraswap
14. Setting up swapspace version 1, size = 102396 KiB
15. no label, UUID=908e51f8-a022-4508-8819-73e1d8837e2b
16. Enable the file as current swap space with the swapon command:
17. root@localhost:~# swapon /var/extraswap
18. root@localhost:~# swapon -s
19. Filename Type Size Used Priority
20. /devdm-1 partition 1015800 0 -1
21. /dev/sda3 partition 102392 0 -2
22. /var/extraswap file 102392 0 -3
Key Term
fdisk
Command used to manipulate the MBR partition table for Linux. This utility can be used to create, modify,
and delete partitions for a fixed disk.
Section 20.3 | Section 20.3.1 | Section 20.3.2 | Section 20.3.3 | Section 20.3.4 | Section 20.3.5
gdisk
An interactive GPT partition table manipulator. It will automatically covert the old-style MBR partition
toable to the GPT format.
| Section 20.4 | Section 20.4.1
mke2fs
Command used to create an ext2/ext3/ext4 filesystem. This usually corresponds to a device such as a hard
drive.
Section 20.7
mkfs
Command used to build a Linux file system on a device. mkfs.fstype is also available to create a specific
file system with ease. For example an adminsitrator can use mkfs.ext4 to build an ext4 file system.
Section 20.7
mkswap
Command used to build a Linux swap area. A device argument will be need to specify where the swap area
will be created.
Section 20.10.1 | Section 20.10.2
parted
A disk partitioning and partition resizing utility. It allows an administrator to destroy, create, resize, move,
and copy ext2, linux-swap, FAT, and FAT32.
Section 20.5
swap space
Used when the amount of physical memory (RAM) is full. If the system needs more memory resources and
the RAM is full, inactive pages in memory are moved to the swap space.
| Section 20.10 | Section 20.10.1 | Section 20.10.2
Chapter 21: Mounting Filesystems

21.1 Introduction
Linux treats almost everything as a file, which makes the job that the filesystem performs particularly important.
The filesystem is a tree-like structure, with directories containing sub-directories and files. Unlike other operating
systems you may be familiar with, the logical directory structure of Linux can span multiple disks and partitions,
organized under a single root directory. Instead of manipulating drive letters, the administrator grafts, or mounts,
new partitions, each with their own filesystem, on top of existing directories to give the illusion of a single, large,
drive.

Recall the three steps in the process of making and using filesystems:

1. Divide the hard drive into partitions.


2. Format each partition with a filesystem.
3. Mount the formatted partitions onto the directory tree of an existing filesystem.

This chapter will focus on the final step of mounting the formatted partition.

21.2 Viewing Mounted Filesystems


Mounting of partitions and checking on existing mounts is accomplished with the mount command. When called
with no arguments, the mount command shows the currently mounted devices. This can be performed by regular
users, not just the root user.

⁠The output of the command may appear like the following:

Note

The following example may not match the output in our virtual environment.

sysadmin@localhost:~$ mount
/dev/sda2 on / type ext4 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
tmpfs on /dev/shm type tmpfs (rw)
/dev/sda1 on /boot type ext4 (rw)
/dev/sda5 on /home type ext4 (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs

The general format of this output is:

DESCRIPTION OF SOURCE on MOUNT POINT type FILESYSTEM TYPE (OPTIONS)

Description of Source
/dev/sda5 on /home type ext4 (rw)

proc on /proc type proc (rw)

Every mounted filesystem comes from a source—either a device representing a disk, a network location for a
network filesystem, or a tag indicating a pseudo-filesystem. This latter class (which includes proc, sysfs, devpts,
tmpfs, none, and sunrpc in the output above) is the Linux kernel's way of sharing information with the real
filesystem. For example, the proc filesystem exposes the process list and system configuration as a set of files that
can be read and written to.

Mount Point

/dev/sda2 on / type ext4 (rw)


/dev/sda5 on /home type ext4 (rw)

The mount point shows where the source can be found on the filesystem. The output above indicates that the root /
filesystem is actually served from the /dev/sda2 partition, but files in the /home directory are stored on the
/dev/sda5 partition.

Filesystem Type

/dev/sda5 on /home type ext4 (rw)


proc on /proc type proc (rw)

Each filesystem has a type, which tells the kernel how to work with the data contained on the device. For actual
filesystems like the xfs, ext4, and reisferfs filesystems, this relates the blocks stored on disk to the files and
directories that you see. For network filesystems like the nfs filesystem, this translates the network calls and
packets sent and received into disk reads and writes. For the pseudo-filesystems, the filesystem type describes what
kind of resources are exposed.

Consider This

Most operating systems allow files to be accessed on another computer rather than requiring that the files be copied
back and forth. This concept is often known as a network file share, or simply a file share. With many operating
systems, a remote file is accessed differently than a local file, such as having to specify a network path every time
the file is accessed.

UNIX makes heavy use of abstractions to make the user’s job easier. Rather than present a remote file share and a
local hard drive differently, the kernel takes care of the details and presents a standard interface. Thus, a network
volume (drive, partition, or folder) from another computer can be mounted in a similar fashion as a local drive. The
only differences are the time to access the resource and the location: network volumes use an IP address and path,
while local volumes simply use a path to a device for a local volume. After a volume is mounted, it looks like any
other part of the disk.

Another abstraction is the concept of a pseudo-filesystem. A pseudo-filesystem is not contained on an actual disk;
it’s a hierarchical view into the kernel’s data. For example, the proc pseudo-filesystem exposes each process as a
directory of files and subdirectories, where each file contains various information from the process's environment
to the list of files it has open. The proc pseudo-filesystem also has files and directories corresponding to various
options, such as network buffer sizes that can be read and written.

Presenting system information as a filesystem gives the administrator a familiar interface that is easily used and
scripted.

Options
/dev/sda5 on /home type ext4 (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)

Each filesystem also has options. Some options, such as the read/write rw option and read-only ro option, are
fairly universal. Some filesystems have options corresponding to specific items such as the network timeout
parameters for a network filesystem or the journalling parameters for a journaled filesystem.

Administrators generally work with disk drives and network filesystems, leaving the pseudo filesystems for the
distribution to set up and manage. The disks may take many forms such as individual disk partitions, logical disks
made up of multiple disks (such as LVM), or even other hardware that presents itself as a disk (such as RAID).

Another method for getting information about filesystems is by using the lsblk command. The lsblk command
lists information about block devices, either all of the ones that are available with the -a option, or output can be
tailored with various other options such as the -f option, which outputs information about available filesystems.

sysadmin@localhost:/$ lsblk -a
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 0 loop
loop1 7:1 0 0 loop
loop2 7:2 0 0 loop
loop3 7:3 0 0 loop
loop4 7:4 0 0 loop
loop5 7:5 0 0 loop
loop6 7:6 0 0 loop
loop7 7:7 0 0 loop
sda 8:0 0 3.7T 0 disk
|-sda1 8:1 0 512M 0 part
|-sda2 8:2 0 3.5T 0 part /etc/hosts
`-sda3 8:3 0 128G 0 part [SWAP]
sdb 8:16 1 0 disk
sdc 8:32 1 0 disk
sr0 11:0 1 1024M 0 rom
sr1 11:1 1 1024M 0 rom
sysadmin@localhost:/$ lsblk -f
NAME FSTYPE LABEL UUID MOUNTPOINT
sda
|-sda1
|-sda2 /etc/hosts
`-sda3 [SWAP]
sr0
sr1

21.3 Mounting Filesystems Manually


In order to properly mount a filesystem, at least two parameters must be provided to the mount command: the
filesystem identifier and the directory path name to mount it on. If no other options are needed, the mount
command will mount the filesystem on the specified directory mount point.

Important

Unless set up in the /etc/fstab file beforehand, mounting requires root user access.

Note
The following examples may not match the output in our virtual environment.

root@localhost:~# mount /dev/sdb1 /mnt

The first step to mounting a filesystem is to create a directory to serve as a mount point. Alternatively, the /mnt
and /media directories may be used, which usually exist by default on most Linux distributions for this purpose.
The /mnt and /media directories are typically only used to mount a temporary resource such as removable media,
including USB drives and optical disks. Some desktop-oriented distributions will automatically mount removable
devices under the /media/USERNAME/DEVICENAME directory.

The easiest form of the manual mount command is shown above. In this situation, the Linux kernel understands
that /dev/sdb1 is a filesystem and can even detect what kind of filesystem is on the disk. If the filesystem cannot
be detected, then use the -t option to indicate the type of filesystem:

root@localhost:~# mount -t iso9660 /dev/scd0 /mnt

This last command mounts a device called /dev/scd0 on /mnt and tells the kernel to use the iso9660 filesystem,
which is for CD and DVD devices. If it is necessary to tell the kernel what kind of filesystem is being used, then
this should be a sign that something is amiss as the autodetection is generally reliable.

When a filesystem is mounted, the default options for that filesystem are used. The -o option can be used to
specify alternative mount options from the command line. Some mount options are only used when manually
mounting a filesystem, while others are commonly used when automatically mounting a filesystem.

To mount a filesystem read-only, pass the ro option, such as:

root@localhost:~# mount /dev/sdb2 /opt -o ro

Consider This

Mounting a filesystem on a directory that already contains files will render those files temporarily inaccessible.
Therefore be careful to mount on directories known to be empty.

Once a filesystem is mounted on a directory, only the contents of that filesystem will be visible. What was
previously visible in a directory is not gone, but will become visible only after the new filesystem is unmounted.

For example, consider the situation in which the /data directory already contains files and then it is used as a
mount point:

root@localhost:~# ls /data
file1 file2
root@localhost:~# mount /dev/sda3 /data
root@localhost:~# ls /data
file3 file4

It appears that file1 and file2 were deleted, but they are just hidden from view. If the filesystem was unmounted,
then these files would reappear:

root@localhost:~# ls /data
file3 file4
root@localhost:~# umount /data
root@localhost:~# ls /data
file1 file2
21.4 Unmounting Filesystems Manually
To maximize performance, Linux keeps parts of the filesystem in memory. If media, such as USB devices, were to
be removed before those memory buffers were flushed, some data may not be written to disk. This is known as an
“unclean” dismount. This may result in data loss or even filesystem corruption. Unmounting is the procedure used
to flush all the buffers and make the disk safe to remove.

To unmount a filesystem, use the umount command with either the filesystem or the directory given as an
argument. For example, to unmount the /mnt directory that was previously mounted, execute the following
command:

Note

The following examples may not match the output in our virtual environment.

root@localhost:~# umount /mnt

Because the /dev/sdb1 filesystem was mounted under the /mnt directory, the following command would have
also worked:

root@localhost:~# umount /dev/sdb1

There are a few instances where the umount command will fail to unmount a filesystem:

 There is a file open that is located within the filesystem. The term open meaning in use by a program. For
example, if the file was being edited by a text editor like the vi editor, it would be considered to be open.
 There is an executable file running that is located within the filesystem.
 A user has a directory within the filesystem as their current working directory.

When the umount command fails to unmount a filesystem, it will normally report that the device is busy:

root@localhost:~# umount /mnt


umount: /mnt: device is busy.
(In some cases useful info about processes that use
the device is found by lsof(8) or fuser(1))

To determine what is making the filesystem busy, use the lsof or fuser commands as suggested in the output of
the previous example.

The output of the lsof command is the list of all open files on the operating system, which can easily number in
the thousands. Therefore, it is important to filter the output of the lsof command to find the correct opened file. A
good way to do this is to pipe the output of the lsof command to the grep command. Use the grep command to
find the filesystem that should be unmounted. For example, if the /mnt directory was busy, the root user can
execute the following command from the /mnt directory:

root@localhost:/mnt# lsof | grep /mnt


bash 2577 root cwd DIR 8,1 1024 2 /mnt
lsof 2631 root cwd DIR 8,1 1024 2 /mnt
grep 2632 root cwd DIR 8,1 1024 2 /mnt
lsof 2633 root cwd DIR 8,1 1024 2 /mnt

The first three columns are most useful: the name of the process, the process ID, and the user running the process.
Using the process ID along with the kill command, a system administrator can terminate processes that may be
keeping the directory busy. However, be very careful about killing processes that have files open for writing as this
may damage files or directories within a filesystem.

The fuser command provides much more concise output, and it will indicate if a file is open for writing. It is even
able to terminate processes, much like the kill command.

The -v option to the fuser command produces slightly more output, including the name of the user who is running
the process and a code which indicates the way that a process is using the directory. For example, if unsuccessfully
attempting to unmount the /mnt directory, try executing the following fuser command:

root@localhost:~# fuser -v /mnt


USER PID ACCESS COMMAND
/mnt: root 2529 ..c.. bash

In this case, the process keeping the /mnt directory busy is being run by the root user. The process id is 2529, the
access of c indicates the process is using the directory as its current directory. The process itself is the Bash shell.

Access codes that might be reported by the fuser command are:

Access Code Meaning


c The process is using the mount point or a subdirectory as its current directory.
e The process is an executable file that resides in the mount point structure.
f The process has an open file from the mount point structure.
F The process has an open file from the mount point structure that it is writing to.
r The process is using the mount point as the root directory.
m The process is a mmap'ed file or shared library.

If the process has a file open for writing or the mount point is a root directory, it is not wise to kill that process.
Otherwise, to terminate the process, execute the following command:

root@localhost:~# fuser -k /mnt

As with the kill command, the default signal sent by the fuser command is the TERM signal. Use the fuser -l
command to list the signals that can be used:

root@localhost:~# fuser -l
HUP INT QUIT ILL TRAP ABRT IOT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT
STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH IO PWR SYS

These are the same signals that are available for the kill command. To send a specific signal with the fuser
command, place a hyphen in front of the signal name. For example, to end a stubborn process that is keeping the
/mnt directory busy, execute the following command:

root@localhost:~# fuser -k -KILL /mnt

Once the process has been terminated, it should be possible to execute the umount command to unmount the
filesystem.

Consider This

As with the kill command, the fuser command must be executed with root privileges when attempting to
manage a process that is not owned by the current user.
The fuser command is designed to stop processes so a filesystem can be unmounted. Because filesystems
typically require root privileges to unmount, it would seem to be unusual for a regular user to execute either the
fuser or umount commands.

However, removable media, such as USB dongles and optical devices, typically can be unmounted by regular
users. As a result, knowing how the fuser command works can be useful for regular users, as well as
administrators.

21.5 Mounting Filesystems Automatically On Boot


Manually mounting filesystems with the mount command results in a non-persistent mount. If the system is
rebooted, then the filesystem must be mounted again to be accessed. The same is true for activating swap devices
with the swapon command.

The /etc/fstab file is used to configure what filesystems will be mounted automatically at boot. It can also be
used to activate swap devices automatically. It may be helpful to think of this file as the filesystem table, to
remember its name. To those familiar with mounting a filesystem manually, the format of the file should make
sense.

Root privileges are required to make changes to the /etc/fstab file. Any changes made to this file should be
performed with care, as mistakes may prevent the system from booting normally.

In fact, it would be an excellent idea to create a backup of the /etc/fstab file before making changes. In the event
of a disaster, the original file can be restored by copying the backup to the /etc/fstab file using a recovery of a
live disk. To make a backup copy, as the root user, execute a command like the following:

root@localhost:~# cp /etc/fstab /etc/fstab.backup

A system with three filesystem partitions and one swap partition might have an /etc/fstab file that looks like the
following:

#
# /etc/fstab
# Created by anaconda on Fri Jan 17 10:31:51 2014
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=3db6ba40-67d2-403d-9c0a-9a901697cd8d / ext4 defaults 1 1
UUID=09d641d5-bc5a-4065-8d80-8ae797dfa7f3 /boot ext4 defaults 1 2
UUID=5ee634a5-c360-4211-a41b-9aa40d78a804 /home ext4 defaults 1 2
UUID=34819281-65e3-4c78-ba2d-16952684c9cb swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0

Notice that the first seven lines of this file are comments because they start with the # character. To add comments
to the file, start a line with a # character. The existing comments recommend referring to man pages for the fstab,
findfs, mount, and blkid commands.
The first four columns in the /etc/fstab file map directly to the parameters used to mount a filesystem manually
with the mount command.

Device Identifier

The first column identifies the device to be mounted. This could be the name of a device like /dev/sdb1 in the
previous manual mount examples. However, the /etc/fstab file is read at boot time when the system is
unattended, so it is not always possible to predict the name of the devices. For example, if SATA cables are
switched during maintenance, the /dev/sda device may change places with the /dev/sdb device.

UUID

For this reason, the most common way to refer to a partition is by using a universally unique identifier (UUID), as
in the following example:

UUID=3db6ba40-67d2-403d-9c0a-9a901697cd8d / ext4 defaults 1 1


UUID=09d641d5-bc5a-4065-8d80-8ae797dfa7f3 /boot ext4 defaults 1 2
UUID=5ee634a5-c360-4211-a41b-9aa40d78a804 /home ext4 defaults 1 2

To determine what the UUID value is for a device, use the blkid command. The output of this command will look
similar to this, though the UUIDs will be different:

root@localhost:~# blkid
/dev/sda1: UUID="09d641d5-bc5a-4065-8d80-8ae797dfa7f3" TYPE="ext4"
/dev/sda2: UUID="3db6ba40-67d2-403d-9c0a-9a901697cd8d" TYPE="ext4"
/dev/sda3: UUID="34819281-65e3-4c78-ba2d-16952684c9cb" TYPE="swap"
/dev/sda5: UUID="5ee634a5-c360-4211-a41b-9aa40d78a804" TYPE="ext4"
/dev/sdb1: UUID="a9183c2c-ee1f-4e57-9a60-b0d9e87a0337" TYPE="ext4"
/dev/sdb2: UUID="71b38ae6-6824-4ad3-9e2f-821d7f532b97" TYPE="swap"

The blkid command can also be used with a path name for a filesystem as an argument and it will provide
information about just that one device:

root@localhost:~# blkid /dev/sdb1


/dev/sdb1: UUID="a9183c2c-ee1f-4e57-9a60-b0d9e87a0337" TYPE="ext4"

The UUID is automatically created when the filesystem is created. It is considered the best way to identify local
filesystems in the /etc/fstab file because it doesn't change after the filesystem has been created and it should
always be unique. Even if the hard drive is moved to another computer, the UUIDs will be unique for each
filesystem. Unfortunately, the UUID isn't easy to remember or type, so it is difficult to use for manual mounting.

Device Name

A second, more traditional way of specifying a local filesystem is to use the path name for the device, such as
/dev/sda1 for the first partition on the first disk:

/dev/sda1 / ext4 defaults 1 1


/dev/sda2 /boot ext4 defaults 1 2
/dev/sda5 /home ext4 defaults 1 2

While device path names like /dev/sdb1 are easy to remember and type, they are not as reliable as UUIDs. As the
naming of the disk drive depends on the order of detection during the boot process, the naming of the disks might
change if the order of detection changes (such as when a new disk drive is added to the system).

Labels
Another option is to use filesystem labels. The volume label can be set using the e2label command. For example,
the following command will set a label called mydata on the /dev/sdb1 filesystem:

root@localhost:~# e2label /dev/sdb1 mydata

The label for a filesystem can be viewed with the e2label command:

root@localhost:~# e2label /dev/sdb1


mydata

Labels can also be created for the extents filesystem xfs, either while making the filesystem or by using the
xfs_admin command:

root@localhost:~# xfs_admin -L myapps /dev/sdb3

Labels can be viewed (if they are set) with the blkid command just like they were for the UUIDs. The output of
the blkid command is helpful, as it shows how to use the label:

root@localhost:~# blkid /dev/sdb1


/dev/sdb1: UUID="a9183c2c-ee1f-4e57-9a60-b0d9e87a0337" TYPE="ext4" LABEL="mydata"

Labels can be used in the first field of the /etc/fstab file, such as LABEL="mydata". If labels are created by a
single administrator, unique labels can be ensured; however, multiple users with root access may accidentally
create partitions with the same label name:

LABEL="root" / ext4 defaults 1 1


LABEL="boot" /boot ext4 defaults 1 2
LABEL="home" /home ext4 defaults 1 2

Warning

Be careful with labels because they are human generated and can be duplicated when cloning a disk.

If the system detects a duplicate label, it is unpredictable which disk partition the system will actually mount when
that label is used.

The following table provides a summary of these three methods of referring to the partition to mount:

Method Advantages Disadvantages

Hard to type and difficult to


UUID Should always be unique, preventing any mounting conflicts.
remember.

Device Device names can easily change,


Easy to type and remember.
Name causing mounting errors.

Easy to type and remember. Label names won't dynamically change like
Label May not be unique like UUID naming.
device names, but they are not always unique.
Mount Point Field

The second field is the mount point (mount directory) where the partition is to be mounted. It also corresponds to
the second parameter to the mount command:

UUID=3db6ba40-67d2-403d-9c0a-9a901697cd8d / ext4 defaults 1 1


UUID=09d641d5-bc5a-4065-8d80-8ae797dfa7f3 /boot ext4 defaults 1 2
UUID=5ee634a5-c360-4211-a41b-9aa40d78a804 /home ext4 defaults 1 2

There is nothing special about a mount point, it is either an empty directory that was created with the mkdir
command for that purpose or an existing directory.

Filesystem Field

The third field is the filesystem type. Enter the correct Type Code using the values provided by the following table:

Name Type Code

Fourth Extended Filesystem ext4

Third Extended Filesystem ext3

Second Extended Filesystem ext2

Extents Filesystem xfs

File Allocation Table vfat

ISO 9660 iso

Universal Disc Format udf

In most cases, the filesystem type for regular partitions will be the ext4 filesystem:

UUID=3db6ba40-67d2-403d-9c0a-9a901697cd8d / ext4 defaults 1 1


UUID=09d641d5-bc5a-4065-8d80-8ae797dfa7f3 /boot ext4 defaults 1 2
UUID=5ee634a5-c360-4211-a41b-9aa40d78a804 /home ext4 defaults 1 2

Mount Option Field

The fourth field in the /etc/fstab file is a comma-separated list of the mount options which would normally be
passed to mount with the -o options. This field is used to pass parameters to the filesystem driver, such as to make
the device read-only or to adjust timeouts. Most filesystems have a huge number of mount options available:

UUID=3db6ba40-67d2-403d-9c0a-9a901697cd8d / ext4 defaults 1 1


UUID=09d641d5-bc5a-4065-8d80-8ae797dfa7f3 /boot ext4 defaults 1 2
UUID=5ee634a5-c360-4211-a41b-9aa40d78a804 /home ext4 defaults 1 2

The man page for the mount command provides documentation of some of the mount options that apply to all
filesystems. In addition, a search through the man page for the mount command will result in finding mount
options for specific filesystems. The following is an excerpt:

Mount options for ext4


The ext4 filesystem is an advanced level of the ext3 filesystem which
incorporates scalability and reliability enhancements for supporting
large filesystem.

The options journal_dev, noload, data, commit, orlov, oldalloc,


[no]user_xattr [no]acl, bsddf, minixdf, debug, errors, data_err, grpid,
bsdgroups, nogrpid sysvgroups, resgid, resuid, sb, quota, noquota,
grpquota and usrquota are backwardly compatible with ext3 or ext2.

journal_checksum
Enable checksumming of the journal transactions. This will
allow the recovery code in e2fsck and the kernel to detect cor-
ruption in the kernel. It is a compatible change and will be
ignored by older kernels.

journal_async_commit
Commit block can be written to disk without waiting for descrip-
tor blocks. If enabled older kernels cannot mount the device.
This will enable 'journal_checksum' internally.

The man page for the particular filesystem to be mounted will often include useful mount options. For example,
when determining mount options for an ext4 filesystem, then the man page for mkfs.ext4 would display the
correct documentation.

Earlier in this chapter, it was mentioned that partitions could be mounted read-only. To prevent any changes to a
filesystem, place the read-only mount option in the corresponding line of the /etc/fstab file:

UUID=3db6ba40-67d2-403d-9c0a-9a901697cd8d /date ext4 ro 1 1

The most common mount option is the defaults option. The defaults mount option implies a number of
standard mount options are in effect. The following table lists the mount options that are in effect when defaults
is used, the purpose of the mount option, and the option that is the opposite of the default mount option (if
available):

Mount
Purpose Opposite
Option

rw Allow reading and writing ro

suid Allow suid executes nosuid

dev Allow device files nodev

exec Allow executable files noexec

auto Automatically mount noauto

Prevent ordinary users from mounting or unmounting the partition. Using the user option allows
nouser user
non-root users to mount that particular device, which is helpful for removable media.

async All writes should be asynchronous sync

Only update access time on file access if the file has been modified or its metadata changed since
relatime N/A
last access
Using the defaults keyword is clearer and faster than specifying each individual option.

If multiple options are to be used, then they must be separated by a comma and have no embedded spaces. Any
unspecified options will still use the default values, so using the defaults keyword can be thought of as a simple
placeholder.

The following configuration will still be mounted in read/write mode, allow executable files, and so forth:

UUID=3db6ba40-67d2-403d-9c0a-9a901697cd8d /date ext4 nosuid,nodev 1 1

It is interesting to note that when using defaults for the mount options, the only mount option that will be
displayed when the mount command is executed will be the rw options:

/dev/sda2 on / type ext4 (rw)

Dump Field
UUID=3db6ba40-67d2-403d-9c0a-9a901697cd8d / ext4 defaults 1 1
UUID=09d641d5-bc5a-4065-8d80-8ae797dfa7f3 /boot ext4 defaults 1 2
UUID=34819281-65e3-4c78-ba2d-16952684c9cb swap swap defaults 0 0

The purpose of this field is to tell an administrator which filesystems should be backed up when using the dump
command. The administrator would execute the dump -w command and the resulting output would be a list of the
filesystems to back up. This list is generated by filesystems that have a value of 1 in the dump field of the
/etc/fstab file. A value of 1 in this field is used for local real filesystems (filesystems on partitions that reside on
local hard drives). Any pseudo-filesystems, remote filesystems, or swap space entries should have a 0 value in this
field.

This is a bit out of date, as the dump command is rarely used by system administrators on modern Linux
distributions. However, it is important to know since the /etc/fstab file requires a valid entry in this field.

Filesystem Check Field


UUID=3db6ba40-67d2-403d-9c0a-9a901697cd8d / ext4 defaults 1 1
UUID=09d641d5-bc5a-4065-8d80-8ae797dfa7f3 /boot ext4 defaults 1 2
UUID=34819281-65e3-4c78-ba2d-16952684c9cb swap swap defaults 0 0

The sixth field is for determining the order in which the filesystems will be checked by the fsck (File System
ChecK ) utility during system boot. This utility is designed to find and fix filesystem problems.

The root filesystem should always have a 1 in this field to indicate that it will be checked by the fsck program
first. All other local filesystems (ext2/ext3/ext4) should have a value of 2 specified for this field, so they will be
checked after the root filesystem.

If the filesystems are within the same drive, they will be checked sequentially, but if they are on separate drives,
they will be checked in parallel, if possible.

Any pseudo-filesystems, remote filesystems, or swap space entries should have a 0 value in this field. These
filesystems should never be checked by the fsck utility.

Note

The fsck utility will be covered in greater detail in a later chapter, as it can also be used as an interactive program.
21.6 Mounting With fstab
Another useful feature of mount requires discussion, passing only one argument, such as:

root@localhost:~# mount /home

Linux will read the configuration for this mount from the /etc/fstab file if it exists. This allows a new mount to
be created in /etc/fstab and then tested instead of needing a reboot. It can also be used to remount a volume that
has been taken offline for maintenance.

There is also a valuable mount option that will never be specified in the /etc/fstab file: the remount option. This
option is useful for changing a mounted filesystem’s options without unmounting the filesystem itself.

root@localhost:~# mount /home -o remount, noatime

This command will switch the /home mount to have the noatime option (the atime option shows the last time a
file was accessed or read) without needing to remount the filesystem. Keep in mind that this will not persist across
a reboot until the fstab file has been updated. Once changes have been made to the fstab file, execute something
like the following to make them effective:

root@localhost:~# mount -o remount /mnt

Remounting is different from executing the umount command on a filesystem and then executing the mount
command on that same filesystem. While unmounting/mounting will fail on an in-use filesystem, remounting is
really just changing the mount options and will succeed on an in-use filesystem.

After updating the /etc/fstab file, don't reboot the system to test the changes. Instead, use the -o remount
option. If the changes are correct, no message will be displayed, but if a mistake was made, an error like the
following would be displayed:

root@localhost:~# mount -o remount /


mount: / not mounted already, or bad option

If there are no errors in the corresponding entry contained within the /etc/fstab file, then the mount -o
command will produce no output.

The remount option is helpful but can lead to problems if the administrator allows the /etc/fstab file to get out
of sync with the running configuration.
21.7 Systemd Mount Units
Another approach to mounting filesystems is by using systemd mount units. Systemd mount units are configuration
files that end in .mount and contain information about resources to be mounted at startup.

These files contain a Mount section that has information about the filesystem mount point, and they must be named
for the specific path to be mounted. Mounts which are listed in the /etc/fstab file are converted at boot time and
when the system manager is reloaded.

The systemd-mount utility is the mechanism that systemd uses to create and start a transient .mount file, destroy a
transient .mount file, or to start an .automount unit of the filesystem.

Below is an example of a .mount file used for a snap install of software. Snaps are software installation files that
can be used across various Linux distributions instead of the specific binary installers used by Ubuntu, Red Hat,
and other distributions.

[Unit]

Description=Mount unit for core, revision 6673

Before=snapd.service

[Mount]

What=/var/lib/snapd/snaps/core_6673.snap

Where=/snap/core/6673

Type=squashfs

Options=nodev,ro,x-gdu.hide

[Install]

WantedBy=multi-user.target

In the example above, a snap mount unit was created to install software in the contents of the .mount file above.
Below is a breakdown of the fields and options in .mount file.

 The [Unit] field:


 [Unit]

 Description=Mount unit for core, revision 6673

 Before=snapd.service
Field Purpose
Description Shows which mount unit is going to be mounted.
Before Shows the snapd.service file as the file name to be mounted.

 The [Mount] field:


 [Mount]

 What=/var/lib/snapd/snaps/core_6673.snap

 Where=/snap/core/6673

 Type=squashfs

 Options=nodev,ro,x-gdu.hide
Field Purpose
What
The file to be mounted including its path. Note that an absolute path must be used in the name of
the mount unit which it controls.
Where The location it will be mounted to.
Type
The filesystem type that the file is stored in. In the example above, this is squashfs, the
compressed, read-only filesystem.
Defines the specific options to be used. The nodev option is a security feature that prevents block
Options
special devices (which could allow harmful code to be run) from being mounted on the filesystem.
The ro option stands for read-only and the x-gdu.hide option prevents the snap mount from
being visible to System Monitor.

 The [Install] field:


 [Install]

 WantedBy=multi-user.target
Field Purpose
WantedBy Tells systemd that this filesystem is to be used by the multi-user boot target.

Although mount unit configuration does allow for more flexible mounting of resources. One case for network
resources would be where having the ability to define things like how long to wait for the mount command to
finish, is desirable. However, in many cases, using the fstab file is still the preferred approach.
21.8 loop Option
The loop option to the mount command is used to mount special filesystems that are stored within a file. These
files have the extension of .img or .iso (for ISO 9660 filesystem files), which contain complete filesystems that
can be mounted with the mount command by using the loop option:

root@localhost:~# mount -o loop fs.img /mnt


root@localhost:~# mount -o loop cdrom.iso /mnt

To better understand the purpose of the loop option, consider the following scenario: A system administrator has
been instructed to download an ISO file software.iso from the internet. This ISO file contains several RPM
software packages that need to be installed on some local systems. The administrator has two choices, burn a DVD
of the ISO file, or to mount the ISO file as part of the filesystem. To conserve resources, the administrator chooses
to mount the ISO file.

To gain access to these software packages, which all end with the .rpm extension, the system administrator mounts
the ISO file and then copies the software packages by executing the following commands:

root@localhost:~# mount -o loop software.iso /mnt


root@localhost:~# mkdir /root/latestrpms
root@localhost:~# cp /mnt/*.rpm /root

After copying the software packages to the /root/latestrpms directory, the software.iso file can be
unmounted and deleted from the system.

Note

Almost everything in Linux is a file, including optical disks. If there is an image of a disk inside a file, it can be
mounted directly from the file without needing to burn the image back on a disk using the loop option.

21.9 Monitoring Filesystems


The df command can also be used to view mounted filesystems. The output of this command displays the usage of
the filesystem, where it's mounted, and the space usage of the device. To have the df command display filesystem
sizes in human-readable format, use the -h option. Use the -T option to have the df command display the
filesystem type:

root@localhost:~# df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda2 ext4 6.3G 3.2G 2.9G 53% /
tmpfs tmpfs 351M 84K 351M 1% /dev/shm
/dev/sda1 ext4 485M 52M 408M 12% /boot
/dev/sda5 ext4 2.2G 69M 2.0G 4% /home

The output displays the filesystems that have variable free space; the tmpfs filesystem, which is similar to a RAM
disk, falls into this category, while other pseudo-filesystems like the proc filesystem, do not.
21.10 Mount a Filesystem
The following describes how to configure a new filesystem that has been created on the /dev/sdb1 device to
mount during the boot process automatically. One single line will be added at the end of the /etc/fstab file. The
assumption for this example is that the partition has been created by the fdisk command and the filesystem has
been created by the mkfs command.

Before modifying the /etc/fstab file, first, gather the information needed. Use the blkid command to determine
the UUID or label of the new filesystem. The result will be similar to the following:

root@localhost:~# blkid dev/sdb1


/dev/sdb1: UUID="a9183c2c-ee1f-4e57-9a60-b0d9e87a0337" TYPE="ext4" LABEL="mydata"

In this example, the filesystem label will be used. So, the first field should be:

LABEL="mydata"

Next, create a mount point in the existing tree with the mkdir command:

root@localhost:~# mkdir /data

Now, place the following as the second field:

LABEL="mydata" /data

Assuming the filesystem on the partition is the Fourth Extended type, the value for the third field will be:

LABEL="mydata" /data ext4

Unless there is a compelling reason not to do so, use the defaults for the mount options field by specifying the
value for the fourth field as:

LABEL="mydata" /data ext4 defaults

Since /dev/sdb1 is formatted as an ext4 filesystem and this device is local to the system, the fifth field (the dump
check) should be enabled with the value of:

LABEL="mydata" /data ext4 defaults 1

By the same logic, the sixth field should have the value:

LABEL="mydata" /data ext4 defaults 1 2

Putting all of these fields together for the normal entry into the /etc/fstab file results in the following line:

LABEL="mydata" /data ext4 defaults 1 2


Device Mount Point Filesystem Options dump fsck

After modifying the /etc/fstab file, check that the new line has been added correctly by mounting the filesystem
with only the mount point or device name as an argument:

root@localhost:~# mount /data


root@localhost:~# mount /dev/sdb1
Important

If there is an error when trying to mount the filesystem, then go back and fix the /etc/fstab file or restore the
backup of this file. Do not reboot the system until the error is fixed; errors in the /etc/fstab file can prevent
the system from booting.

21.11 Activate Swap Space


The following describes how to configure a new swap partition that has been created on the /dev/sdb2 device to
activate during the boot process automatically. One single line will be added at the end of the /etc/fstab file. The
assumption here is that the partition has been created by the fdisk command and the partition has been configured
as a swap partition with the mkswap command.

For the first field, specify the device. Again, use the blkid command to gather the information about this partition.
The output would look something like the following:

root@localhost:~# blkid /dev/sdb2


/dev/sdb2: UUID="6f450a83-9d2e-409f-8bce-826696a49e54" TYPE="swap" LABEL="myswap"

In this example, the swap label will be used. So, the first field should be:

LABEL="myswap"

Important

When creating an entry for a swap file instead of a swap partition, always use the path name for the swap file, such
as /root/swapfile. This is the only setting in the /etc/fstab entry that will be different for a swap file than a
swap partition.

For the mount point in the second field, all swap partitions always use the following:

LABEL="myswap" swap

For the filesystem type in the third field, all swap partitions always use the following:

LABEL="myswap" swap swap

The defaults mount option can be used with swap partitions or swap files, just as it can be used with regular
filesystems. In most cases, using defaults is fine for performance if all swap devices are equal in read/write
performance; for this example, the defaults option will work well for the value of the fourth field:

LABEL="myswap" swap swap defaults

Consider This

Consider the pri mount option for swap partitions. This mount option will allow different priorities for different
swap spaces. The higher priority a swap device has, the more likely the Linux kernel is to use that area.
For example, if a swap file has a mount option of pri=1 and a swap partition has a mount option of pri=2, then the
swap partition will have a higher priority and be more likely to be used than the swap file.

In general, swap partitions should have better performance than swap files because the kernel needs to go through
the regular filesystem to access swap files. This will slow down the access time. So, when using both swap
partitions and swap files, assign a higher priority to the swap partition than to the swap file.

The fifth and sixth fields, the dump check and filesystem check fields, are never enabled for either swap partitions
or swap files, so they should both be zero:

LABEL="myswap" swap swap defaults 0 0

Putting all of these fields together for the normal swap partition into the /etc/fstab file results in the following
line:

LABEL="myswap" swap swap defaults 0 0


Device Mount Point Filesystem Options dump fsck

To verify that the swap partition or file has been added correctly, use the swapon -a command; this will activate
all swap entries in the /etc/fstab file. Errors about not being able to activate spaces that were already active can
be ignored, but errors in trying to activate the new swap space must be corrected in the /etc/fstab file before
rebooting, or there may be issues later.

After using the swapon -a command, verify that the swap partition or file is now activated by using the swapon -
s command. If the output includes the new swap partition, then the entry should be correct in the /etc/fstab file.

As mentioned previously, the only difference in a line that describes a swap partition versus a swap file is the first
field:

/var/swapfile swap swap defaults 0 0


Device Mount Point Filesystem Options dump fsck
Key Terms

/etc/fstab
A file that contains descriptive information about various file systems. The filesystems described in this file
will eventually be mounted by the mount command either manually or when the system is booted.
Section 21.5 | Section 21.6 | Section 21.10 | Section 21.11
/media/
The directory containing subdirectories used as mount points for removable media such as floppy disks,
cdroms, dvds, and flash drives.
Section 21.3
blkid
Command that can be used to determine the UUID value for a device.
Section 21.5
fsck
Command used to check and optionally repair one or more Linux file systems. If no filesystem is specified
with the command, fsck will check all filesystems in the /etc/fstab file by default.
Section 21.5
lsblk
Command that lists information about block devices.
Section 21.2
mount
Command used to tell the Linux kernel to attach a files system found on a device to a certain directory.
Section 21.2 | Section 21.3 | Section 21.5 | Section 21.6 | Section 21.7 | Section 21.8 | Section 21.10
umount
Command used to tell the Linux kernel to detach a file system found on a device from a certain directory.
Section 21.3 | Section 21.4
LAB 21
21.0 Introduction
In order to provide the functionality you need to apply these concepts, this VM may require a minute or two to
load.

The lab component for Chapters 20 and 21 is combined into this single lab, due to the nature of the material.

 In Chapter 20, we discussed creating partitions and filesystems.


 In Chapter 21, we demonstrated how to access the partitions and filesystems via mounting.

This lab combines these activities to avoid creating partitions twice.

As requirements for an active system grow and the number of users increases, it is often necessary to add
additional hard drive space. When you add a drive to the system, you will need to create one or more partitions.
Partitions are used to divide a hard drive into smaller chunks. Even if you don't want to divide a hard drive into
smaller chunks, you will need to at least create a single partition to make use of the drive.

Once you have a partition, you will need to place a filesystem on the partition. After you create the filesystem, you
will make the partition available via a mount point.

You may also need to add additional swap space to the system, either in the form of a swap partition or swap file.
Swap space is virtual memory that is used by the system when RAM becomes full.

21.1 Step 1
Log in to the system using the root account. When prompted, provide the root password:

root
netlab123
Ubuntu 18.04.2 LTS ubuntu tty1

ubuntu login: root


Password:
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-45-generic x86_64)

* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage

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.
root@ubuntu:~#

21.2 Step 2
Use the fdisk command to display the current partitions:

fdisk -l
root@ubuntu:~# fdisk -l
Disk /dev/sda: 9.8 GiB 10485760000 bytes, 20580000 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifierL 0x9f6a80de

Device Boot Start End Sectors Size Id Type


/dev/sda1 * 2048 20477951 20475904 9.8G 8e Linux LVM

Disk /dev/sdb: 4 GiB, 4294967296 bytes, 8388608 sectors


Units: sectors of 1 *512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

[ 816.422399] print_req_error: I/O error, dev fd0, sector 0

[ 816.446441] print_req_error: I/O error, dev fd0, sector 0

Disk /dev/mapper/ubuntu—vg-root: 9.3 GiB, 994469784 bytes, 19423232 sectors


Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/mapper/ubuntu—vg-swap_1: 512 MiB, 536870912 bytes, 1048576 sectors


Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

The following describes key components of the output:

Device
The specific partition that the row is describing. For example, /dev/sda1 is the first partition on the first
SATA hard drive.
Start The starting sector of the partition.
End The ending sector of the partition.
Blocks The size of the partition in blocks.
An identifier which is used to tell the kernel what type of filesystem should be placed on this partition. For
Id
example, the value 83 indicates that this partition should have an ext2, ext3, or etx4 filesystem type.
System
A human-readable name that indicates the type of filesystem the Id column refers to. For example, 83 is a
Linux filesystem.
21.3 Step 3
In this step, we will begin creating a new partition on the sdb drive. Execute the following command to start this
process:

fdisk /dev/sdb
root@ubuntu:~# fdisk /dev/sdb
Welcome to disk (util-linux 2.31.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table.


Created a new DOS disk label with disk identifier 0xdcd69338.

Command (m for help):

21.4 Step 4
At the Command prompt, type the m command to display the help section:

m
root@ubuntu:~# fdisk /dev/sdb
Welcome to disk (util-linux 2.31.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table.


Created a new DOS disk label with disk identifier 0xdcd69338.

Command (m for help): m


DOS (MBR)
a toggle a bootable flag
b edit nested BSD disklabel
c toggle the dos compatibility

Generic
d delete a partition
F list free unpartitioned space
l list know partition types
n add a new partition
p print the partition table
t change a partition type
v verify the partition table
i print information about a partition

Misc
m print this menu
u change display/entry units
x extra functionality (experts only)

Script
l load disk layout from sfdisk script file
0 dump disk layout to sfdisk script file

Save & Exit


w write table to disk and exit
q quit without saving changes
Create a new label
g create a new empty GPT partition table
G create a new empty SGI (IRIX) partition table
o create a new empty DOS partition table
s create a new empty Sun partition table

Command (m for help):

As you can see from the output of the m command, there are many things you can do with the fdisk utility. For this
lab, we are going to focus on just two things: creating partitions and changing partition types.

21.5 Step 5
At the Command prompt, type the p command to display the current partition table. The output should be the same
as when you previously executed the fdisk -l command:

p
Command (m for help): p
Disk /dev/sdb: 4 GiB, 4294967296 bytes, 8388608 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x97566fcf

Command (m for help):

While it is not critical for you to understand all of the output of this command, a brief summary of the more useful
output is provided below:

Disk /dev/sdb Disk name (/dev/sdb) and size in MB and bytes.


Units
Available units are sectors, a fixed unit of user accessible storage, which in this case is
512 bytes, the minimum unit of storage available to the system.
Sector size The total number of sectors is the most important since partitions are done by sectors.
(logical/physical) Note that a block and a sector are the same things, in this case.
This is somewhat useful because if you are trying to figure out how big an existing
partition is, you can take the number of sectors and multiply it by the value provided
I/O size
here. So, if a partition is 2,000 sectors in size and there are 512 bytes per sector, then the
partition is 1,024,000 bytes in size. An easier way to think of it is that 512 bytes is 0.5
MB. So, if a partition is 2,000 sectors in size, it is 1,000 MB in size (or approximately
1GB in size).
21.6 Step 6
At the Command prompt, type n to create a new partition:

n
Command (m for help): n
Partition type:
p primary (2 primary, 0 extended, 2 free)
e extended
Select (default p):

21.7 Step 7
At the Select prompt, type the e command to specify that you are going to create an extended partition. This will
allow you to create more partitions, called logical partitions, within the extended partition:

e
Command (m for help): n
Partition type:
p primary (2 primary, 0 extended, 2 free)
e extended
Select (default p): e
Partition number (1-4, default 1):

Recall that you can have up to 4 primary partitions. One of those can be an extended partition. Within the extended
partition, you can create more partitions called logical partitions. It is critical to understand this because if you use
all 4 primary partitions on a hard disk, then you will be unable to create any more partitions, even if there is
unpartitioned space available on the hard disk.

21.8 Step 8
At the Partition number prompt, type 2 to specify that you are going to use the second partition number. This
will result in a partition device name of /dev/sdb2:

2
Command (m for help): n
Partition type:
p primary (2 primary, 0 extended, 2 free)
e extended
Select (default p): e
Partition number (1-4, default 1): 2
First sector (2048-8388607, default 2048): _
Note that you never use extended partitions directly. In other words, you won't create filesystems on extended
partitions, and you won't mount them. Their sole purpose is to be a container for logical partitions.
21.9 Step 9
The next prompt asks for the block (or sector) this partition will start on. To accept the default value, simply press
the Enter key:

Enter
Command (m for help): n
Partition type:
p primary (2 primary, 0 extended, 2 free)
e extended
Select (default p): e
Partition number (1-4, default 2): 2
First sector (2048-8388607, default 2048):
Last sector, *sectors or +size(K,M,G,T,P) (2048-8388607, def

21.10 Step 10
The next prompt, Last sector… asks for where the new partition will end. You can either provide the last sector,
the number of sectors or a specific size (in units of kilobytes, megabytes, gigabytes, terabytes, or petabytes). The
default value is to use the rest of the drive, which normally is what you want to use for extended partitions. Press
the Enter key to accept the default value:

Enter
Command (m for help): n
Partition type:
p primary (2 primary, 0 extended, 2 free)
e extended
Select (default p): e
Partition number (1-4, default 2): 2
First sector (2048-8388607, default 2048):
Last sector, *sectors or +size(K,M,G,T,P) (2048-8388607, default 8388607):

Created a new partition 2 of type ‘Extended’ and of size 4 GiB.

Command (m for help):

If you wanted to specify the Last sector (think of this as the ending sector), you could just provide the number of
the sector. Unless you are going to use the rest of the drive, as you have done in this case, specifying the Last
sector is very rare. It is also fairly rare to specify +sectors (think of this as how many sectors you want to use for
this partition), as sector sizes are somewhat confusing.

In most cases, you specify the size of a partition by using +size (think of this as how much space you want to
allocate to the partition). A value of +2000K will create a 2000-kilobyte partition. A value of +200M will create a
200-megabyte partition. A value of +2G will create a 2-gigabyte partition.
21.11 Step 11
At the Command prompt, type the p command to display the current partition table. You should see your new
partition:

p
Command (m for help): p
Disk /dev/sdb: 4 GiB, 4294967296 bytes, 8388608 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifierL 0xdcd69338

Device Boot Start End Sectors Size Id Type


/dev/sdb2 2048 8388607 8386560 4G 5 Extended

Command (m for help):


It is always a good idea to check your work before saving the changes. The p command shows the current partition
table, but changes haven't been made to the hard drive yet.

21.12 Step 12
Now you can create a partition that you can later format with a filesystem and access via a directory by mounting
it. To create this new partition, first type n at the Command prompt:

n
Command (m for help): n
Allspace for primary partitions is in use.
Adding logical partition 5
First sector (4096-8388607, default 4096):

21.13 Step 13
Press the Enter key to accept the default for the First sector:

Enter
Command (m for help): n
Allspace for primary partitions is in use.
Adding logical partition 5
First sector (4096-8388607, default 4096):
21.14 Step 14
At the next prompt, enter +200M to create a 200MB partition:

+200M
Command (m for help): n
Command (m for help): n
Allspace for primary partitions is in use.
Adding logical partition 5
First sector (4096-8388607, default 4096):
Last sector, +sectors or +size{K,M,G} (4096-8388607, default 8388607): +200M

Created a new partition 5 of type ‘Linux’ and of size 200 MiB.


Command (m for help):
Don't forget to type the + character before 200M.

21.15 Step 15
Type p at the Command prompt to see your new partition:

p
Command (m for help): p

Disk /dev/sdb: 4 GiB, 4294967296 bytes, 8388608 sectors


Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xb2c87c2e

Device Boot Start End Sectors Size Id Type


/dev/sdb1 2048 8388607 8386560 4G 5 Extended
/dev/sdb5 4096 413695 409600 200M 83 Linux
Command (m for help):

21.16 Step 16
Type w at the Command prompt to save your new partitions:

Command (m for help): w


The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

root@ubuntu:~#
21.17 Step 17
The kernel needs to be instructed to re-read the partition table that is now on the hard drive and put it into memory.
You can tell that the kernel doesn't know about these new partitions yet because of the output of the following
command:

ls /dev/sd*
root@ubuntu:~# ls /dev/sd*
/dev/sda /dev/sda1 /dev/sdb /dev/sdb2 /dev/sdb5

When the kernel recognizes new partitions, this will result in new device files being automatically created in the
/dev directory. As you can see from the previous output, the kernel doesn't know about the two new partitions as
there isn't a /dev/sda2 or /dev/sda5 file.

1.18 Step 18
Reboot the system to have the kernel recognize the new partitions:

root@ubuntu:~# reboot
In some cases, you may be able to run a command, such as kpartx or partprobe, to have the kernel read the new
partition table. However, on this system, these commands do not exist.

21.19 Step 19
After the system finishes booting, log in to the system using the root account. When prompted, provide the root
password:

root
netlab123
Ubuntu 18.04.2 LTS ubuntu tty1

ubuntu login: root


Password:
Last login: Tue Jun 25 11:44:39 UTC 2019 on tty1
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-45-generic x86_64)

* Documentation: https://help.ubuntu.com/
* Management: https://landscapte.canonical.com
* Support: https://ubuntu.com/advantage

root@ubuntu:~#
21.20 Step 20
Then, verify the new files have been created in the /dev directory:

ls /dev/sd*
root@ubuntu:~# ls /dev/sd*
/dev/sda /dev/sda1 /dev/sdb /dev/sdb2 /dev/sdb5

21.21 Step 21
Execute the following command to create an ext4 partition on the /dev/sdb5 partition:

mkfs -t ext4 /dev/sdb5


root@ubuntu:~# mkfs -t ext4 /dev/sdb5
mke2fs 1.44.1 (24-Mar-2018)
Discarding device blocks: done
Creating filesystem with 204800 1k blocks and 51200 inodes
Filesystem UUID: 616fc3dc-7b69-403f-9532-289277460408
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729

Allocating group tables: done


Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: do

21.22 Step 22
Create a directory to use as a mount point for the new partition by using the mkdir command:

mkdir /data
root@ubuntu:~# mkdir /data
root@ubuntu:~#

Then, mount the new partition and verify that it mounted correctly by executing the mount commands as shown:

mount /dev/sdb5 /data


mount
21.23 Step 23
Use the nano editor to edit the /etc/fstab file:

nano /etc/fstab
root@ubuntu:~# nano /etc/fstab

Add the following line to the /etc/fstab file:

/dev/sdb5 /data ext4 defaults 1 1


# /etc/fstab: static file system information.
#
# Use „blkid‟ to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point> <type> <options> <dump> <pass>
/dev/mapper/ubuntu—vg-root / ext4 errors=remount-ro 0 1
/dev/mapper/ubuntu—vg-swap_1 none swap sw 0 0
/dev/fd0 /media/floppy0 auto rw,user,noauto,exec,utf8 0 0
/dev/sdb5 /data ext4 defaults 1 1

[ Read 10 lines ]
^G Get Help ^O Write Out ^W Where Is ^K Cut Text ^J Justify ^C Cur Pos M-U Undo
^X Exit ^R Read File ^\ Replace ^U Uncut Text ^T To Spell ^_ Go To Line M-E Redo

The /etc/fstab file will be used to mount filesystems automatically when the system reboots.

Type Ctrl+X to exit the nano editor. At the Save modified buffer? prompt, type the Y key.

Ctrl+x
y
Save modified buffer? (Answering "No" will DISCARD changes.)
Y Yes
N No ^C Cancel

Press Enter to save (write) the file.

Enter
File Name to Write: /etc/fstab_
^G Get Help M-D DOS Format M-A Append M-B Backup File
^C Cancel M-M Mac Format M-P Prepend ^T

21.24 Step 24
Verify this change with the following tail command:

tail -n 1 /etc/fstab
Note that the character after the -n option is a number 1, not a lowercase letter L.
root@ubuntu:~# tail -n 1 /etc/fstab
/dev/sdb5 /data ext4 defaults 1 1
If no output is displayed for the command above, verify that the /etc/fstabfile does not contain additional
empty lines and attempt the command again. Alternatively, you can increase the number of lines value for the -n
option to the tail command.

21.25 Step 25
When the system reboots, the /etc/fstab file will be used to mount filesystems automatically. However, you
don't want to reboot the system since any error in this file could cause the boot process to fail completely. To test
the new entry in this file, unmount the /data filesystem and remount it by only specifying the mount point:

umount /data
root@ubuntu:~# umount /data
mount /data
mount

When you only specify the mount point argument when executing the mount command, the command looks at the
/etc/fstab file for the rest of the information (the partition to mount and the mount options).

If you made a mistake in the new entry in the /etc/fstab file, you might get an error like the following:

root@ubuntu:~# mount /data


mount: can't find /data in /etc/fstab or /etc/mtab

If this happens, look at the /etc/fstab file, correct the error, and try to mount again.
21.26 Step 26
To create additional swap space, you either need to create a new partition or a new, large file. In the first example,
you will create a swap partition. Start by using the fdisk command as shown:

fdisk /dev/sdb
root@ubuntu:~# fdisk /dev/sdb

Welcome to fdisk (util-linux 2.31.1)


Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Command (m for help):

21.27 Step 27
Create a new partition by entering n at the Command prompt and use the rest of the information provided below:

n
Enter
Enter
Command (m for help): n
All space for primary partitions is in use.
Adding logical partition 6
First sector (415744-8388607, default 415744):
Last sector, +sectors or +size{K,M,G} (4415744-8388607, default 8388607):

Created a new partition 6 of type ‘Linux’ and of size 3.8 GiB.

Command (m for help):

21.28 Step 28
Change the partition type by entering the t command at the Command prompt and entering the values provided
below. When finished, enter the p command at the Command prompt to verify that your new partition has an Id of
82:

t
6
82
p
Command (m for help: t
Partition number (2,5,6, default 6): 6
Hex code (type L to list codes): 82
Changed system type of partition 6 to 82 (Linux swap / Solaris)
Command (m for help): p

Device Boot Start End Sectors Size Id Type


/dev/sdb1 2048 8388607 8386560 4G 5 Extended
/dev/sdb5 4096 413695 409600 200M 83 Linux
/dev/sdb6 415744 8388607 7972864 3.8G 82 Linux swap / Solaris
Command (m for help):
21.29 Step 29
Type w at the Command prompt to save your new partition:

w
Command (m for help: w
The partition table has been altered.
Syncing disks.

root@ubuntu~#

21.30 Step 30
Reboot the system to have the kernel recognize the new partitions:

reboot
root@ubuntu:~# reboot
In some cases, you may be able to run a command, such as the partprobe command, to have the kernel read the
new partition table. However, on this system, this command does not exist.

21.31 Step 31
After the system finishes booting, log in to the system using the root account. When prompted, provide the root
password:

root
netlab123
Ubuntu 18.04.2 LTS ubuntu tty1

ubuntu login: root


Password:
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-45-generic x86_64)

* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage

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.

root@ubuntu:~#
21.32 Step 32
Then, verify the new files have been created in the /dev directory:

ls /dev/sd*
root@ubuntu:~# ls /dev/sd*
/dev/sda /dev/sda1 /dev/sdb /devsdb2 /dev/sdb5 /dev/sdb6

21.33 Step 33
To format the partition as swap space with a label of myswap, execute the following mkswap command:

mkswap -L myswap /dev/sdb6


root@ubuntu:~# mkswap -L myswap /dev/sdb6
Setting up swapspace version 1, size = 3.8 GiB (4082102272 bytes)
LABEL=myswap, UUID=624b1bad-c835-44e5-3bc9f71a50a4

21.34 Step 34
Use the free command to see the current swap space for the system. Then, use the swapon command to add the
new swap partition to current swap space. Finally, use the free command again to verify the changes:

free
swapon -a /dev/sdb6
free
root@ubuntu:~# free
total used free shared buff/cache available
Mem: 492952 44148 364068 580 84736 436084
Swap: 524284 0 524284
root@ubuntu:~# swapon -a /dev/sdb6
root@ubuntu:~# free
total used free shared buff/cache available
Mem: 492952 45228 362620 580 84804 434708
Swap: 4510712 0 4510712
21.35 Step 35
Use the nano editor to edit the /etc/fstab file:

nano /etc/fstab
root@ubuntu:~# nano /etc/fstab

To have the new swap partition enabled automatically at boot, add the following line to the bottom of the
/etc/fstab file:

LABEL=myswap none swap sw 0 0


# /etc/fstab: static file system information.
#
# Use „blkid‟ to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point> <type> <options> <dump> <pass>
/dev/mapper/ubuntu—vg-root / ext4 errors=remount-ro 0 1
/dev/mapper/ubuntu—vg-swap_1 none swap sw 0 0
/dev/fd0 /media/floppy0 auto rw,user,noauto,exec,utf8 0 0
/dev/sdb5 /data ext4 defaults 1 1
LABEL=myswap none swap sw 0 0

^G Get Help ^O Write Out ^W Where Is ^K Cut Text ^J Justify ^C Cur Pos M-U Undo
^X Exit ^R Read File ^\ Replace ^U Uncut Text ^T To Spell ^_ Go To Line M-E Redo

Type Ctrl+X to exit the nano editor. At the Save modified buffer? prompt, type the Y key.

Ctrl+X
Y
Save modified buffer? (Answering “No” will DISCARD changes.)
Y Yes
N No ^C Cancel

Press Enter to save (write) the file.

Enter
File Name to Write: /etc/fstab_
^G Get Help M-D DOS Format M-A Append M-B Backup File
^C Cancel M-M Mac Format M-P Prepend ^T

21.36 Step 36
Verify this change with the following tail command:

tail -n 1 /etc/fstab
root@ubuntu:~# tail -n 1 /etc/fstab
LABEL=myswap none swap sw 0 0
21.37 Step 37
To test the new setting in the /etc/fstab file, you could reboot the system. However, if you made any errors, the
system may end up being unbootable. A better solution for testing the new entry in the /etc/fstab file is to
execute the swapon -a after first removing the partition from swap space. Execute the following commands:

swapon -s
swapoff /dev/sdb6
swapon -s
swapon -a
swapon -s
root@ubuntu:~# swapon -s
Filename Type Size Used Priority
/dev/dm-1 partition 524284 0 -2
/dev/sdb6 partition 3986428 0 -3
root@ubuntu:~# swapoff /dev/sdb6
root@ubuntu:~# swapon -s
Filename Type Size Used Priority
/dev/dm-1 partition 524284 0 -2
root@ubuntu:~# swapon -a
root@ubuntu:~# swapon -s
Filename Type Size Used Priority
/dev/dm-1 partition 524284 0 -2
/dev/sdb6 partition 3986428 0 -3

In the commands above, the swapon command used with the -s option demonstrates which swap spaces are
currently being used, while the swapon command used with the -a option enables all swap devices that are listed in
the /etc/fstab file.

If there were any errors in the line that you just added to this file, the swapon -a command would have produced
output error messages. For example:

root@ubuntu:~# tail -n 1 /etc/fstab


LABEL=myyswap none swap sw 0 0
root@ubuntu:~# swapon -a
swapon: cannot find the device for LABEL=myyswap

Notice that the value for LABEL was mistyped (it should only have one y, not two). If you get an error message
when executing the swapon -a command, review the entry in the /etc/fstab file, correct it and try to execute the
swapon -a command again.
21.38 Step 38
To create a new swap file, first, create a large file with the dd command. To determine a good location for this new
file, run the df -h command to see which partition has enough space to hold the swap file:

df -h
root@ubuntu:~# df -h
Filesystem Size Used Avail Use% Mounted on
udev 213M 0 213M 0% /dev
tmpfs 49M 592K 48M 2% /run
/dev/mapper/ubuntu—vg-root 9.1G 1.5G 7.1G 18% /
tmpfs 241M 0 241M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 241M 0 241M 0% /sys/fs/cgroup
/dev/sdb5 190M 1.6M 175M 1% /data
tmpfs 49M 0 49M 0% /run/user

21.39 Step 39
In this case, the / filesystem has plenty of space. Create a large file with the following dd command in the /var
directory (which is part of the / partition):

dd if=/dev/zero of=/var/swapfile bs=1M count=100


root@ubuntu:~# dd if=/dev/zero of=/var/swapfile bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100MiB) 0.118785 s, 858MB/s

21.40 Step 40
The result should be a file that is approximately 100MB in size. Confirm this by executing the following
command:

ls -lh /var/swapfile
root@localhost:~# ls -lh /var/swapfile
-rw-r--r-- 1 root root 100M Jun 26 12:40 /var/swapfile
21.41 Step 41
Convert this file into a swap file by executing the following command:

mkswap /var/swapfile
root@ubuntu:~# mkswap /var/swapfile
mkswap: /var/swapfile: insecure permissions 0664, 0660 suggested.
Setting up swap space version 1, size = 100 MiB (104853504 bytes)
No label, UUID=fe0dfcb8-e9de-4305-bd8f-8f28c26ff997

21.42 Step 42
Add the swap file to the current swap space and then confirm by executing the following commands:

swapon /var/swapfile
swapon -s
root@ubuntu:~# swapon /var/swapfile
swapon: /var/swapfile: insecure permissions 0644, 0600 suggested.
root@ubuntu:~# swapon -s
Filename Type Size Used Priority
/dev/dm-1 partition 524284 0 -2
/dev/sdb6 partition 3986428 0 -3
/var/swapfile file 102396 0
21.43 Step 43
Use the nano editor to edit the /etc/fstab file:

nano /etc/fstab
root@ubuntu:~# nano /etc/fstab

To have the new swap file enabled automatically at boot, add the following line to the bottom of the /etc/fstab
file:

/var/swapfile none swap sw 0 0


# /etc/fstab: static file system information.
#
# Use „blkid‟ to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point> <type> <options> <dump> <pass>
/dev/mapper/ubuntu—vg-root / ext4 errors=remount-ro 0 1
/dev/mapper/ubuntu—vg-swap_1 none swap sw 0 0
/dev/fd0 /media/floppy0 auto rw,user,noauto,exec,utf8 0 0
/dev/sdb5 /data ext4 defaults 1 1
LABEL=myswap none swap sw 0 0
/var/swapfile none swap sw 0 0

^G Get Help ^O Write Out ^W Where Is ^K Cut Text ^J Justify ^C Cur Pos M-U Undo
^X Exit ^R Read File ^\ Replace ^U Uncut Text ^T To Spell ^_ Go To Line M-E Redo

Type Ctrl+X to exit the nano editor. At the Save modified buffer? prompt, type the Y key.

Ctrl+X
Y
Save modified buffer? (Answering “No” will DISCARD changes.)
Y Yes
N No ^C Cancel

Press Enter to save (write) the file.

Enter
File Name to Write: /etc/fstab_
^G Get Help M-D DOS Format M-A Append M-B Backup File
^C Cancel M-M Mac Format M-P Prepend ^T
21.44 Step 44
Verify this change with the following tail command:

tail -n 1 /etc/fstab
root@ubuntu:~# tail -n 1 /etc/fstab
/var/swapfile none swap sw 0 0

21.45 Step 45
To test the new setting in the /etc/fstab file, you could reboot the system. However, if you made any errors, the
system may end up being unbootable. A better solution for testing the new entry in the /etc/fstab file is to
execute the swapon -a command after first removing the swap file from swap space. Execute the following
commands to see how this is accomplished:

swapon -s
swapoff /var/swapfile
swapon -s
swapon -a
swapon -s
root@ubuntu:~# swapon -s
Filename Type Size Used Priority
/dev/dm-1 partition 524284 0 -2
/dev/sdb6 partition 3986428 0 -3
/var/swapfile file 102396 0 -4
root@ubuntu:~# swapoff /var/swapfile
root@ubuntu:~# swapon -s
Filename Type Size Used Priority
/dev/dm-1 partition 524284 0 -2
/dev/sdb6 partition 3986428 0 -3
root@ubuntu:~# swapon -a
swapon: /var/swapfile: insecure permissions 0644, 0600 suggested.
root@ubuntu:~# swapon -s
Filename Type Size Used Priority
/dev/dm-1 partition 524284 0 -2
/dev/sdb6 partition 3986428 0 -3
/var/swapfile file 102396 0 -4
Chapter 22: Maintaining Integrity

22.1 Introduction
Filesystems must be maintained in order to ensure that they continue to function correctly and that the system can
continue to run. This section discusses filesystem administration, as well as maintenance and tuning.

In order to maintain the integrity of a filesystem, it is vital to monitor it and to follow proper procedures in
managing the system. Under normal circumstances, filesystems will function properly with no need for
intervention, but in the event that a problem arises, it is important to know how to discover the source of the
problem and how to fix it.

22.2 Filesystem Issues


Before discussing filesystem utilities in depth, it is important to discuss the most common causes of filesystem
damage. For example, one of the easiest ways to damage a filesystem is to shut down the system improperly. You
should never just flip the switch on a surge suppressor or pull the plug from its power source unless the system will
not respond to all other attempts to shut it down properly. In many cases, just pressing the power button once will
cause many systems to shut down gracefully (this depends on the hardware and BIOS settings of the computer).

When using a graphical desktop environment, an icon may be available to begin the shutdown process. For
example, within the Gnome Desktop Environment, click on the System menu and then choose Shut Down; a dialog
similar to the following will be displayed:

There are also a few commands available to shut down the Linux system from the command line. For example, the
following init commands and user commands are available.
Init Command Purpose User Command
init 0 Shut the system off halt
init 6 Restart the system reboot

Be aware that the init commands require root privileges, whereas the user commands do not if the user is logged
in locally and there are no other users logged into the system. Also, discretion is recommended when using the
init command as it is abrupt and can cause unintended consequences. In some cases, it is considered more
appropriate to use the shutdown -h, shutdown -r, poweroff, or even reboot commands, many of which are
links to each other.

Note

Linux distributions that have replaced the traditional SysVinit daemon with systemd use the systemct1 command
to affect the state of the system and services running. To restart a system using systemd, execute the systemct1
reboot command. To shut down a system using systemd, execute using the systemctl poweroff command.

22.3 Monitoring Disk Info


Two storage-related statistics that should be monitored closely to ensure a system will continue to run correctly are
free data block space and free inodes. The df command can help monitor both of these important numbers.

Data block space is used to store the contents of a file (the file's data). If data block space is exhausted within a
filesystem, it will not be possible to add any new content to either new or existing files.

By default, the df command without any option or arguments will display filesystems usage using 1K (1024 bytes)
data block size:

sysadmin@localhost:~$ df
Filesystem 1K-blocks Used Available Use% Mounted on
overlay 3711914792 119199908 3404137348 4% /
tmpfs 66007320 0 66007320 0% /dev
tmpfs 66007320 0 66007320 0% /sys/fs/cgroup
/dev/sda2 3711914792 119199908 3404137348 4% /etc/hosts
shm 65536 0 65536 0% /dev/shm

When executed with the -h option, the output of the df command is displayed in human-readable units such as
MiB and GiB:

sysadmin@localhost:~$ df -h
Filesystem Size Used Avail Use% Mounted on
overlay 3.5T 114G 3.2T 4% /
tmpfs 63G 0 63G 0% /dev
tmpfs 63G 0 63G 0% /sys/fs/cgroup
/dev/sda2 3.5T 114G 3.2T 4% /etc/hosts
shm 64M 0 64M 0% /dev/shm

Consider This

Additional options will yield even more interesting and helpful information, try adding a -T to the df command to
see the filesystem Type added as a column to the output:

sysadmin@localhost:~$ df -hT
Filesystem Type Size Used Avail Use% Mounted on
overlay overlay 3.5T 114G 3.2T 4% /
tmpfs tmpfs 63G 0 63G 0% /dev
tmpfs tmpfs 63G 0 63G 0% /sys/fs/cgroup
/dev/sda2 ext4 3.5T 114G 3.2T 4% /etc/hosts
shm tmpfs 64M 0 64M 0% /dev/shm
Each file created in a filesystem is assigned a unique identifier by the filesystem. This identifier is known as an
inode and there is a fixed number of them available when using ext2/ext3/ext4.In other words, if a filesystem has
only 10,000 inodes, only 10,000 files can be stored in that filesystem.

Inodes are important because in order to create a file, an inode is needed to store the metadata (information like
permissions, timestamps, etc.) about that file. In fact, the inode stores everything about the file except its name and
its contents.

Consider This

Inodes are limited to a set amount at filesystem creation in the ext2/ext3/ext4 family of filesystems, but in many
other filesystems, inodes are generated as needed, examples include JFS and XFS.

To determine how many files have been created and how many inodes are still available for a filesystem, use the -
i option to the df command:

sysadmin@localhost:~$ df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
overlay 235708416 502951 235205465 1% /
tmpfs 16501830 19 16501811 1% /dev
tmpfs 16501830 14 16501816 1% /sys/fs/cgroup
/dev/sda2 235708416 502951 235205465 1% /etc/hosts
shm 16501830 1 16501829 1% /dev/shm

The number of inodes is determined when the filesystem is created. The default technique is to use a ratio that
depends on how many data blocks the filesystem contains, so larger filesystems will contain more inodes. The
options that can be used to affect this ratio will be discussed later.

Be sure to view the output of the df command carefully to find filesystems that are getting low on data block space
or inodes. If a filesystem is getting low, take steps like moving some files to another filesystem with more
resources or removing files that are unnecessary.
22.4 The du Command
Consider a scenario where a filesystem seems to be running low on free data blocks. Investigate the amount of free
disk space or disk blocks using a tool such as the df command. One of the next logical steps to address this
concern would be to figure out what directory or subdirectory within that filesystem might be using the most data
blocks. The directory usage du command will report the size of files and directories'; this can be helpful for finding
the largest ones:

The default output of the du command shows just two columns of information: the file size and the path name for
the file. The du command is automatically recursive, so it will normally process not only the current directory but
also all of its directories.

An effective way to find the largest files within the specified directories is to pipe the output to the sort command
with the -n option, so that the output will be sorted from smallest to largest. For example, executing the du | sort
-n command in a user's home directory would result in output like the following, placing the largest files at the
bottom of the output:

sysadmin@localhost:~$ du | sort -n | tail -10


4 ./Pictures
4 ./Public
4 ./Templates
4 ./Videos
8 ./Documents/School/Art
8 ./Documents/School/Engineering
8 ./Documents/School/Math
28 ./Documents/School
1128 ./Documents
1180 .
Warning

Keep in mind that errors will likely result if the du command is run outside of a regular user's own home directory
or the /tmp and /var/tmp directories.

Two options used often with the du command are the human-readable -h option and the summary -s option to
only display a summary of the entire directory. For example, executing the command below would display a
human-readable summary of how much space is used by both the /bin and the /usr/bin directory.

sysadmin@localhost:~$ du -sh /bin /user/bin


6.6M /bin
38M /usr/bin

A couple of other options to the du command that can be useful include the --max-depth and --exclude options.

To limit the depth of how recursive the du command will be, provide a numerical argument to the --max-depth
option to indicate how many directories deep to display.

sysadmin@localhost:~$ du Documents
8 Documents/School/Math
8 Documents/School/Engineering
8 Documents/School/Art
28 Documents/School
4 Documents/Work
1128 Documents
sysadmin@localhost:~$ du --max-depth=1 Documents
28 Documents/School
4 Documents/Work
1128 Documents

If there are files or directories that shouldn't be included, use one or more --exclude options. Glob characters can
be used as well to form the pattern to be used by the --exclude option.

sysadmin@localhost:~$ du --exclude=School Documents


4 Documents/Work
1100 Documents

As an example of using these both options, analyze the output of the du command in the following example. To
determine the size of each directory that is a direct child of the /usr directory, the --max-depth=1 option is used.

The following command will be run as a regular user, which means accessing the /usr/lib/audit directory will
result in an error as regular users do not have access to this directory. The --exclude=/usr/lib/audit option
avoids this error

sysadmin@localhost:~$ du -h --max-depth=1 --exclude=/usr/lib/audit


4.0K ./Public
4.0K ./Downloads
4.0K ./Pictures
4.0K ./Videos
4.0K ./Templates
4.0K ./Desktop
4.0K ./Music
1.2M ./Documents
4.0K ./.cache
1.2M .

22.5 The tune2fs Command


The tune2fs command can view and change some of the settings for ext2, ext3, and ext4 filesystems. Generally,
this command is considered safe, but to avoid taking risks, a backup of the filesystem should be made before using
the command.

The tune2fs command has a number of options. Below are a few examples of common options that can be used
on a filesystem.

By default, each filesystem will have a full system check during the boot process either every 180 days or after 30
mounts, whichever comes first. Unfortunately, this slows the boot process, especially if all filesystems are checked
during a single boot. Automatic filesystem checking can be disabled by executing the following:

The following examples may not match the output in our virtual environment.
root@localhost:~# tune2fs -c0 -i0 /dev/sdb1

In the example above, the -c option will change the maximum number of times that a filesystem may be mounted
before it is required to have a full filesystem check. The default value of 30 times has been disabled by setting the
value to 0. The -i option will change the maximum time interval between when a filesystem is forced to have a
full filesystem check. This default value of 180 days has been disabled by setting the interval to 0.

To automatically have the acl and user_xattr mount options apply any time filesystem is mounted, execute the
following command:
root@localhost:~# tune2fs -o acl,user_xattr /dev/sdb1

The -o option in the command above specifies the default mount options. By default, the Red Hat derived
distributions specify that acl and user_xattr options are added to filesystems created during installation. Note
that when applying multiple options, they need to be comma separated.

Finally, to verify the changes have been saved, list the superblock information for the filesystem by using the -1
option:

root@localhost:~# tune2fs -1 /dev/sdb1

To summarize, the following is a table of options available for tune2fsto tune a ext2, ext3 or ext4 filesystem:

Option Effect
-1 List the superblock information for a filesystem.
-c
Change the maximum number of times that a filesystem may be mounted before it is required to have a full
filesystem check. The default value is normally 30 times. This can be disabled by setting the value to 0.
-i
Change the maximum time interval between when a filesystem is forced to have a full filesystem check.
The default value is 180, meaning 180 days. This can be disabled by setting the interval to 0.
-j Create a journal file for an ext2 filesystem, allowing it to be mounted as an ext3 or ext2 filesystem.
-m
Specify the percentage of space to be reserved for the root user or privileged processes. The default value
of 5% is often unnecessarily large for large filesystems.
Specify default mount options. By default, the RedHat derived distributions specify that acl and
-o user_xattroptions are added to filesystems created during installation. When applying multiple options,
they need to be comma separated.
Consider this

There are filesystem settings that the tune2fscommand cannot change and that have to be set at the time the
filesystem is created. For the ext2, ext3, and ext4 filesystems, the following table lists the mke2fs command
options that cannot be changed after the filesystem is created:

Option Effect
Allows the block size to be specified. Valid block sizes are 1024, 2048, or 4096 bytes (some systems allow
-b
a block size of 8192). If the "wrong" block size is used, the filesystem may run out of data blocks before
running out of inodes. If the average file size is smaller than 4 KiB, it may be beneficial to use a smaller
block size closer to the average file size.
Allows the size of an inode to be specified. By default, mke2fs will make an inode size of 128 bytes. If the
-I system uses SELinux or SambaV4, it may be beneficial to set this size to 256 bytes to allow space
extended attributes that SELinux and sambaV4 use.
Allows a bytes/inode ratio to be specified. To avoid either running out of data blocks while still having
-i inodes, or vice versa, set a ratio that will be close to the average file size. As each file requires at least one
inode to store its meta-information, this is a critical value.
-N
If the size of the average file is unknown, but the number of files required is known, use this option to
specify exactly how many inodes to create
Key Term
df
Command used to report file system disk space usage. df can be used with a FILE name agrument, if no
FILE name is given, the sapce available on all urrently mounted file systems will be reported.
Section 22.3
du
Command used to estimate file usage on a disk. du will summarize disk usage of each FILE, recursively for
directories.
Section 22.4
tune2fs
Command that allows a system administrator to adjust various tunable file system parameters such as
mount count and maximum mount counts before a file system check needs completed. tune2fs works with
the ext2/3/4 family of file systems.
LAB 22
22.0 Introduction
In order to provide the functionality you need to apply these concepts, this VM may require a minute or two to
load.

In this lab, you will explore commands that provide you with useful information regarding the directory structure
and filesystems. These commands are critical to maintaining the stability of the system.

Knowing how to monitor the usage of the filesystems allows you to make sure space is available for both the OS
and users. Determining which directories are using the most space provides you with the knowledge to fix issues
related to filesystems that become "full".

Understanding filesystem attributes and knowing how to view and modify these attributes allows you to fine-tune
the system, so it will perform better.

22.1 Step 1
Log in to the system using the root account. When prompted, provide the root password:

root
netlab123
CentOS Linux 7 (Core)
Kernel 3.10.0-957.el7.x86_64 on an x86_64

Centos login: root


Password:
[root@centos~]#

22.2 Step 2
Execute the following command to list filesystem disk space usage details:

df
[root@centos~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/VolGroup-lv_root 3997376 1020524 2750756 28% /
devtmpfs 237476 0 237476 0% /dev
tmpfs 249412 0 249412 0% /dev/shm
tmpfs 249412 4532 244880 2% /run
tmpfs 249412 0 249412 0% /sys/fs/cgroup
/dev/sda1 499656 102788 360172 23% /boot
tmpfs 49884 0 49884 0% /run/user/0

Sizes are given in 1K (kilobyte) block sizes. Knowing how to view this information is useful because a filesystem
that is full can cause problems, as users and system processes will be unable to write to the filesystem.
22.3 Step 3
To view the output of the df command in more human-readable format, use the -h option:

df -h
[root@centos~]# df -h
Filesystem Size Used Available Use% Mounted on
/dev/mapper/VolGroup-lv_root 3.9G 997M 2.7G 28% /
devtmpfs 232M 0 232M 0% /dev
tmpfs 244M 0 244M 0% /dev/shm
tmpfs 244M 4.5M 240M 2% /run
tmpfs 244M 0 244M 0% /sys/fs/cgroup
/dev/sda1 488M 101M 352M 23% /boot
tmpfs 49M 0 49M 0% /run/user/0

22.4 Step 4
To view filesystem inode usage, use the -i option:

df -i
[root@centos~]# df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/mapper/VolGroup-lv_root 262144 27045 235099 11% /
devtmpfs 59369 358 59011 1% /dev
tmpfs 62353 1 62352 1% /dev/shm
tmpfs 62353 430 61923 1% /run
tmpfs 62353 16 62337 1% /sys/fs/cgroup
/dev/sda1 32768 334 32434 2% /boot
tmpfs 62353 1 62352 1% /run/user/0
Recall that each file needs an inode. Therefore, if a filesystem has 1,310,720 inodes then this also represents the
maximum number of files that can reside on that filesystem.

22.5 Step 5
To determine which directories are using the most disk space, use the du command. For example, execute the
following command to determine how much space the /usr directory is using:

du /usr | more
[root@centos~]# du /usr | more
Type Q to exit the more command:

22.6 Step 6
The output of the du command can be immense. To see just a summary of how much space a specific directory
structure is using, use the -s option:

du -s /usr
[root@centos~]# du -s /usr
914376 /usr

22.7 Step 7
The output is given in block sizes (1 block = 1 kilobyte, in this case). To see a more human-readable value, use the
-h option:

du -sh /usr
[root@centos~]# du -sh /usr
893M /usr
22.8 Step 8
The du command is useful because once you discover that a filesystem is close to becoming full, you need to
determine where the largest chunks of files are. A common way of doing this is to see which of the directories
under the root directory are using the most space. Execute the following command to see a demonstration:

du -sh /*
[root@centos~]# du -sh /*
0 /bin
100M /boot
0 /dev
33M /etc
20K /home
0 /lib
0 /lib64
16K /lost+found
4.0K /media
4.0K /mnt
4.0K /opt
Some output has been omitted in the example above for brevity.

22.9 Step 9
Execute the following command to find the largest files in the /etc directory structure:

du /etc | sort -nr | head


[root@centos~]# du /etc | sort -nr | head
33636 /etc
21020 /etc/selinux
21000 /etc/selinux/targeted
15220 /etc/selinux/targeted/active
10996 /etc/selinux/targeted/active/modules
10988 /etc/selinux/targeted/active/modules/100
7772 /etc/udev
3812 /etc/selinux/targeted/policy
1932 /etc/selinux/targeted/contexts
1832 /etc/selinux/targeted/contexts/files
22.10 Step 10
In addition to displaying file space by filesystem or directory structure, you also want to know how to display other
information about filesystems. Execute the following command to display filesystem information:

dumpe2fs /dev/sda1 | head


[root@centos~]# dumpe2fs /dev/sda1 | head
dumpe2fs 1.42.9 (28-Dec-2013)
Filesystem volume name: <none>
Last mounted on: /boot
Filesystem UUID: 5dac1ba0-cdbc-4ba2-99dd-17f298456819
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal ext_attr resize_inode dir_index filetype
needs_recovery extent 64bit flex_bg sparse_super large_file huge_file uninit_bg dir_nlink
extra_isize
Filesystem fags: signed_directory_hash
Default mount options: user_xattr acl
Filesystem state: clean
Errors behavior: Continue

22.11 Step 11
This output contains very useful filesystem information. For example, to display the number of Free inodes
(every file needs an inode, so the number of Free inodes indicates how many more files you can place on this
filesystem), execute the following command:

dumpe2fs /dev/sda1 | grep “Free inodes” | head -1


Note that the option after the head command is a number 1, not a lower-case letter L.
root@centos:~# dumpe2fs /dev/sda1 | grep "Free inodes" | head -1
dumpe2fs 1.42.9 (28-Dec-2013)
Free inodes: 32434
Once a filesystem has been created, the number of total inodes is set in stone.

22.12 Step 12
To see the default mount options of the filesystem, execute the following command:

dumpe2fs /dev/sda1 | grep “Default mount options”


[root@centos~]# dumpe2fs /dev/sda1 | grep "Default mount options"
dumpe2fs 1.42.9 (28-Dec-2013)
Default mount options: user_xattr acl
The default mount options are specified when the filesystem is initially created. Any additional mount options are
specified in the /etc/fstab file.
22.13 Step 13
Most of a filesystem's attributes can only be specified when the filesystem is created. For example, the number of
inodes cannot be changed later. However, the reserved block space can be changed. Execute the following
command to see the current value of the reserved block count:

dumpe2fs /dev/sda1 | grep "Reserved block count"


[root@centos~]# dumpe2fs /dev/sda1 | grep "Reserved block count"
dumpe2fs 1.42.9 (28-Dec-2013)
Reserved block count: 6553

The reserved block count is how much space on the filesystem is reserved for the root account or processes that run
as the root account (typically, system processes).

On some filesystems, such as /home, you may want to reduce this value since the root user doesn't use that
filesystem often. On other filesystems, you may find the need to increase the reserved block count.

22.14 Step 14
To change the reserved block count, you change the percentage of the filesystem that is reserved. This reserved
amount can only be used by the root account and is set to 5% by default. Execute the following commands to
change this value and confirm the change:

dumpe2fs /dev/sda1 | grep "Reserved block count"


tune2fs -m 10 /dev/sda1
dumpe2fs /dev/sda1 | grep "Reserved block count"
[root@centos~]# dumpe2fs /dev/sda1 | grep "Reserved block count"
dumpe2fs 1.42.9 (28-Dec-2013)
Reserved block count: 6553
[root@centos~]# tune2fs -m 10 /dev/sda1
tune2fs 1.42.9 (28-Dec-2013)
Setting reserved blocks percentage to 10% (13107 blocks)
[root@centos~]# dumpe2fs /dev/sda1 | grep "Reserved block count"
dumpe2fs 1.42.9 (28-Dec-2013)
Reserved block count: 13107
Chapter 23: Fixing Filesystems

23.1 Introduction
Filesystems and the data on them are extremely important components of any system, so knowing how to fix issues
when they occur is equally critical. This is one of the main reasons why information that is stored on a filesystem
should be copied to multiple locations, or secured via more traditional backups. It also highlights how important it
is to understand how to fix a filesystem, should it break.

Filesystems may require repair for a number of reasons:

 Sudden power outage resulting in unclean dismount of partitions. An uninterruptible power supply (UPS) is
typically used to prevent this.
 Ejecting removable read/write media, such as a USB key or flash drive, before a clean dismount has
occurred (i.e., removing the media before issuing the umount command).
 Loss of network connectivity between a host and a partition that is mounted as a network file system (NFS).
 Normal wear leading to corrupted disk sectors and gradual disk failure.
 Electrical surges or exposure to magnetic fields.
 Malware.

23.2 The fsck Command


The fsck command is used to check filesystems for consistency issues and to repair those issues when found. The
fsck command has some similarities to the mkfs command. First of all, it is a generic tool for use with filesystems;
its purpose is to check filesystems for errors and attempt to repair them. Second, fsck is actually a front end for
the various filesystem checkers, meaning it will call the appropriate back end command, like the e2fsck command,
based upon the filesystem type.

The files that link the front end to the back end are named by patterns like the fsck.FILESYSTEM-TYPE pattern,
such as fsck.ext4 or fsck.vfat. These files between the front and back end commands can be a great way to
find documentation.

For example, to discover the actual filesystem-specific command that is used to check vfat filesystems, execute the
man fsck.vfat command. This will display the man page for the real back end command for checking vfat
filesystems, which is the dosfsck command. Likewise, viewing the man page for fsck.ext4 displays the e2fsck
command used for checking ext2, ext3, and ext4 filesystems.

It is not necessary to know which back end to use. Simply execute the fsck command with either the pathname for
the filesystem or its mount point. The fsck command will determine the filesystem-specific program to call based
upon the filesystem type from the entry in the /etc/fstab file. If the filesystem does not have an entry in the
/etc/fstab file, then the -t option can be used with the fsck command to specify the filesystem type.
Warnings About the fsck Command

While this tool is designed to check and fix filesystems, it can actually damage filesystems too! The fsck utility is
not designed to be executed on currently used filesystems (systems that are already mounted). If the fsck
command is run on a currently mounted filesystem, the following error will appear:

Note

The following example may not match the output in our virtual environment.

root@localhost:~# fsck /dev/sda1


fsck from util-linux-ng 2.17.2

e2fsck 1.41.12 (17-May-2010)


/dev/sda1 is mounted.

WARNING!! The filesystem is mounted. If you continue you ***WILL*** cause ***SEVERE***
filesystem damage.

Do you really want to continue (y/n)? no

check aborted

In this case, definitely type n for no. Keep in mind, if the filesystem is already mounted, then it doesn't need to be
checked. The very fact that it is mounted means it is working correctly.

A backup policy should be implemented to facilitate recovery of important files in the event they are lost or
corrupted. It is all too common that backups are not considered until it is too late.

Consider This

When it comes to backups, late may be better than never. If a filesystem is damaged and can't be mounted, consider
making a backup of it with the dd command before trying to fix it with the fsck command. That way, if the fix that
the fsck command performs actually makes things worse than they were originally, it is still possible to revert
back to the condition preserved in the backup.

One of the more useful options for the fsck command is the -y option, which will cause fsck to assume a yes
response to all prompts that it would normally make. Using this option may prevent hours typing the letter y in
response to questions from the tool like, Would you like to fix this?

Since the root filesystem cannot be unmounted while the system is running, it can be difficult to check. One
approach to checking the root filesystem, is to boot up another Linux operating system with a different root
filesystem. A common approach is to download and use a Live CD-ROM, DVD, or USB, which are bootable
Linux operating systems that fit on those media.

Another non-interactive approach is to force a filesystem check to occur, by executing the touch /forcefsck
command as the root user. If this file exists at boot time, then the fsck command is executed on all filesystems in
the /etc/fstab file that have a non-zero value for the FSCK column. After completion, the /forcefsck file will
be removed, and the timestamp of the /.autofsck file will be updated to the time when the check finished.
For partitions that can be unmounted while the system is running, the fsck command can be started interactively to
perform the check. For example:

Note

The following examples may not match the output in our virtual environment.

root@localhost:~# mount | grep /data


/dev/sdb1 on /data type ext4 (rw)
root@localhost:~# umount /data
root@localhost:~# fsck /dev/sdb1
fsck from util-linux-ng 2.17.2
e2fsck 1.41.12 (17-May-2010)
/dev/sdb1: clean, 11/12824 files, 6532/51200 blocks

Note that the fsck command did not perform a filesystem check in the previous example. Since the filesystem was
cleanly unmounted (which would also happen during a normal system shutdown or reboot), the state of the
filesystem was set to clean. The fsck command doesn't perform any checks when the filesystem state is clean.

A filesystem check can be forced by using the -f option:

root@localhost:~# fsck -f /dev/sdb1


fsck from util-linux-ng 2.17.2
e2fsck 1.41.12 (17-May-2010)
Pass 1: Checking indoors, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/sdb1: 11/12824 files (9.1% non-contiguous), 6532/51200 blocks

When a partition has a problem, attempting to mount it may result in an error message like this:

mount: you must specify the filesystem type

Normally, the mount command will read the first block of the filesystem (the superblock) where the information
about the filesystem type is kept. When a superblock is damaged, the mount command is unable to read that
information.

In this case, use the fsck command to fix the filesystem. The output may look something like the following:

fsck from util-linux-ng 2.17.2

e2fsck 1.41.12 (17-May-2010)

fsck.ext2: Superblock invalid, trying backup blocks...


mydata was not cleanly unmounted, check forced.
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information

mydata: ***** FILE SYSTEM WAS MODIFIED *****


mydata: 11/25688 files (0.0% non-contiguous), 4800/102400 blocks

Notice the highlighted text of the output shows that the command tried backup blocks. The fsck command will
often be able to find a backup copy of the superblock that was created at the time the filesystem was last modified.
23.3 The e2fsck Command
The e2fsck command is the filesystem checker called by fsck for ext2, ext3, and ext4 filesystems. There are
options that can be used with the e2fsck command that aren't documented in the man page for the fsck command.
These filesystem-specific options can be used directly with the e2fsck command or with the fsck command
(which will pass the options to thee2fsck command).

For example, the fsck command may require the exact location of a backup superblock. The superblock is a
critical component to the filesystem, and when corrupted, it is difficult to recover. The backup superblocks are used
by the fsck command to fix a corrupted superblock.

If custom settings were used when creating a filesystem, the backup superblocks may not be in a standard location.
In that case, the output of the mkfs command should be documented because that output includes the location of
the backup superblocks. These backup superblocks may be located by using the dumpe2fs command:

Note

The following examples may not match the output in our virtual environment.

root@localhost:~# dumpe2fs /dev/sdb1 | grep superblock


dumpe2fs 1.41.12 (17-May-2010)
Primary superblock at 1, Group descriptors at 2-2
Backup superblock at 8193, Group descriptors at 8194-8194
Backup superblock at 24577, Group descriptors at 24578-24578
Backup superblock at 40961, Group descriptors at 40962-40962

Use the -b option with the e2fsck command to specify a backup when the primary superblock has been corrupted.
For example:

root@localhost:~# e2fsck -b 8193 /dev/sdb1

The fsck command could also be used with the same option, as it will pass this option on to the e2fsck command:

root@localhost:~# fsck -b 8193 /dev/sdb1

There are a couple of other options to automate the e2fsck command. The -n option assumes that the input for
every prompt is no. The -n option can be useful when running the command to test for possible problems, but
opting not to fix them at this time. The output can be captured for further analysis and discussion, perhaps with
another administrator.

23.4 The lost+found Directory


In most cases, after running the fsck command, the fixed filesystem is mounted and no further action is required.
However, if the fsck command produces any unreferenced file errors, it may be prudent to look inside the
lost+found directory that is located in the mount point directory of the filesystem. This is the location where all
lost files are stored.
A file can be “lost” if its filename becomes corrupted and therefore cannot be placed in a normal directory. After
fsck, such a file is relocated to the lost+found directory, and its inode number will appear instead of the
filename.

Note

The following examples may not match the output in our virtual environment.

root@localhost:~# ls -l /data
lost+found
root@localhost:~# ls -l /data/lost+found
total 5
-rw-r--r--. 1 root root 83 Mar 4 06:37 #34234
-rw-r--r--. 1 root root 1911 May 20 2013 #4596

What should be done with these “poor, lost files”? Without a name, it may be hard to find where they belong, but
keep in mind that the file command can be used to determine the file type. For text files, viewing the contents
may be helpful. The files’ timestamps and ownership can also help to determine where these files belong.

23.5 Repairing XFS Filesystems


The XFS file system is in wide usage, some distributions use it for most if not all filesystems, others use it as the
file system for the user’s home directory portion of a system. It is stable, featureful and trusted.

Every filesystem, no matter how trusted needs to be repaired now and then, as power outages happen, filesystem
corruption happens due to rogue programs etc.

XFS filesystems are repaired differently than other file systems. As XFS is capable of containing immensely large
numbers of files (inodes), which would make boot-time checking impractical, even using a file system journal,
which XFS does.

XFS relies on the journal for most error correction, or when dealing with the filesystem being marked as not having
been properly unmounted. If a filesystem is not cleanly unmounted, it is marked as needing to be checked, which
XFS does by replaying the journal log—usually this is enough to ensure that the data is written correctly.

In cases where XFS’s metadata or structure has become corrupted, an error such as mount: Structure needs
cleaning may occur, and the xfs_repair utility will need to be run against the filesystem in order to repair any
inconsistencies.

Consider This

Whenever a filesystem is apparently corrupted, it’s best to have a backup of the data on the filesystem. The
xfs_copy and xfsdump commands may be helpful in that regard. The xfs_copy command can create an exact
duplicate of the questionable filesystem in order to experiment with repairs.

These commands are out of the scope of the objectives and of this course.

In the eventuality that you must attempt the repair an XFS filesystem, it’s fairly straightforward to use. The
xfs_repair command can only be run on an unmounted filesystem, which means if the XFS filesystem on a
device is used as the /home directory, then all users must be off the filesystem in order to unmount it for repair.
To unmount the /dev/sda3 filesystem, as the root user (and not in the /home directory structure) use the
command:

Note

The following examples may not match the output in our virtual environment.

root@localhost:~# umount /dev/sda3

To use xfs_repair on the filesystem, use the following command:

root@localhost:~# xfs_repair /dev/sda3

Phase 1 - find and verify superblock...


Phase 2 - using internal log
- zero log...
- scan filesystem freespace and inode maps...
- found root inode chunk
Phase 3 - for each AG...
- scan and clear agi unlinked lists...
- process known inodes and perform inode discovery...
- agno = 0
- agno = 1
- agno = 2
- agno = 3
- process newly discovered inodes...
Phase 4 - check for duplicate blocks...
- setting up duplicate extent list...
- check for inodes claiming duplicate blocks...
- agno = 0
- agno = 1
- agno = 2
- agno = 3
Phase 5 - rebuild AG headers and trees...
- reset superblock...
Phase 6 - check inode connectivity...
- resetting contents of realtime bitmap and summary inodes
- traversing filesystem ...
- traversal finished ...
- moving disconnected inodes to lost+found ...
Phase 7 - verify and correct link counts...
done

Note

In certain circumstances, it may be advantageous to zero out the XFS filesystem’s journal log, such as when the
journal log has become corrupted. Zeroing out an XFS journal log is an extreme move, and should only be done as
a last resort.

To zero out an XFS filesystem’s journal log, use the command:

root@localhost:~# xfs_repair -L /dev/sda3

In situations where manual repair of the XFS filesystem is desired, the xfs_db command can be used to initiate
such repair on an XFS filesystem. The xfs_db command is used to perform debugging options and possible repairs
to an XFS filesystem, but if inexpertly used can easily make the filesystem unusable and unrecoverable.

To use xfs_db in expert mode use the command:


Important

Expert mode of the xfs_db command allows for the modification of data structures, which can be dangerous!

root@localhost:~# xfs_db -x /dev/sda3

As a method of keeping your XFS filesystems in good shape, the xfs_fsr or Filesystem Reorganizer for the xfs
command can be used on your mounted XFS filesystems to keep them organized and working well.

The xfs_fsr command works on one file at a time, noting where it’s data is, compacting and reorganizing files to
be as streamlined as possible in order to improve read and write times, thus affecting system performance.

Before invoking the xfs_fsr command to use system resources reorganizing filesystems, it’s a good idea to check
if they need this sort of maintenance. The xfs_db command can be used to assess the need for reorganization:

root@localhost:~# xfs_db -r /dev/sda3


xfs_db>frag
actual 345, ideal 289, fragmentation factor 16.23%
Note, this number is largely meaningless.
Files on this filesystem average 1.19 extents per file
xfs_db>quit

The use of the internal frag command will report back the state of the filesystem’s fragmentation, and this will
work on mounted or unmounted filesystems. The state of the example filesystem is fairly low fragmentation, so
reorganization would likely yield little or no actual performance results.

If the fragmentation factor is above 25% or so, then reorganization would yield measurable performance results.

To reorganize and optimize all mounted filesystems on your system and see verbose output on exactly what is
being done to what files, use the command:

root@localhost:~# xfs_fsr -v /dev/sda3


No improvement will be made (skipping): ino=3147588472
ino=1247877226
No improvement will be made (skipping): ino=1247877226
ino=124787727
No improvement will be made (skipping): ino=1247877440
ino=1247877470
extents before:2 after:1 DONE ino=1247877470
ino=1247849901
extents before:2 after:1 DONE ino=1247849901
ino=1247849973
No improvement will be made (skipping): ino=1247849973
ino=1247877640
Output Omitted...

Another very useful feature of the xfs_fsr command is that you can set it to run for a given period of time, so it
can be started either manually or on a scheduled basis to run for a couple of hours each night when the system is
less utilized. To run xfs_fsr for 1 hour and then stop:

root@localhost:~# xfs_fsr -t 3600

The utility will then go to work for up to an hour, reorganizing the drives file by file until the time limit is over, or
the files are done being reorganized.
If for some reason xfs_fsr is interrupted or needs to be stopped, it keeps track of where it was in the
reorganization process, and can resume where it left off when it is run again.
Key Terms
e2fsck
Command used to check the ext2/ext3/ext4 family of file systems.
Section 23.3
fsck
Command used to check and optionally repair one or more Linux file systems. If no filesystem is specified
with the command, fsck will check all filesystems in the /etc/fstab file by default.
| Section 23.2
xfs_db
Command that can be used to perform debugging options and possible repairs to an XFS filesystem.
Section 23.5
xfs_fsr
Filesystem Reorganizer for the <command>xfs</command> command can be used on your mounted XFS
filesystems to keep them organized and working well.
Section 23.5
xfs_repair
A utility that can be run in order to repair any inconsistencies in a filesystem. The
<command>xfs_repair</command> command can only be run on an unmounted filesystem
Section 23.5
LAB 23
23.0 Introduction
In order to provide the functionality you need to apply these concepts, this VM may require a minute or two to
load.

There are circumstances in which a filesystem may break. This can occur, for example, when the filesystem isn't
properly shut down due to a power outage or a frustrated system administrator pulling the power on the system.

Because of how filesystem changes are made, filesystem corruption can occur when a filesystem isn't correctly
unmounted. This is because changes to the filesystem metadata (information about the filesystem) are stored in
memory initially. When a filesystem is unmounted correctly, all of this data is flushed to the hard drive.

When filesystems break, an administrator needs to know how to fix the problems. The fsck utility provides you
with the tools to fix filesystems.

23.1 Step 1
Log in to the system using the root account. When prompted, provide the root password:

root
netlab123
Ubuntu 18.04.2 LTS ubuntu tty1
ubuntu login:
Password:
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-45-generic x86_64)

* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage

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.
root@ubuntu:~#
23.2 Step 2
In order to complete this lab, a new partition must be created. The steps to create a new partition will essentially be
the same as what you performed in a previous lab. Execute the following command to start this process:

fdisk /dev/sdb
root@ubuntu:~# fdisk /dev/sdb
Welcome to disk (util-linux 2.31.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table.


Created a new DOS disklabel with disk identifier 0xb23bc72f.

Command (m for help):

23.3 Step 3
At the Command prompt, type p to display the current partition table:

p
Command (m for help): p
Disk /dev/sdb: 4 GiB, 4294967296 bytes, 8388608 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xb23bc72f

Command (m for help):

23.4 Step 4
At the Command prompt, type n to create a new partition:

n
Command (m for help): n
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p):
23.5 Step 5
At the Select prompt, type e to specify that you are going to create an extended partition:

e
Command (m for help): n
Partition type:
p primary (1 primary, 0 extended, 4 free)
e extended
Select (default p): e
Partition number (1-4, default 1):

23.6 Step 6
At the Partition number prompt, type 1 to specify that you are going to use the first partition number:

1
Command (m for help): n
Partition type:
p primary (1 primary, 0 extended, 4 free)
e extended
Select (default p): e
Partition number (1-4, default 1): 1

23.7 Step 7
At the First sector prompt, accept the default value by pressing the Enter key:

Enter
Command (m for help): n
Partition type:
p primary (0 primary, 0 extended, 4 free)
e extended
Select (default p): e
Partition number (1-4, default 1): 1
First sector (2048-8388607, default 2048):
23.8 Step 8
Press the Enter key to accept the default value at the Last sector prompt:

Enter
Command (m for help): n
Partition type:
p primary (1 primary, 0 extended, 3 free)
e extended
Select (default p): e
Partition number (1-4, default 2): 2
First sector (41943040-42967039, default 41943040):
Using default value 41943040
Last sector, +sectors or +size{K,M,G} (2048-8388607, default 8388607):

Created a new partition 1 of type ‘Extended’ and of size 4 GiB.

Command (m for help):

23.9 Step 9
At the Command prompt, type p to display the current partition table. You should see your new partition:

p
Command (m for help): p
Disk /dev/sdb: 4 GiB, 4294967296 bytes, 8388608 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifierL 0xb23bc72f

Device Boot Start End Sectors Size Id Type


/dev/sdb1 2048 8388607 8386560 4G 5 Extended

Command (m for help):


23.10 Step 10
Now, you can create a partition that you can later format with a filesystem and access via a directory by mounting
it. To create this new partition, first type n at the Command prompt:

n
Command (m for help): n
All space for primary partitions is in use.
Adding logical partition 5
First sector (4096-8388607, default 4096):
First sector (41945088-42967039, default 41945088):

23.11 Step 11
Press the Enter key to accept the default for the First sector:

Enter
Command (m for help): n
All space for primary partitions is in use.
Adding logical partition 5
First sector (4096-8388607, default 4096):
Last sector, +sectors or +size{K,M,G} (4096-8388607, default 8388607):

23.12 Step 12
At the next prompt, enter +200M to create a 200MB partition:

+200M
Command (m for help): n
All space for primary partitions is in use.
Adding logical partition 5
First sector (4096-8388607, default 4096):
Last sector, +sectors or +size{K,M,G} (4096-8388607, default 8388607):+200M
Command (m for help):
23.13 Step 13
Type p at the Command prompt to see your new partition:

p
Command (m for help): p
Disk /dev/sdb: 4 GiB, 4294967296 bytes, 8388608 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifierL 0xb23bc72f

Device Boot Start End Sectors Size Id Type


/dev/sdb1 2048 8388607 8386560 4G 5 Extended
/dev/sdb5 4096 413695 409600 200M 83 Linux

Command (m for help):

23.14 Step 14
Type w at the Command prompt to save your new partitions:

w
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

root@ubuntu:~#

23.15 Step 15
Reboot the system to have the kernel recognize the new partitions:

reboot
root@ubuntu:~# reboot
In some cases, you may be able to run a command, such as kpartx or partprobe, to have the kernel read the new
partition table. However, on this system, these commands do not exist.
23.16 Step 16
After the system finishes booting, log in to the system using the root account. When prompted, provide the root
password:

root
netlab123
Ubuntu 18.04.2 LTS ubuntu tty1
ubuntu login:
Password:
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-45-generic x86_64)

* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage

root@ubuntu:~#

23.17 Step 17
Then, verify the new files have been created in the /dev directory:

ls /dev/sd*
root@ubuntu:~# ls /dev/sd*
/dev/sda /dev/sda1 /dev/sdb /dev/sdb1 /dev/sdb5

23.18 Step 18
Execute the following command to create an ext4 partition on the /dev/sdb5 partition:

mkfs -t ext4 /dev/sdb5


root@ubuntu:~# mke2fs -t ext4 /dev/sdb5
mke2fs 1.44.1 (24-Mar-2018)
Discarding device blocks: done
Creating filesystem with 204800 1k blocks and 51200 inodes
Filesystem UUID: ab7552f0-0802-49f5-8241-70fdc183b676
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729

Allocating group tables: done


Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done
23.19 Step 19
Create a directory to use as a mount point for the new partition by using the mkdir command. Then, mount the new
partition and verify that it mounted correctly by executing the mount commands as shown.

Create a directory called /data to use as a mount point for the new partition by using the mkdir command:

mkdir /data
root@ubuntu:~# mkdir /data
root@ubuntu:~#
mount /dev/sdb5 /data
mount
23.20 Step 20
Attempt to run the fsck utility on the /dev/sdb5 filesystem by executing the following command:

fsck /dev/sdb5
root@ubuntu:~# fsck /dev/sdb5
fsck from util-linux 2.31.1
e2fsck 1.44.1 (24-Mar_2018)
/dev/sdb5 is mounted.
e2sck: Cannot continue, aborting.
The fsck utility will not run on a mountedfilesystem. The purpose of the fsck command is to fix filesystem
problems on filesystems that can't be mounted. If the filesystem is mounted, there are no filesystem problems and
no need to run the fsck command.

23.21 Step 21
Unmount the /dev/sda5 partition and then attempt to run the fsck utility on the /dev/sda5 filesystem by executing
the following commands:

umount /dev/sdb5
fsck /dev/sdb5
root@ubuntu:~# umount /dev/sdb5
root@ubuntu:~# fsck /dev/sdb5
fsck from util-linux 2.31.1
e2fsck 1.44.1 (24-Mar-2018)
/dev/sdb5: clean, 11/51200 files, 12115/204800 blocks

The clean value indicates that this filesystem is either new or has been correctly unmounted. Therefore, there is no
need to run fsck because the filesystem is not broken.

23.22 Step 22
One way of having the fsck utility run on a clean filesystem is to force the checking of the filesystem with the -f
option:

fsck -f /dev/sdb5
root@ubuntu:~# fsck -f /dev/sdb5
fsck from util-linux 2.31.1
e2fsck 1.44.1 (24-Mar-2018)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/sdb5: 11/51200 files (0.0% non-contiguous), 12115/204800 bl
23.23 Step 23
Another technique that you can use is to manually switch the filesystem state from clean to not clean. To do
this, execute the following command:

debugfs -w -R "ssv state 0" /dev/sdb5


root@ubuntu:~# debugfs -w -R "ssv state 0" /dev/sdb5
debugfs 1.44.1 (24-Mar-2018)

A filesystem state of not clean just indicates that the filesystem was not properly unmounted. There may be
problems with the filesystem, but then again, there may be no problems at all. If a filesystem is set to not clean,
then the fsck utility will check the filesystem.

The debugfs command can make changes directly to the filesystem. Use this utility with caution on filesystems
that are on critical systems, as you could easily damage the filesystem with this utility.

23.24 Step 24
After switching the filesystem state, you can run the fsck command:

fsck /dev/sdb5
root@ubuntu:~# fsck /dev/sdb5
fsck from util-linux 2.31.1
e2fsck 1.44.1 (24-Mar-2018)
/dev/sdb5 1.44.1 was not cleanly unmounted, check forced.
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/sdb5: 11/51200 files (0.0% non-contiguous), 12115/204800 bl

23.25 Step 25
The superblock is where critical filesystem data is stored. If the primary superblock is corrupted, then you need to
use a backup superblock to fix the primary superblock. To view the backup superblocks of a filesystem, execute
the following command:

dumpe2fs /dev/sdb5 | grep superblock


root@ubuntu:~# dumpe2fs /dev/sdb5 | grep superblock
dumpe2fs 1.44.1 (24-Mar-2018)
Primary superblock at 1, Group descriptors at 8194-8195
Backup superblock at 8193, Group descriptors at 24578-24579
Backup superblock at 24577, Group descriptors at 24578-24579
Backup superblock at 40961, Group descriptors at 40962-40963
Backup superblock at 57345, Group descriptors at 57346-57347
Backup superblock at 73729, Group descriptors at 73730-73731
23.26 Step 26
The following command is intended for testing purposes. You would never run this command on a production
machine. Execute the following command to force the corruption of your primary superblock:

Warning

Be very careful when typing this command. If you don't type it exactly as shown, it may end up deleting the entire
filesystem. If that happens, the only solution is to reset the VM and restart the lab.

dd if=/dev/zero of=/dev/sdb5 bs=1024 count=1 seek=1


root@ubuntu:~# dd if=/dev/zero of=/dev/sda5 bs=1024 count=1 seek=1
1+0 records in
1+0 records out
1024 bytes (1.0 kB, 1.0 KiB) copied, 0.00405975 s, 252 kB/s

23.27 Step 27
To verify that the filesystem now has a problem, attempt to mount the filesystem by executing the following
command:

mount /dev/sdb5 /data


root@ubuntu:~# mount /dev/sdb /data
mount: /data: wrong fs type, bad option, bad superblock on /dev/sdb, missing codepage or
helper program, or other error.
Normally, the mount command can determine the filesystem type by looking at values in the primary superblock.
However, if that information can't be accessed, you will get the error message mount: you must specify the
filesystem type.

23.28 Step 28
Execute the following command to try to mount the filesystem by specifying the filesystem type:

mount -t ext4 /dev/sdb5 /data


root@ubuntu:~# mount -t ext4 /dev/sdb5 /data
[ 1969.413457] EXT$-fs (sdb5): VFS: Can’t find ext4 filesystem
mount: /data: wrong fs type, bad option, bad superblock on /dev
23.29 Step 29
Notice the suggestion to view the contents of the dmesg command. Execute the following command:

dmesg | tail
root@ubuntu:~# dmesg | tail
[ 3.220384] parport0: PC-style at 0x378, irq 7 [PCSPP,TRISTATE]
[ 3.519704] SSE version of gmc_enc/dec engaged.
[ 3.626606] ppdev: user-space parallel port driver
[ 3.717314] Adding 524284k swap on /dev/mapper/ubuntu--vg-swap_1. Priority:-2 extents:1
across:524284k FS
[ 4.082803] random: crng init done
[ 4.082805] random: 7 urandom warning(s) missed due to ratelimiting
[ 1080.847807] EXT4-fs (sdb5): mounted filesystem with ordered data mode. Opts: (null)
[ 1080.847807] sdb: sdb1 < sdb5 >
[ 1080.864385] sdb: sdb1 < sdb5 >
[ 1969.413457] EXT4-fs (sdb5): VFS: Can’t find ext4 filesystem

The highlighted lines demonstrate that without the primary superblock, the mount command has no way of finding
the ext4 filesystem on this partition.

23.30 Step 30
You can use a backup superblock to fix the primary superblock. Unfortunately, if the primary superblock is
corrupted, then you can't use the dumpe2fs command to view the location of backup superblocks:

dumpe2fs /dev/sdb5 | grep superblock


root@ubuntu:~# dumpe2fs /dev/sdb5 | grep superblock
dumpe2fs: 1.44.1 (24-Mar-2018)
dumpe2fs: Bad magic number in super-block while trying to open /dev/sdb5
Couldn’t find valid filesystem superblock.

23.31 Step 31
However, there is a second way to determine a backup superblock that will work on a filesystem that has a
corrupted primary superblock. Execute the following command:

mke2fs -n /dev/sdb5
root@ubuntu:~# mke2fs -n /dev/sdb5
mke2fs 1.44.1 (24-Mar-2018)
Creating filesystem with 240800 1k blocks and 51200 inodes
Filesystem UUID: 71b895c4-e9f4-4e7a-992f-b90f6784094f
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729

Important

Do not forget to include the -n option. Without the -n option, you would end up creating a new filesystem on that
partition, resulting in complete data loss.
23.32 Step 32
To fix the filesystem using the backup superblock, execute the following command. When prompted with Fix<y>?
type the letter Y:

fsck -b 8193 /dev/sdb5


y
root@ubuntu:~# fsck -b 8193 /dev/sdb5
fsck from util-linux 2.31.1
e2fsck 1.44.1 (24-Mar-2018)
/dev/sdb5 1.44.1 was not cleanly unmounted, check forced.
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
Block bitmap differences: +(8193--8451) +(24577--24835) +(40961--41219) +(57345--57603)
+(73729--73987)
Fix<y>? yes
Inode bitmap differences: Group 1 inode bitmap does not match checksum.

/dev/sdb5: ***** FILE SYSTEM WAS MODIFIED *****


/dev/sdb5: 11/51200 files (0.0% non-contiguous), 12115/204800 bl

23.33 Step 33
Verify that the filesystem was fixed by mounting it with the first mount command and then verify that the
filesystem mounted properly with the second mount command:

mount /dev/sdb5 /data


mount
23.34 Step 34
The most common time for a filesystem error to occur is during the boot process. In the last phase of this lab, you
will create a filesystem error and fix it during the boot process. Start by using the nano editor to edit the
/etc/fstab file:

nano /etc/fstab
root@ubuntu:~# nano /etc/fstab

Add the following line to the bottom of the /etc/fstab file:

/dev/sdb5 /data ext4 defaults 0 0


If the /etc/fstab file is currently empty, make the line above the first and only line of the file.
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point> <type> <options> <dump> <pass>
/dev/mapper/ubuntu—vg-root / ext4 errors=remount-ro 0 1
/dev/mapper/ubuntu—vg-swap_1 none swap sw 0 0
/dev/fd0 /media/floppy0 auto rw,user,noauto,exec,utf8 0 0
/dev/sdb5 /data ext4 defaults 0 0

^G Get Help ^O Write Out ^W Where Is ^K Cut Text ^J Justify ^C Cur Pos M-U Undo
^X Exit ^R Read File ^\ Replace ^U Uncut Text ^T To Spell ^_ Go To Line M-E Redo

Type Ctrl+X to exit the nano editor. At the Save modified buffer? prompt, type the Y key.

Ctrl+x
y
Save modified buffer? (Answering "No" will DISCARD changes.)
Y Yes
N No ^C Cancel

Press Enter to save (write) the file.

Enter
File Name to Write: /etc/fstab_
^G Get Help M-D DOS Format M-A Append M-B Backup File
^C Cancel M-M Mac Format M-P Prepend ^T
23.35 Step 35
Verify this is correct by executing the following command:

tail -1 /etc/fstab
Note that the character after the -n option is a number 1, not a lowercase letter L.
root@ubuntu:~# tail -1 /etc/fstab
/dev/sdb5 /data ext4 defaults 0 0

23.36 Step 36
To test that this line is accurate, unmount the /dev/sda5 filesystem and remount it again by specifying only the
mount point:

umount /data
root@ubuntu:~# umount /data
mount /data
mount
Recall that when you specify only the mount point, the mount command looks at the corresponding entry in the
/etc/fstab file to determine the rest of the information needed to mount. If the mount command is successful, the
entry in the /etc/fstab file is correct.

23.37 Step 37
Next, unmount the filesystem and use the dd command to create an error in the filesystem:

umount /data
dd if=/dev/zero of=/dev/sdb5 bs=1024 count=1 seek=1
root@ubuntu:~# umount /data
root@ubuntu:~# dd if=/dev/zero of=/dev/sda5 bs=1024 count=1 seek=1
1+0 records in
1+0 records out
1024 bytes (1.0 kB) copied, 0.00596831 s, 172 kB/s

23.38 Step 38
Verify that the filesystem is broken by attempting to mount it:

mount /data
root@ubuntu:~# mount /data
[ 3502.251839] EXT4-fs (sdb5): VFS : Can’t find ext4 filesystem
mount: /data: wrong fs type, bad option, bad superblock on /dev/sdb5, missing codepage or
helper program, or other error.

23.39 Step 39
Typically, you would want to fix the filesystem before you reboot the machine. However, in this case the point is
to learn how to fix a filesystem error that prevents a system from rebooting. Reboot the machine:

reboot
root@ubuntu:~# reboot

23.40 Step 40
The system will boot to a point, and then an error message will appear:
Because this filesystem is a non-critical filesystem (not needed to boot the system), you could press the letter S,
and the mounting process for this filesystem would be skipped. You could then login and fix the problem by
running the fsck command. However, if it was a critical filesystem, you wouldn't be able to do that. For this lab,
consider this a critical filesystem.
23.41 Step 41
Type the root password and press the Enter key. You will then be provided a command prompt:

netlab123
Enter
...
Give root password for maintenance
(or press Control-D to continue):
root@ubuntu:~#

At this prompt, type the following command to fix the filesystem:

fsck /dev/sdb5
root@ubuntu:~# fsck /dev/sdb5
fsck from util-linux 2.31.1
e2fsck 1.44.1 (24-Mar-2018)
/dev/sdb5 1.44.1 was not cleanly unmounted, check forced.
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
Inode bitmap differences: Group 1 inode bitmap does not match checksum.
FIXED.
Block bitmap differences: Group 1 block bitmap does not match checksum.
FIXED.

/dev/sdb5: ***** FILE SYSTEM WAS MODIFIED *****


/dev/sdb5: 11/51200 files (0.0% non-contiguous), 12115/204800 blocks

Unlike the fsck utility that you run when logged in as root, the fsck utility that runs when in maintenance mode,
as is the case here, knows to check backup superblocks automatically.

23.42 Step 42
Now that the filesystem has been fixed, you can continue the boot process by holding down the Ctrl+D. You could
also type the exit command:

exit
root@ubuntu:~# exit
23.43 Step 43
The system should boot the rest of the way and provide you with a login prompt. Log in to the system using the
root account. When prompted, provide the root password:

root
netlab123
Ubuntu 18.04.2 LTS ubuntu tty1
Ubuntu login: root
Last login: Sat Jun 29 21:30:29 UTC 2019 on tty1
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-45-generic x86_64)

* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage

root@ubuntu:~#

23.44 Step 44
Verify that the filesystem was fixed by running the mount command:

mount
23.45 Step 45
Lastly, after you have finished running the fsck command, you should look in the lost+found directory for the
filesystem to see if any lost files have been placed in that directory. Execute the following command:

root@ubuntu:~# ls /data/lost+found
root@ubuntu:~#

No output is a good thing. If there are any lost files, they will not have regular names; rather, they will be named
after their inode number.
Chapter 24: Package Management

24.1 Introduction
The two most common software management systems were started by two of the most popular Linux distributions:
Red Hat and Debian. Both of these systems provide similar functionality, including the ability to manually
download and install a software program as well as automate the process. While some may argue that one system is
better than the other, the argument is mostly moot since most administrators typically don't have a choice as to
which software management system is available for their distribution.

While there is a chance that you may only need to learn one system (the one that is used on your distribution of
Linux), knowing both systems provides the flexibility of being able to manage software on many different Linux
distributions. The good news is that once you understand one system, understanding the other is not too difficult.

Another Linux distribution, SUSE, uses the package management system developed by Red Hat as well as its own
package management system called Zypper. In this chapter, you will learn about Red Hat, Debian, and SUSE
command line package management.

24.2 RPM Package Management


Red Hat's package management system is based upon the file format used to package the software files used within
that distribution, known as the RPM Package Manager. Although invented at Red Hat, RPM is used for
managing software for many different distributions and is the baseline software management system defined by the
Linux Standards Base.

Consider This

Originally, this software management system was simply called RPM, or Red Hat Package Manager. It seems
strange that it is now referred to as the RPM Packager Manager since the "PM" in RPM originally stood for
"Package Manager". In a sense, it is similar to referring to an ATM as an "ATM machine" while ATM stands for
"Automated Teller Machine".

In reality, RPM no longer stands for "Red Hat Package Manager". When RPM became part of the Linux Standards
Base (LSB), it was renamed RPM Package Manager to avoid including "Red Hat" in its name. This is primarily
because the LSB attempts to be as neutral as possible when it comes to Linux distributions.

Typically, RPM Package Manager is simply referred to as RPM.

RPM files are available in two formats: .src.rpm files and .rpm files. Unless you are compiling the software
yourself or viewing the source code of the software, you don't need to be concerned with the .src.rpm files. These
files contain the source code that is used to build the binary .rpm files. The binary .rpm files are the ones that
contain the compiled code that is ready to use.

The files that are used by RPM have a specific naming convention to help identify the package, its version number,
its release identifier, and which architecture the software was built for. For example, if a file was named:
x3270-x11-3.3.6-10.5.el6.i686.rpm

Then critical information could be discovered from just the file name:

package_name-version-release.architecture.rpm

Package Name

x3270-x11-3.3.6-10.5.el6.i686.rpm

The name of the package may include a hyphen. The name ends where the version number begins; the version
number is always a decimal delimited number.

Version Number

x3270-x11-3.3.6-10.5.el6.i686.rpm

Immediately following the package name and the hyphen that follows the package name is the version number.
This version number is set by the original developer of the software.

Release Identifier

x3270-x11-3.3.6-10.5.el6.i686.rpm

Following the hyphen after the version number is the release identifier. Release identifiers are chosen by the
packager (not the software developers) of the software, which is normally the vendor of the distribution.

Architecture

x3270-x11-3.3.6-10.5.el6.i686.rpm

If a package contains binary code, then the computer architecture that the code was compiled on will be the final
part of the file name before the .rpm file extension. There are several architecture types:

Code Architecture
noarch Packages that do not contain binary code, such as those that may only contain script files
src Packages that have not been compiled
i686 Packages compiled to run in 32-bit mode on a Pentium 4 or later processor
x86_64
Packages compiled to run in 64-bit mode on either an AMD 64-bit processor or an Intel EM64T 64-bit
compatible processor
24.2.1 RPM Queries
Any user can perform RPM queries to display information about packages that are currently installed on the
system or about RPM files that have yet to be installed (either on the filesystem or reachable by a URL). The
difference between doing a query about an installed package versus an RPM file is two-fold:

 To query a package that is not installed, use the -p FILE option. The FILE argument specifies the path to a
local .rpm file or URL of an .rpm file on the internet (ftp or http).
 To query an installed package, use only the package name.

Note

Some of the files required for the following examples are not available in our virtual environment. Therefore, some
of the examples may not match the output in the VM.

Additional practice for RPM package management is provided in the lab.

To perform any RPM query, always use the -q option with the rpm command. To query for basic package
information, use the -i option:

[sysadmin@localhost ~]$ rpm -qi bash


Name : bash
Version : 4.2.46
Release : 31.el7
Architecture: x86_64
Install Date: Tue Dec 4 14:38:13 2018
Group : System Environment/Shells
Size : 3667773
License : GPLv3+
Signature : RSA/SHA256, Mon Nov 12 14:21:49 2018, Key ID 24c6a8a7f4a80eb5
Source RPM : bash-4.2.46-31.el7.src.rpm
Build Date : Tue Oct 30 17:09:33 2018
Build Host : x86-01.bsys.centos.org
Relocations : (not relocatable)
Packager : CentOS BuildSystem <http://bugs.centos.org>
Vendor : CentOS
URL : http://www.gnu.org/software/bash
Summary : The GNU Bourne Again shell
Description :
The GNU Bourne Again shell (Bash) is a shell or command language
interpreter that is compatible with the Bourne shell (sh). Bash
incorporates useful features from the Korn shell (ksh) and the C shell
(csh). Most sh scripts can be run by bash without modification.

To perform a similar query on the RPM file for bash, the -p option would be added along with the -q and -i
options:

[sysadmin@localhost ~]$ rpm -qip bash-4.2.46-31.el7.src.rpm

Consider This

Where is this .rpm file located? On most distributions, the .rpm files are not stored by default on the local
filesystems. They can be found either on the installation media (install DVD or CD ROM) or online on servers
called repositories.
Always remember that RPM queries require the use of the -q option for installed packages and the -qp for
uninstalled package files. There are many different types of queries that can be performed, as described in the
following table:

Option Purpose

-a List all of the installed packages currently on the system

-c Display a list of configuration files that belong to the package

-d List the documentation files that belong to the package

-i Display the package information

-K Check the package integrity

-l List all files in the package

--provides List the capabilities this package provides

-R List the capabilities that this package requires

--scripts List the scripts that are used before and after installation of the package

-s Display the state of each package file as normal, not installed or replaced

Querying Scripts

It is a good idea to query a package to see the scripts it will execute before installing an RPM file from a third-
party source. Because root privileges are required by default to install or remove RPM packages from the system,
these scripts will run as root during the installation or removal of a package from the system; this is potentially
dangerous since scripts run as root can make any change to the system.

Before installing the x3270-x11 package, the administrator could view the scripts to ensure that they are not
dangerous by executing the following command:

[sysadmin@localhost ~]$ rpm -qp --scripts x3270-x11-3.3.6-10.5.el6.i686.rpm


postinstall scriptlet (using /bin/sh):
cd /usr/share/x3270/fonts && /usr/bin/mkfontdir
touch --no-create /usr/share/icons/hicolor
if [ -x /usr/bin/gtk-update-icon-cache ]; then
gtk-update-icon-cache -q /usr/share/icons/hicolor
fi
postuninstall scriptlet (using /bin/sh):
if [ "$1" = "0" ]; then
cd /usr/share/x3270/fonts && /usr/bin/mkfontdir
fi
touch --no-create /usr/share/icons/hicolor
if [ -x /usr/bin/gtk-update-icon-cache ]; then
gtk-update-icon-cache -q /usr/share/icons/hicolor
fi

The output of this query shows that there is a postinstall and postuninstall script for this package. In this
case, these scripts are not dangerous, as they are updating fonts and icons that the package may use.
Querying the Integrity of a Package

If an administrator is concerned with the security of the system, then not only should the administrator query a
package to view its scripts, but also query the integrity of a package by using the -K option. To use this option on
an .rpm file , import the public key file that is distributed by the same organization that packaged and distributed
the .rpm file.

Typically, the public keys for the distribution are automatically included with the system. For example, on a Red
Hat-derived distribution, the public key files are stored in the /etc/pki/rpm-gpg directory. An administrator can
import these keys into the RPM database with the command:

[sysadmin@localhost ~]$ rpm --import /etc/pki/rpm-gpg/*

After the keys have been imported, then a package's integrity can be verified. For example, to verify the integrity of
the x3270-x11 package, an administrator could execute the following command:

[sysadmin@localhost ~]$ rpm -qpK x3270-x11-3.3.6-10.5.el6.i686.rpm


x3270-x11-3.3-4.el7.x86_64.rpm: rsa sha1 (md5) pgp md5 OK

Notice the only output that is capitalized is OK, meaning that the package is not corrupted. The following output has
several acronyms capitalized along with NOT OK, indicating a corrupted package:

[sysadmin@localhost ~]$ rpm -qpK x3270-x11-3.3.6-10.5.el6.i686.rpm


x3270-x11-3.3-4.el7.x86_64.rpm: rsa sha1 (MD5) PGP MD5 NOT OK

Querying for Installed Packages

There are several methods to determine if a package is installed. If the exact package name is known, simply query
the package by name. For example, to see if the bash package is installed, execute:

[sysadmin@localhost ~]$ rpm -q bash


bash-4.2.46-31.el7.src.rpm

If the package is installed, then the output will be like the original RPM file name without the .rpm extension. If
the package is not installed, the output will indicate so:

[sysadmin@localhost ~]$ rpm -q pickle


package pickle is not installed

The * glob character may be useful if the exact package name is not known. For example, if you knew that the
package name contained python, but you were unsure of the rest, then execute the following command:

[sysadmin@localhost ~]$ rpm -qa *python*


python-2.6.6-52.el6.x86_64
python-urlgrabber-3.9.1-9.el6.noarch
rpm-python-4.8.0-37.el6.x86_64
python-libs-2.6.6-52.el6.x86_64
python-pycurl-7.19.0-8.el6.x86_64
python-iniparse-0.3.1-2.1.el6.noarch

Note

To get an alphabetical list of all installed packages, execute the rpm -qa | sort command. To get a chronological
list of all packages, execute the rpm -qa --last command.
24.2.2 Installing Packages With rpm
A dependency is a software package (or a feature) that is required for another package to be installed and function
correctly. When an administrator uses the rpm command to install a .rpm software package, that process will fail if
the dependencies for that package are not already installed.

For example, to install the x3270-x11-3.3.6-10.5.el6.i686.rpm package, execute:

[sysadmin@localhost ~]$ rpm -i x3270-x11-3.3.6-10.5.el6.i686.rpm

If there were any missing dependencies, the rpm command would fail and display an error message like the
following:

[sysadmin@localhost ~]$ rpm -i x3270-x11-3.3.6-10.5.el6.i686.rpm


error: Failed dependencies:
libicuuc.so.42 is needed by x3270-x11-3.3.6-10.5.el6.i686
x3270 = 3.3.6 is needed by x3270-x11-3.3.6-10.5.el6.i686

Based upon the previous output, a library or shared object file named libicuuc.so.42 and the x3270 package
(version 3.3.6) are missing. The library file is a bit tricky since it is not clear what package it belongs to.
Searching the internet using the library file name reveals that the missing package needed in order to install the
library file is named libicu.

It is important to note that sometimes a package and its dependencies must be installed at the same time if there are
any circular dependencies between them. Once the x3270 and libicu packages are located, then the administrator
would install them along with the x3270-x11 package by executing a command like the following:

[sysadmin@localhost ~]$ rpm -i x3270-x11-3.3.6-10.5.el6.i686.rpm x3270-3.3.6-


10.5.el6.i686.rpm libicu-4.2.1-9.1.el6_2.i686.rpm

The RPM system uses a database to track the capabilities of each previously installed package. An RPM file
contains a list of package dependencies. Before installing an RPM package, the rpm command compares this
information to determine if the dependencies were satisfied.

Most administrators determine package dependencies by examining the output of a failed RPM package install.
However, it is also possible to check the requirements and dependencies of a package in advance with the
following rpm query (partial output shown):

[sysadmin@localhost ~]$ rpm -qpR x3270-x11-3.3.6-10.5.el6.i686.rpm


/bin/sh
/usr/bin/mkfontdir
gtk2 >= 2.6
libICE.so.6
libicuuc.so.42
libnsl.so.1
libssl.so.10
libutil.so.1
x3270 = 3.3.6

Note

To see what each package provides, perform a query with the --provides option. The output from the following
command demonstrates that this package provides the required x3270 package with the version equal to 3.3.6:
[sysadmin@localhost ~]$ rpm -qp --provides x3270-3.3.6-10.5.el6.i686.rpm
config(x3270) = 3.3.6-10.5.el6
x3270 = 3.3.6-10.5.el6
x3270(x86-32) = 3.3.6-10.5.el6

Occasionally, a package needs to be reinstalled, perhaps because a file from that package is missing. Normally, the
rpm command will refuse to install a package that is already installed, but it can be forced by adding the --force
option. For example, to reinstall the x3270 package, execute the following command:

[sysadmin@localhost ~]$ rpm --force -i x3270-3.3.6-10.5.el6.i686.rpm

24.2.3 Erasing Packages with rpm


The rpm command can be used to erase (remove) packages from the system with the -e option. However,
dependency issues may arise. If there were dependency issues when a group of packages was installed, then there
may also be dependency issues when that group of packages is removed.

For example, if an attempt was made to remove the x3270 or libicu packages without first removing the x3270-
x11 package, then an error would occur:

[sysadmin@localhost ~]$ rpm -e x3270 libicu


error: Failed dependencies:
x3270 = 3.3.6 is needed by (installed) x3270-x11-3.3.6-10.5.el6.i686
libicuuc.so.42 is needed by (installed) x3270-x11-3.3.6-10.5.el6.i686

In other words, the rpm command will not allow a package to be erased if it is a requirement of another package. If
the x3270-x11 package were erased first, then the other two packages could be erased.

In the case of circular dependencies, when packages depend on each other, then all the packages can be removed
with a single rpm command by specifying all package names as an argument:

[sysadmin@localhost ~]$ rpm -e x3270-x11 x3270 libicu

24.2.4 Updating Packages With rpm


To update a package with a new version or newer release, use the rpm command with either the -U or the -F option.
As was the case with installing or removing packages, dependency issues may arise when updating packages.
Installing an updated package often requires the installation of updates to the packages that it depends upon.

The -U option can be used with the rpm command to either install or update a package:

[sysadmin@localhost ~]$ rpm -U x3270-4.3.6-10.5.el6.i686.rpm

On the other hand, when using the rpm command with the -F option, the package will only be updated if the
package is already installed; this is called freshening the package:

[sysadmin@localhost ~]$ rpm -F x3270-4.3.6-10.5.el6.i686.rpm


Important

The kernel package is so critical that when a new version is available, it should be installed rather than updated or
freshened. The kernel files are organized to allow for multiple versions to exist on the system simultaneously. In
this way, if an updated kernel is installed on your system but is not functional, simply reboot the system and select
the previous kernel from the bootloader menu.

24.2.5 Using rpm2cpio


The rpm2cpio command accepts an .rpm file as an argument (or reads data that is in a package format from
standard input) and outputs a cpio archive. This capability can be used to list the contents of an .rpm file or to
extract one or more files from within the original .rpm file.

For example, to list the contents of the telnet-server-0.17-47.el6_3.1.i686.rpm file, execute the following
command. The output shows the files contained within the .rpm file and the total number of 512KiB blocks that
those files would use if extracted:

[sysadmin@localhost ~]$ rpm2cpio telnet-server-0.17-47.el6_3.1.i686.rpm | cpio -t


./etc/xinetd.d/telnet
./usr/sbin/in.telnetd
./usr/share/man/man5/issue.net.5.gz
./usr/share/man/man8/in.telnetd.8.gz
./usr/share/man/man8/telnetd.8.gz
108 blocks

To copy these files from the .rpm file, use the following command to extract these files to the current directory:

[sysadmin@localhost ~]$ rpm2cpio telnet-server-0.17-47.el6_3.1.i686.rpm | cpio -imud

Several options for the cpio command are listed in the table below.

Option Purpose
-i Extract
-m Retain the original modification times on the files
-u Unconditionally replace any existing files
-d Create any parent directories of the files contained within the archive

Note

Recall that the cpio command is an archive command that can merge many files into a single file.

The cpio command is covered in greater detail earlier in the course.

Consider This

Why use the rpm2cpio command? Consider a situation where a key package file is accidentally removed from the
system. Reinstalling the entire package may be overkill if only a single file is needed. Using the rpm2cpio
command, the file that is missing can be extracted and copied back into the appropriate directory.
24.3 Managing Packages With yum
While an administrator can manage software directly with the rpm command, other higher level commands are
available that make software management significantly easier. The yum command can locate and download
packages on the internet and resolve dependencies automatically.

Dependencies occur when a package (P1) depends on other packages (P2, P3, P4) to function correctly. The
dependant packages (P2, P3, P4) may have their own dependencies (P5, P6, P7, P8), and so on. Resolving these
cascading dependencies manually can be a daunting task!

Circular dependencies are sometimes possible when two packages require each other. For example, chicken.rpm
requires egg.rpm, but egg.rpm requires chicken.rpm. Although it is possible to resolve dependency issues
manually with the rpm command, they can be solved automatically with the yum command.

The yum command can perform some operations that the rpm command cannot. The big advantage of the yum
command is that it can be configured to automatically download packages and resolve package dependencies. In
addition, the yum command can display package information for packages that aren't even on the system by
accessing this data from a server called a repository.

Typically, the yum command is configured by editing the /etc/yum.conf file and the files found in the
/etc/yum.repos.d directory. These configuration files are used to specify servers (the repositories) on the internet
where the yum command can obtain the RPM files automatically. If the system does not have networking enabled
or doesn't have access to the internet, then it will not be able to use the yum commands to manage packages. In
those situations, the rpm commands can be used for package management.

One rpm query that was not mentioned previously is the -f option:

[sysadmin@localhost ~]$ rpm -qf /bin/bash


bash-4.1.2-15.el6_4.x86_64

This query is used to determine which package owns (or provides) the /bin/bash file. This query only succeeds if
the bash package is already installed on the system. Unfortunately, this is not helpful when trying to find the
package owner for a file and that package was not installed on your system, as is often the case when trying to
resolve dependency issues. For example, if the libicu package is not installed then the following query will fail:

[sysadmin@localhost ~]$ rpm -qf /usr/lib/libicuuc.so.42


error: file /usr/lib/libicuuc.so.42: No such file or directory

On the other hand, the yum command can be used to determine which package owns the file because the yum
command searches the database of the repository server(s):

[sysadmin@localhost ~]$ yum provides /usr/lib/libicuuc.so.42

Better yet, you don't even need to know the directory that a file is supposed to exist in, because a glob pattern can
be used:

[sysadmin@localhost ~]$ yum provides "*/libicuuc.so.42"

The other distinct advantage of using the yum command over the rpm command is the ability to search for a
package in the repositories, based upon the name or description of the package. For example, the following yum
command will display all packages (installed or available for install) that have the word terminal in the
description:
[sysadmin@localhost ~]$ yum search terminal
Loaded plugins: fastestmirror, refresh-packagekit, security
Loading mirror speeds from cached hostfile
* base: centosb6.centos.org
* extras: centosi5.centos.org
* updates: centosb6.centos.org
============================ N/S Matched: terminal =============================
gnome-terminal.i686 : Terminal emulator for GNOME
nautilus-open-terminal.i686 : Nautilus extension for an open terminal shortcut
kbd.i696 : Tools for configuring the console (keyboard, virtual terminals, etc.)
minicom.i686 : A text-based modem control and terminal emulation program
ncurses-base.i686 : Descriptions of common terminals
ncurses-term.i686 : terminal descriptions
openct.i686 : Middleware framework for smart card terminals
perl-TermReadKey.i686 : A perl module for simple terminal control
rdesktop.i686 : X client for remote desktop into Windows terminal Server
screen.i686 : A screen manager that supports multiple logins on one terminal
tn5250.i686 : 5250 Telnet protocol and terminal
tsclient.i686 : Client for VNC and Windows terminal Server
vte.i686 : A terminal emulator
x3270.i686 : An X Window System based IBM 3278/3279 terminal emulator
x3270-text.i686 : IBM 3278/3279 terminal emulator for text mode
x3270-x11.i686 : IBM 3278/3279 terminal emulator for the X Window System
xterm.i686 : terminal emulator for the X Window System

24.3.1 Installing Packages With yum


The yum utility is the preferred command to install packages since it will resolve dependency issues for you. For
example, to install x3270-x11 package, an administrator could execute the following:

[sysadmin@localhost ~]$ su -
Password:
[root@localhost ~]# yum install x3270-x11

After some output that shows how it is resolving dependencies, the output from this yum command would look like
the following:

================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
x3270-x11 i686 3.3.6-10.5.el6 base 416 k
Installing for dependencies:
libicu i686 4.2.1-9.1.el6_2 base 5.0 M
x3270 i686 3.3.6-10.5.el6 base 136 k

Transaction Summary
================================================================================
Install 3 Package(s)
Total download size: 5.5 M
Installed size: 20 M
Is this ok [y/N]:

At the Is this ok [y/N]: prompt, if y is typed followed by the Enter key, then all three packages will be
installed. As the output shows, it will be installing the requested package x3270-x11 and the dependencies
packages (libicu and x3270).
The Is this ok [y/N] prompt can be skipped by adding the -y option to the yum command. The following
command would install the x3270-x11 and its dependencies without any confirmation prompt:

⁠ 
[root@localhost ~]# yum -y install x3270-x11

The yum command has the ability to install many packages at once. List multiple package names with the yum
install command:

[root@localhost ~]# yum install telnet telnet-server ftp vsftpd

The previous command would install four packages and any of their dependencies.

Multiple packages can also be installed using yum groups. A yum group is a collection of packages that work
together to create a large piece of software. For example, the GUI software called Gnome isn't just a single
package, but rather a collection of packages working together to provide a GUI environment.

Use the yum grouplist command to list all of the groups that are installed on a system, as well as groups that are
available:

[root@localhost ~]# yum grouplist | head


Loaded plugins: fastestmirror, refresh-packagekit, security
Setting up Group Process
Loading mirror speeds from cached hostfile
* base: centosb6.centos.org
* extras: centosd6.centos.org
* updates: centosk3.centos.org
Installed Groups:
Additional Development
Base
Desktop

To see details about a specific group, use the yum groupinfo command:

[root@localhost ~]# yum groupinfo "Perl Support"


Loaded plugins: fastestmirror, refresh-packagekit, security
Setting up Group Process
Loading mirror speeds from cached hostfile
* base: centosb6.centos.org
* extras: centosd6.centos.org
* updates: centosk3.centos.org

Group: Perl Support


Description: Perl interfaces to common libraries and functionality.
Mandatory Packages:
perl
Default Packages:
perl-Crypt-SSLeay
perl-XML-Dumper
perl-XML-Grove
perl-XML-Twig
perl-core
Optional Packages:
perl-DBD-SQLite
perl-Date-Calc
perl-Date-Manip
perl-Frontier-RPC
perl-LDAP
Use the yum groupinstall command to install a group of packages. The group names that have spaces will have
to be contained in quotes:

[root@localhost ~]# yum groupinstall "Office Suite and Productivity"

Consider This

The only packages that are installed with the yum groupinstall command are the ones listed as either Default or
Mandatory (see the output of the yum groupinfo command in the previous example). Use the yum install
command to install any of the packages that are listed under Optional Packages.

24.3.2 Removing Packages With yum


If you have a choice as an administrator, you should also use the yum command to remove packages as it will
resolve dependency issues for you. When removing a package that has other packages that depend upon it, then the
yum command will offer to remove the dependencies.

For example, if an attempt is made to remove the libicu package, then the yum command would offer to also
remove the x3270 and x3270-x11 packages. The yum command supports using either the remove or erase
command:

[root@localhost ~]# yum remove libicu


[root@localhost ~]# yum erase libicu

The output from both commands shows that it will remove not only the requested package, but the two other
packages that depend upon the libicu package:

================================================================================
Package Arch Version Repository Size
================================================================================
Removing:
libicu i686 4.2.1-9.1.el6_2 @base 19 M
Removing for dependencies:
x3270 i686 3.3.6-10.5.el6 @base 383 k
x3270-x11 i686 3.3.6-10.5.el6 @base 768 k

Transaction Summary
================================================================================
 ⁠
Remove 3 Package(s)

Installed size: 20 M
Is this ok [y/N]:

The above action can be confirmed by typing y and pressing the Enter key. The use of the -y option is discouraged
for erasing packages, to prevent the accidental removal of a package that is needed.

To remove an entire group of commands, use the yum groupremove command followed by the group name.
24.3.3 Updating Packages With yum
Using the yum list updates command will cause the system to connect to repositories on the internet to identify
newer versions or releases of packages and list them. By using the yum update command, the system will
download and update all possible packages after requesting confirmation.

To update one or more individual packages, the following syntax can be used:

yum update [PACKAGE]...

As previously mentioned with the rpm command, the kernel packages should always be installed and not updated.
This applies to the rpm command, but not to the yum command because yum is aware of the special nature of the
kernel package. Even if the command yum update kernel is used, the yum command will install an updated
kernel, not update it.

24.4 Installing Packages With DNF


Dandified Yum, or DNF, is the next upcoming version of the yum command. This package management tool was
introduced in the Red Hat sponsored Fedora 18 Linux distribution. DNF is designed to solve package management
dependency issues, also referred to as depsolve problems, that were present in yum. Due to the growth in the
creation and use of applications, retrieving applications has become increasingly complex, resulting in more
dependency issues. DNF includes an upgraded dependency solver called state-of-the-art-satisfiability (SAT)
dependency solver to address dependency issues.

Another benefit of DNF over yum is a clearly documented Application Programming Interface (API). The API is
the interface that allows applications to work with other applications. Regular users typically won’t have to interact
at the API level when using applications as this is done by the developers of the applications. However, a poorly
documented API can result in slow development or upgrade of applications. DNF is designed with a strict API for
plugins and extensions and it mostly maintains command line compatibility with yum.

Consider This

In the previous output of package installs, you may have noted the terms plugins and extension:

Loaded plugins:
nautilus-open-terminal.i686 : Nautilus extension for an open terminal shortcut

Generally speaking, these terms refer to software modules that add functionality to an application. The terms
plugin and extension are not used consistently throughout computing. In the case of DNF, a plugin refers to
software that provides extra functionality to DNF and modifies the DNF installation itself. Therefore, when you
run DNF utilities, the plugins’ capabilities are available. This is analogous to adding new command line options to
a command.

Extensions are programs that import DNF functionality through DNF's Python libraries. They do not modify the
DNF installation. This is analogous to adding a new command, versus adding options to a well-known command.

To start using DNF, the dnf command can be executed using the following syntax:

dnf [OPTIONS] <COMMAND> [<ARGUMENTS>...]


Similar to the yum command, the dnf command uses the list command with the --available argument to list all
available packages on the system:

[root@localhost ~]# dnf list --available


Last metadata expiration check: 0:25:49 ago on Sat Jun 22 23:41:27 2019.
Available Packages
cowsay.noarch 3.04-4.el7 mnt_local_repo_

The output above indicates that the cowsay.noarch package is available for install. To install the cowsay.noarch
package, the install option can be used:

[root@localhost]# dnf install cowsay.noarch


added from: file:///mnt/local_repo/ 935 kB/s | 1.6 kB 00:00
Dependencies resolved.
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
cowsay noarch 3.04-4.el7 mnt_local_repo_ 42 k

Transaction Summary
================================================================================
Install 1 Package

Total size: 42 k
Installed size: 77 k
Is this ok [y/N]: y
Downloading Packages:
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : cowsay-3.04-4.el7.noarch 1/1
Verifying : cowsay-3.04-4.el7.noarch 1/1

Installed:
cowsay-3.04-4.el7.noarch

Complete!

To verify that the cowsay.noarch package was successfully installed, list the recently installed packages using the
list command with the --installed option:

[root@localhost ~]# dnf list --installed


Installed Packages
acl.x86_64 2.2.51-14.el7 @System

audit-libs.x86_64 2.8.4-4.el7 @System

basesystem.noarch 10.0-7.el7.centos @System

bash.x86_64 4.2.46-31.el7 @System

bind-license.noarch 32:9.9.4-73.el7_6 @System

binutils.x86_64 2.27-34.base.el7 @System

bzip2-libs.x86_64 1.0.6-13.el7 @System

ca-certificates.noarch 2018.2.22-70.0.el7_5 @System


centos-release.x86_64 7-6.1810.2.el7.centos @System

chkconfig.x86_64 1.7.4-1.el7 @System

coreutils.x86_64 8.22-23.el7 @System

cowsay.noarch 3.04-4.el7 @mnt_local_r


epo_ cpio.x86_64
2.11-27.el7 @System

cpp.x86_64 4.8.5-36.el7_6.1 @System


Output Omitted...

Based on the output above, the cowsay.noarch package has been installed and the cowsay command can now be
used on the system:

[root@localhost sysadmin]# exit


exit
[sysadmin@localhost ~]$ cowsay Learning Linux is easy!
_________________________
< Learning Linux is easy! >
-------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
[sysadmin@localhost ~]$
24.5 Debian Package Management
Debian's package management system is based upon the format used to package the software files for the Debian
distribution; these package file names end in the .deb extension. The Debian package management system is used
by many other distributions including Ubuntu and Mint Linux. These .deb files are archives that contain the
software and the information to configure it for installation or removal.

The .deb packages contain binary files compiled to execute on a particular computer architecture. In the Debian's
package management system, the source packages, which contain the original source, have the .dsc extension.

While software packages are often installed from either a CD-ROM or a DVD during the installation process of a
Debian-derived distribution, package files are also commonly installed by downloading them directly from
repositories located on internet servers. The primary configuration file that is used to locate these repositories is the
/etc/apt/sources.list file.

Before working with packages, run the apt-get update command. This will ensure that the system has a current
list of the packages that are available in the repositories listed in the /etc/apt/sources.list file. Debian
package files follow a naming convention that makes it easy to determine the package name, version, release, and
architecture. For example, the joe_3.7-2.3_i386.deb file uses this generic pattern:

package-name_version-release_architecture.deb

Package Name

joe_3.7-2.3_i386.deb

The package name is the first part of the file name up to the first underscore _ character.

Version

joe_3.7-2.3_i386.deb

The version is the second part of the file name. It starts after the first underscore and continues until a hyphen -
character is found.

Release

joe_3.7-2.3_i386.deb

The third part of the file name is the release. The release is set by the organization that packages and distributes the
package file. The release starts after the hyphen following the version and ends before the underscore _ character
before the architecture.

Architecture

joe_3.7-2.3_i386.deb

The final part of the file name after the release, but before .deb is the architecture for which the package was
compiled. Not only does Debian support multiple PC architectures, including amd64, i386 and ia64, but numerous
other architectures like armel, armhf, mips, mipsel, powerpc, s390, s390x, and sparc. For the joe_3.7-
2.3_i386.deb package, the architecture of i386 indicates this package is built to run on a 32-bit Intel-compatible
processor.
The dpkg command is the most direct tool available for managing .deb packages. It can be used for installing,
removing, and querying packages for information, although other higher-level tools like synaptic, or the
Advanced Package Tool (APT) provide more powerful capabilities for managing dependencies between
packages. The synaptic command is a graphical user interface that allows an administrator to install, remove, and
update packages by navigating menus. Some of the commands that are a part of APT are discussed later in this
unit.

24.5.1 Installing Software With dpkg


To install a software package in a Debian-based distribution, use the -i option with the dpkg command. For
example, to install the joe_3.7-2.3_i386.deb file, execute:

Note

The following examples represent a system that is different from the virtual machine in this module. The examples
may not match the output in our virtual environment.

Additional practice for Debian package management is provided in the lab.

sysadmin@localhost:~$ dpkg -i joe_3.7-2.3_i386.deb

Debian packages also may have dependencies. There are four categories of dependencies: depends, recommends,
suggests, and enhances. Only the depends category reflects a package that must be installed in order to have the
required dependencies met.

As a low-level tool, dpkg does not provide any automatic way to resolve dependency issues. However, the APT
tool apt-get does have this capability, as will be discussed later in this chapter.

24.5.2 Removing Software With dpkg


There are a couple of ways that an administrator may remove a package, using the -r and -P options to the dpkg
command. The difference between using the -r option and the -P option is that the -r option removes the package
and the -P option purges the package. When a package is removed, almost all of its files are removed except for its
configuration files. When a package is purged, all of the package files are removed, including the configuration
files.

The idea behind removing a package, but not removing its configuration files, is that the configuration files may be
used again in the future if the package is reinstalled.

Consider a scenario in which the joe package is installed to test the text editor that the package provides. After
testing, the administrator has decided that they do not like that editor and would never install it again. Since the
plan is to never install the package again in the future, the package could be purged from the system by the
administrator executing the dpkg -P joe command.
24.5.3 Listing Packages With dpkg
The dpkg command can retrieve a list of the packages that are installed on the system, or list the files that are in a
package. For example, to see all the packages that are currently installed on a system, execute the dpkg -l
command:

sysadmin@localhost:~$ dpkg -l
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==============-============-============-=================================
ii adduser 3.113+nmu3ub all add and remove users and groups
ii apt 1.0.1ubuntu2 amd64 command-line package manager
ii apt-file 2.5.2ubuntu1 all search for files within Debian pa
ii apt-utils 1.0.1ubuntu2 amd64 package management related utilit
ii apt-xapian-ind 0.45ubuntu4 all maintenance and search tools for
...

The output of the dpkg -l command contains five pieces of information:

 The first two pieces of this information are represented by a two-letter code:
 The first letter reflects the desired status of the package, which can be i for installed, u for
unknown, r for remove or h for hold.
 The second letter represents the actual status of the package, where i means installed, and n means
not installed.
 The most common two-letter codes are ii for fully installed and un for not installed.
 The remaining columns show the package name, version (combined with the release), the architecture, and
the description of the package if it is available.

The dpkg -l PACKAGE-NAME-PATTERN command can also be used to list packages based on a glob pattern. For
example, to view all packages that might contain python in the package name, use the dpkg -l "*perl*"
command.

sysadmin@localhost:~$ dpkg -l "*perl*"


Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==============-============-============-=================================
un dh-make-perl <none> <none> (no description available)
un libalien-wxwid <none> <none> (no description available)
un libansicolor-p <none> <none> (no description available)
un libanyevent-pe <none> <none> (no description available)
un libarchive-tar <none> <none> (no description available)
un libattribute-h <none> <none> (no description available)
un libautodie-per <none> <none> (no description available)
un libcommon-sens <none> <none> (no description available)
un libcompress-ra <none> <none> (no description available)
un libcompress-ra <none> <none> (no description available)
un libcompress-zl <none> <none> (no description available)
un libcpan-meta-p <none> <none> (no description available)
un libcpan-meta-r <none> <none> (no description available)
un libcpan-meta-y <none> <none> (no description available)
un libdigest-md5- <none> <none> (no description available)
un libdigest-perl <none> <none> (no description available)
un libdigest-sha- <none> <none> (no description available)
Output Omitted...
Using the -L option with dpkg will list the files that a package contains. For example, to view the files that are a
part of the package named perl, execute the dpkg -L perl command.

sysadmin@localhost:~$ dpkg -L python


/.
/etc
/etc/perl
/etc/perl/CPAN
/etc/perl/Net
/etc/perl/Net/libnet.cfg
/usr
/usr/bin
/usr/bin/corelist
/usr/bin/cpan
/usr/bin/enc2xs
/usr/bin/encguess
/usr/bin/h2ph
/usr/bin/h2xs
/usr/bin/instmodsh
/usr/bin/json_pp
/usr/bin/libnetcfg
/usr/bin/perlbug
/usr/bin/perldoc
Output Omitted...

Incidentally, if you know the pathname for a file, then it is possible to determine which package was responsible
for providing that file by using the -S option with the dpkg command. For instance, to discover the package that
provided the /usr/bin/perldoc file, execute the dpkg -S /usr/bin/perldoc command.

sysadmin@localhost:~$ dpkg -S /usr/bin/pydoc


perl: /usr/bin/perldoc

By using the dpkg command with the -s option and a package name, the following package information will be
displayed:

 Status (including whether the package is installed)


 Size
 Organization that maintains the package
 Dependencies
 Description

Try executing dpkg -s perl in the terminal for yourself. It should be noted that all of the example outputs
presented above were shortened for the sake of brevity. Feel free to try any of these examples in the terminal as
well, in order to see their full outputs.
24.5.4 Configuring Packages With dpkg-reconfigure
As part of the process of installing a package, the Debian package management system will also configure that
package. If the package needs to be reconfigured at some later point, execute the dpkg-reconfigure command.
To execute the dpkg-reconfigure command, the following syntax can be used:

dpkg-reconfigure [OPTIONS...] PACKAGES...

⁠ A good example of using the dpkg-reconfigure command is with the tzdata package. When this package is
configured, the administrator sets the time zone information for the computer's current location. If a system is
moved to another location, particularly in a different time zone, then this package should be reconfigured by
executing the dpkg-reconfigure tzdata command.

Note

The following example represents a system that is different from the virtual machine in this module. The example
may not match the output in our virtual environment.

root@localhost:~# dpkg-reconfigure tzdata


24.5.5 Searching for Packages With apt-cache
If the system has the appropriate repositories configured in the /etc/apt/sources.list file and the administrator
has already refreshed the cached information about which packages are available by executing the apt-get
update command, then any user can search for packages by using the apt-cache search command with the
following syntax:

apt-cache search KEYWORD

The keyword that is used should match part of the name or description of the package to be located. Multiple
keywords can be used to clarify the search further; for example, the apt-cache search web server command
would provide better results than the apt-cache search web or apt-cache search server command.

sysadmin@localhost:~$ apt-cache search medusa


medusa - fast, parallel, modular, login brute-forcer for network services
python-medusa - Framework for implementing asynchronous servers
python-medusa-doc - Framework for implementing asynchronous servers

The apt-cache command can also search for packages in a different way. To find out which dependencies a
package has, the apt-cache depends PACKAGE command will list the packages required by the package-name.
For example, to determine the dependencies of the apache2 package, execute the apt-cache depends apache2
command.

sysadmin@localhost:~$ apt-cache depends apache2


apache2
PreDepends: dpkg
Depends: lsb-base
Depends: procps
Depends: perl
Depends: mime-support
Depends: apache2-bin
Depends: apache2-utils
Depends: apache2-data
Depends: <perl:any>
perl
Conflicts: <apache2.2-bin>
Conflicts: <apache2.2-common>
Recommends: ssl-cert
Suggests: <www-browser>
dillo
edbrowse
hv3
lynx
chromium-browser
elinks
epiphany-browser
falkon
firefox
konqueror
links
links2
netrik
sugar-browse-activity
surf
w3m
wslu
xemacs21-mule
xemacs21-mule-canna-wnn
xemacs21-nomule
Suggests: apache2-doc
|Suggests: apache2-suexec-pristine
Suggests: apache2-suexec-custom
Suggests: ufw
Replaces: <apache2.2-bin>
Replaces: <apache2.2-common>

 The apt-cache show PACKAGE command can also display the status of a package with information similar to the
output of the dpkg -s PACKAGE command, but the apt-cache command displays more detailed information,
including checksums that could be used to verify the original package.
24.5.6 Installing/Updating Packages With apt-get
After searching for a package, you may want to install that package and its required dependencies. Using the apt-
get install PACKAGE command will download and prompt the administrator to install that package as well as its
dependencies. For example, to install the apache2 package and its dependencies, execute the apt-get install
apache2 command with administrative privileges:

Note

The sudo command requires the root password netlab123 in our virtual environment.

sysadmin@localhost:~$ sudo apt-get install apache2


[sudo] password for sysadmin:
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
apache2-bin apache2-data apache2-utils libapr1 libaprutil1
libaprutil1-dbd-sqlite3 libaprutil1-ldap libasn1-8-heimdal
libgssapi3-heimdal libhcrypto4-heimdal libheimbase1-heimdal
libheimntlm0-heimdal libhx509-5-heimdal libkrb5-26-heimdal libldap-2.4-2
libldap-common liblua5.2-0 libnghttp2-14 libroken18-heimdal libsasl2-2
libsasl2-modules libsasl2-modules-db libwind0-heimdal ssl-cert
Suggested packages:
www-browser apache2-doc apache2-suexec-pristine | apache2-suexec-custom
libsasl2-modules-gssapi-mit | libsasl2-modules-gssapi-heimdal
libsasl2-modules-ldap libsasl2-modules-otp libsasl2-modules-sql
openssl-blacklist
The following NEW packages will be installed:
apache2 apache2-bin apache2-data apache2-utils libapr1 libaprutil1
libaprutil1-dbd-sqlite3 libaprutil1-ldap libasn1-8-heimdal
libgssapi3-heimdal libhcrypto4-heimdal libheimbase1-heimdal
libheimntlm0-heimdal libhx509-5-heimdal libkrb5-26-heimdal libldap-2.4-2
libldap-common liblua5.2-0 libnghttp2-14 libroken18-heimdal libsasl2-2
libsasl2-modules libsasl2-modules-db libwind0-heimdal ssl-cert
0 upgraded, 25 newly installed, 0 to remove and 28 not upgraded.
Need to get 2896 kB of archives.
After this operation, 11.2 MB of additional disk space will be used.
Do you want to continue? [Y/n]n

Important

Our virtual environment is not configured to download this package. At the Do you want to continue? prompt,
type n to cancel the install.

The apt-get install PACKAGE command can also update a package, if that package is installed and a newer
version is available. If the package is not already on the system, it would be installed; if it is on the system, it
would be updated. To only update, execute the apt-get --only-upgrade install PACKAGE command.

sysadmin@localhost:~$ sudo apt-get --only-upgrade install apache2

 To update all packages of the system, two commands are executed. First, the apt-get update command to update
the cache of all packages available should be executed. Second, execute the apt-get upgrade command; all
packages and dependencies will be updated
24.5.7 Removing/Purging Packages With apt-get
Just as the dpkg command is able to either remove or purge a package, so can the apt-get command. Recall that
the difference between the two is that purging deletes all package files, while removing deletes all but the
configuration files for the package.

⁠ 

An administrator can execute the apt-get remove PACKAGE command to remove a package or the apt-get
purge PACKAGE command to purge a package completely from the system. For example, to purge the web server
completely, execute the apt-get purge apache2 command.

sysadmin@localhost:~$ sudo apt-get purge apache2

24.6 Verifying Files with Checksums


Countless files are available on the internet. From installation ISO files and application programs, to utilities that
aid in managing users and systems, the world of open source computing provides an almost endless selection of
useful code and executables.

Early on, it was recognized that verifying the integrity of files was critical for users, administrators, and
programmers that wanted to transfer data over computer networks. Systems connected by modems and telephone
lines were subject to frequent transmission errors. More recent threats include hackers attempting to replace
genuine software with malware versions.

A checksum is a small piece of complementary data used to verify the integrity of a file (for example, F1). The
file’s creator generates a checksum by applying a cryptographic hashing algorithm to the file’s contents. The
resulting checksum (C1) is irreversible and highly unique. The creator can now confidently share the file (F1) and
the checksum (C1) with others. Recipients who obtain a copy of the file (F2) can verify integrity by repeating the
same hashing algorithm on the copy (F2), producing a new checksum (C2). If the two checksums match (C2 = C1),
the recipient can be confident that their copy of the file is identical to the original (F2 = F1). If the checksums do
not match, the copied file (F2) is corrupted and untrustworthy.

Consider This

A checksum verifies the integrity the downloaded file, but does not verify the authenticity of the sender. If you
trust a file and checksum received from a bad actor, you can still receive malware or tampered data even if the
checksum validation process passes. To solve this problem, some type of public key authentication is typically
added to the file exchange process to verify the authenticity of the sender as well.
24.6.1 md5sum
The md5sum command, based on the MD5 (message-digest 5) algorithm, creates a 128-bit hash using the original
file.

The following syntax can be used to create a checksum with the md5sum command:

md5sum [OPTIONS]... [FILE]...

Create a file in the /tmp directory and create the hash using the md5sum command and view the result:

[sysadmin@localhost]$ touch anyfile.txt


[sysadmin@localhost]$ md5sum anyfile.txt > anyfile.md5
[sysadmin@localhost]$ ls
anaconda-post.log anyfile.md5 anyfile.txt ks-script-mbvg2Y yum.log
[sysadmin@localhost]$ cat anyfile.md5
d41d8cd98f00b204e9800998ecf8427e anyfile.txt

In the output above, the checksum that was generated appears in the anyfile.md5 file:

41d8cd98f00b204e9800998ecf8427e

As you can see from the output of the following command, this is the same number sequence that appears if you
were to execute the md5sum command with the anyfile.txt file as an argument:

[sysadmin@localhost]$ md5sum anyfile.txt


d41d8cd98f00b204e9800998ecf8427e anyfile.txt

The md5sum command can also be used to authenticate the file(s) with the check -c option. This is the option used
to verify the integrity of the file by comparing the computed checksum of the file with the previously generated
.md5 file.

[sysadmin@localhost]$ md5sum -c anyfile.md5


anyfile.txt: OK

Warning

The algorithm used for MD5 is no longer considered secure and should not be relied on for files that might be
intentionally tampered with. It can still be used for checking known files in situations where security isn’t a
concern.

24.6.2 sha256sum
The sha256sum command creates a 256-bit checksum number that can be used to verify a file. This command uses
a similar syntax to that of the md5sum command:

sha256sum [OPTIONS]... [FILE]...

Use the sha256sum command to create the checksum for the anyfile.txt file:

[sysadmin@localhost]$ sha256sum anyfile.txt > anyfile.sha256


[sysadmin@localhost]$ cat anyfile.sha256
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 anyfile.txt

Similar to the md5sum command, the sha256sum command can be used with the -c option to verify the integrity of
the file:

[sysadmin@localhost]$ sha256sum -c anyfile.sha256


anyfile.txt: OK

24.6.3 sha512sum
The sha512sum command creates an even more secure 512-bit checksum for verifying files using the familiar
syntax:

sha516sum [OPTIONS]... [FILE]...

Use the sha512sum command to create a 512-bit checksum for the anyfile.txt file:

[sysadmin@localhost]$ sha512sum anyfile.txt > anyfile.sha512


[sysadmin@localhost]$ cat anyfile.sha512
cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0
ff8318d2877eec2f63b931bd47417a81a538327af927da3e anyfile.txt

Again, as with both the md5sum command and the sha256sum command, the -c option is used to verify the
integrity of the file:

[sysadmin@localhost]$ sha512sum -c anyfile.sha512


anyfile.txt: OK
24.7 SUSE Package Management
Several distributions use the ZYpp/libzypp package management engine, which primarily runs on openSUSE,
SUSE Linux Enterprise, and Ark. Libzypp is the merged result of Ximian’s Red Carpet and SUSE’s YaST
software management engines. Libzypp was designed to perform as the software package management scheme for
SUSE products as well the failed and now mostly dormant Zenworks Linux Management suite from Novell.

What the APT system and .deb packages are on the Debian/Ubuntu side, Libzypp and zypper are to the RPM side
of package management on the SUSE platform. The need to query, install, remove, and update software packages
is universal, as well as the all-important ability to satisfy software dependencies during these actions.

The underlying dependency or satisfiability solver technology is the key to successfully being able to perform
package management tasks on systems that can contain anywhere from hundreds to many thousands of individual
packages, all with many dependencies on each other.

For example, the libc library on a Linux system is a dependency for almost every other package subsequently
installed. If libc is absent or incorrectly versioned, it could be catastrophic to the entire system.

When a system is installed, the software packages must be installed in an exact order that ensures all dependencies
are resolved. This is difficult enough at installation. Updating hundreds of packages is especially challenging on a
running system that is a critical part of a company’s infrastructure.

While ZYpp/libzypp is the background package management engine, which is in charge of satisfying the
dependencies between packages, most system operators will interact mainly with the zypper command line tool.

An important part of software management is the concept of repositories, which are essentially a shared network
resource or local directory that provides a location for searching for software to install and update. Repositories
come in several varieties, the first being those that are official and supported, such as the subscription
channels/repositories that the SCC (SUSE Customer Center) provides for those with support subscriptions.

The next variety is a 3rd-party repository. An excellent example of which is the Packman repository for the
openSUSE community, where a lot of software that is not part of the official openSUSE or SUSE Linux Enterprise
distributions can be found.

The last variety is the local mirror or synchronized repository that an organization will use to maintain a local copy
of the software that can be used by their internal or public-facing systems. The advantage of this third variety is
that it keeps the number of hosts that query and mirror from the official software repositories to as low a number as
possible. This is useful because the various supported subscription-based distributions all highly recommend a
mirror or sync server.

The command-line zypper tool's relationship to the rpm command is roughly analogous to the relationship between
the apt-get tool’s relationship to the dpkg command. The zypper command is used to query, install, remove,
update, manage repositories, and more; it depends on the rpm command’s abilities to accomplish most of these
tasks.

For example, a system operator could install a package with the rpm command, but if it had several dependencies,
the system operator must then determine what packages are additionally needed and then install the dependencies
and the initial package in the exact right order to be successful.

Using zypper to install the same package is much easier, as it will do the hard work of reading the desired
package’s dependencies, query the database of installed packages for those, and if they are not found, determine
which software repository from the list of configured repositories that they may be obtained from. Then, the
zypper command will inform the system operator of what is needed to install the desired package successfully.

The syntax used for the zypper command examples in this course is the following:

zypper [--GLOBAL-OPTS] COMMAND [--COMMAND-OPTS] [COMMAND-ARGUMENTS]

To learn more about the zypper command’s syntax and usage, use the zypper help command:

localhost:~ # zypper help

Note

The zypper command is not installed in the virtual environment provided in this chapter. The following examples
represent a system that is different from the virtual machine in this chapter. As such, the examples in the following
sections may not match the output in our virtual environment.

Additional practice for the zypper command is provided in the lab.


24.7.1 Searching for Packages with zypper
Before a system operator does anything substantial with the zypper command, it is critical to refresh the
information that zypper has about the repositories that the commands in this section will be querying and installing
software from. The refresh ref command can be used to refresh the repository:

sysadmin@localhost:~> su -
Password:
localhost:~ # zypper ref
Repository 'sle-module-basesystem' is up to date. Repository
'sle-module-desktop-applications' is up to date. Repository 'sle-module-
development-tools' is up to date. Repository 'Non-OSS' is up to date.
Repository 'SLES15-15-0' is up to date.
Repository 'SLES' is up to date.
Repository 'sle-module-server-applications' is up to date. All
repositories have been refreshed.

To find a package to install, use the search se command to query the configured repositories on the system.

zypper se PACKAGE

For example, to search for the gvim package, use the following:

localhost:~ # zypper se gvim


Loading repository data...
Reading installed packages...

S | Name | Summary | Type


--+------+--------------+--------
| gvim | A GUI for Vi | package

The example searches for the graphical version of the vim command, gvim, and shows several useful pieces of
information about the package. The first column, S, is the status column, and based on the output above, this
package is not installed—if it was, there would be an i in this column.

The rest of the line is fairly easy to grasp; the Name, a Summary and the Type of result are noted.
24.7.2 Installing Packages with zypper
The zypper command can be used with the install in command to install packages.

zypper in PACKAGE

To install the gvim package, including any necessary dependencies, use the following command:

localhost:~ # zypper in gvim


Loading repository data...
Reading installed packages...
Resolving package dependencies...

The following NEW package is going to be installed:


gvim

1 new package to install.


Overall download size: 1.6 MiB. Already cached: 0 B. After the operation, additional 3.2 MiB
will be used.
Continue? [y/n/...? shows all options] (y): y
Retrieving package gvim-8.0.1568-3.20.x86_64 (1/1), 1.6 MiB (
3.2 MiB unpacked)
Checking for file conflicts: ........................................[done]
(1/1) Installing: gvim-8.0.1568-3.20.x86_64 .........................[done]

Now that the gvim package is installed, re-running the zypper se gvim command again would show an i in the
Status column to show gvim is installed.

localhost:~ # zypper se gvim


Loading repository data...
Reading installed packages...

S | Name | Summary | Type


--+------+--------------+--------
i | gvim | A GUI for Vi | package

If for some odd reason a package is installed and doesn’t work or is damaged, it’s important to know how to
reinstall it in order to fix the issue, hopefully.

To re-install (and force the overwriting of) the gvim package, as the root user, use the command:

localhost:~ # zypper in gvim


Loading repository data...
Reading installed packages...
Forcing installation of 'gvim-8.0.1568-3.20.x86_64' from repository 'sle-module-desktop-
applications'.
Resolving package dependencies...

The following package is going to be reinstalled:


gvim

1 package to reinstall.
Overall download size: 1.6 MiB. Already cached: 0 B. No additional space will be used or
freed after the operation.
Continue? [y/n/...? shows all options] (y): y
Retrieving package gvim-8.0.1568-3.20.x86_64 (1/1), 1.6 MiB (
3.2 MiB unpacked)
Checking for file conflicts:..........................................[done]
(1/1) Installing: gvim-8.0.1568-3.20.x86_64...........................[done]
24.7.3 Managing repositories with zypper
Any Linux system will regularly require updating, patching, and fixes. With all the new packages, updates to
existing packages, security fixes, and patches, it can be a lot of work to keep a Linux system up-to-date unless you
use a dependency-solving solution like APT or ZyPP/Libzypp.

The zypper command interacts a lot with software repositories, which are the gathered collections of software for
different purposes.

To query the software repositories on a system, use the zypper command with the list repositories lr option:

localhost:~ # zypper lr
Repository priorities in effect: (See 'zypper
lr -P' for details)
99 (default priority) : 6 repositories
100 (lowered priority) : 1 repository

# | Alias | Name |Enabled | GPG Check


| Refresh
--+----------------------------------+---------------------------------+---------+----------
-+--------
1 | Basesystem-Module_15-0 | sle-module-basesystem | Yes | (r ) Yes
| No
2 | Desktop-Applications-Module_15-0 | sle-module-desktop-applications | Yes | (r ) Yes
| No
3 | Development-Tools-Module_15-0 | sle-module-development-tools | Yes | (r ) Yes
| No
4 | Non-OSS | Non-OSS | Yes | (r ) Yes
| No
5 | SLES15-15-0 | SLES15-15-0 | Yes | (r ) Yes
| No
6 | SLES15_15-0 | SLES | Yes | (r ) Yes
| No
7 | Server-Applications-Module_15-0 | sle-module-server-applications | Yes | (r ) Yes
| No

To add a repository to install additional software from, first find the repository URL, then use the add repository -
ar option:

localhost:~ # zypper ar -f http://packman.inode.at/suse/openSUSE_Leap_15.1/ packman


Adding repository 'packman'.............................................[done]
Repository 'packman' successfully added

URI : http://packman.inode.at/suse/openSUSE_Leap_15.1/
Enabled : Yes
GPG Check : Yes
Autorefresh : Yes
Priority : 99 (default priority)

Repository priorities in effect: (See 'zypper


lr -P' for details)
99 (default priority) : 7 repositories
100 (lowered priority) : 1 repository

Notice that there is a URI/URL and a nickname (packman) that must both be present for the command to work.

At this time, the zypper ref command would be run again to update the system with the latest metadata from all
repositories, which will prompt for trusting the repository key.
localhost:~ # zypper ref
Repository 'packman' is up to date.
All repositories have been refreshed.

When the query of the new repository is successful, the system can be updated or software operations are
undertaken.

localhost:~ # zypper list-updates -t package


retrieving repository 'packman' metadata ---------------------------------------------------
----------------[|]

New repository or package signing key received:

Repository: packman
Key Name: PackMan Project (signing key) <packman@links2linux.de>
Key Fingerprint: F8875B88 0D518B6B 8C530D13 45A1D067 1ABD1AFB
Key Created: Mon Sep 15 16:18:00 2014
Key Expires: Thu Sep 12 16:17:21 2024
Rpm Name: gpg-pubkey-1abd1afb-54176598

Do you want to reject the key, trust temporarily, or trust always? [r/t/a/? shows all
options] (r): a
Retrieving repository 'packman' metadata ........................[done]
Building repository 'packman' cache..............................[done]
Loading repository data...
Reading installed packages...
No updates found.
24.7.4 Updating Packages with zypper
The zypper command can also be used to update the packages in a repository.

zypper -list-updates PACKAGE

To see a listing of all the packages that are available for update from your repositories, you would use the list-
updates command:

localhost:~ # zypper list-updates -t gvim


Loading repository data...
Reading installed packages...
No updates found.

To perform an update of the system, (which will locate all updates in the configured repositories and perform a
dependency-solve on them) use the update command:

localhost:~ # zypper update


Loading repository data...
Reading installed packages...
No updates found.

Depending on the system and when it was installed, there may be no updates. If there are, they will be listed and
the user queried to indicate if they want to download and install the updates. There are several options for updating
the system in an unattended fashion, and the documentation is excellent.
Key Terms
/etc/apt/sources.list
The package resource list is used to locate archives of the package distribution system in use on the system.
Section 24.5.5
/etc/yum.conf
Configuration file for the YUM package manager.
Section 24.3
/etc/yum.repos.d/
The directory housing YUM configuration files.
Section 24.3
apt-cache
Performs a variety of operations on APT's package cache including operations to search and generate
interesting output from the package metadata.
Section 24.5.5
apt-get
Command-line tool for handling packages.
Section 24.5.6 | Section 24.5.7
dpkg
A tool to install, build, remove and manage Debian packages.
Section 24.5 | Section 24.5.1 | Section 24.5.2 | Section 24.5.3 | Section 24.5.4
dpkg-reconfigure
Utility used to change the settings of individual packages that are registered during installation. These
settings are determined by questions in a package's installation script and modified to reflect the updated
responses.
Section 24.5.4
md5sum
Command based on the MD5 (message-digest 5) algorithm which creates a 128-bit hash using the original
file.
Section 24.6.1
rpm
A powerful Package Manager, which can be used to build, install, query, verify, update, and erase
individual software packages.
Section 24.2 | Section 24.2.1 | Section 24.2.2 | Section 24.2.3 | Section 24.2.4
rpm2cpio
Takes an RPM package file and converts it to a cpio archive.
Section 24.2.5
sha256sum
Command that creates a 256-bit checksum number that can be used to verify a file.
Section 24.6.2
sha512sum
A command that creates a secure 512-bit checksum for verifying files.
Section 24.6.3
yum
Yellow Dog Updater - an interactive, automated update program which can be used for maintaining
systems using rpm.
Section 24.3 | Section 24.3.1 | Section 24.3.2 | Section 24.3.3
zypper
The command line tool for the ZYpp/Libzypp is the background package management engine.
Section 24.7
LAB 24

24.1 RPM Management


Please use the CentOS image to complete the following steps. Select the CentOS PC by clicking on the tab in the
window on the right side of the screen.
In order to provide the functionality you need to apply these concepts, this VM may require a minute or two to
load.

On Red Hat-based distributions, such as Fedora, CentOS, and Red Hat Enterprise Linux, the system that is used to
manage software is called the RPM Package Manager. This system includes a collection of tools that allows an
administrator to add and remove software packages. These tools also allow you to display currently installed
software packages as well as display available software packages.

24.1.1 Step 1
Log in to the system and switch to the root account. When prompted, provide the root password. Next, use the cd
command to change to the root level of the filesystem.

su
netlab123
cd /
This lab has two user accounts (username :: password )

root :: netlab123
sysadmin :: netlab123

Press the [Enter] key to begin...

[sysadmin@localhost ~]$ su
Password:
[root@localhost sysadmin]# cd /
[root@localhost /]#
24.1.2 Step 2
Display some of the installed software packages on the system by using the head command to display the first 10
packages. Execute the following command:

rpm -qa | head


[root@localhost /]# rpm -qa | head
nano-2.3.1-10.el7.x86_64
systemd-libs-219-62.el7_6.6.x86_64
libsolv-0.6.34-2.el7.x86_64
bash-4.2.46-31.el7.x86_64
hwdata-0.252-9.1.el7.x86_64
nss-softokn-freebl-3.36.0-5.el7_5.x86_64
libusbx-1.0.21-1.el7.x86_64
rpcbind-0.2.0-47.el7.x86_64
filesystem-3.2-25.el7.x86_64
tcp_wrappers-7.6-77.el7.x86_64

24.1.3 Step 3
To see details about a specific RPM, execute the following command:

rpm -qi setup


[root@localhost /]# rpm -qi setup
Name : setup
Version : 2.8.71
Release : 10.el7
Architecture: noarch
Install Date: Tue 28 May 2019 05:42:59 PM UTC
Group : System Environment/Base
Size : 696893
License : Public Domain
Signature : RSA/SHA256, Mon 12 Nov 2018 03:19:37 PM UTC, Key ID 24c6a8a7f4a80eb5
Source RPM : setup-2.8.71-10.el7.src.rpm
Build Date : Tue 30 Oct 2018 07:48:11 PM UTC
Build Host : x86-01.bsys.centos.org
Relocations : (not relocatable)
Packager : CentOS Buildsystem <http://bugs.centos.org>
Vendor : CentOS
URL : https://pagure.io./setup/
Summary : A set of system configuration and setup files
Description :
The setup package contains a set of important system configuration and setup files, such as
passwd, group, and profile.
Note that while the full name of the rpm is setup-2.8.71-10.el7.src.rpm, the version number and architecture
can be omitted when referring to the package.
24.1.4 Step 4
To view the scripts that are included with the package, execute the following command:

rpm -qi --scripts setup


[root@localhost /]# rpm -q --scripts setup
postinstall scriptlet (using <lua>):
for i, name in ipairs({"passwd", "shadow", "group", "gshadow"}) do
os.remove("/etc/"..name..".rpmnew")
end
if posix.access("/usr/bin/newaliases", "x") then
os.execute("/usr/bin/newaliases >//dev/null")
end

Note that in the example output provided, the postinstall scriptlet would be executed immediately after the
package was installed.

24.1.5 Step 5
Execute the following command to view the documentation that was included in the setup package:

rpm -q -d setup
[root@localhost /]# rpm -q -d setup
/usr/share/doc/setup-2.8.71/COPYING
/usr/share/doc/setup-2.8.71/uidgid

Knowing the location of the package's documentation is useful when you need to fix problems with the package or
configure elements of the package

24.1.6 Step 6
Display the status of the package files by executing the following command:

rpm -q -s setup | head


[root@localhost /]# rpm -q -s setup | head
normal /etc/aliases
normal /etc/bashrc
normal /etc/csh.cshrc
normal /etc/csh.login
normal /etc/environment
normal /etc/exports
normal /etc/filesystems
normal /etc/fstab
normal /etc/group
normal /etc/gshadow

Typically, this output should indicate normal for each file. If a file has not been installed, it will be listed as not
installed. This could result in the package not functioning correctly.
24.1.7 Step 7
Remove the quota package from the system with the following rpm command:

rpm -e quota
[root@localhost /]# rpm -e quota
[root@localhost /]#

Recall that the rpm command doesn't check for any package dependencies. As a result, you would not see any
warning if another package depended on the quota package.

24.1.8 Step 8
Determine what the quota package requires in order for it to work correctly by executing the following command:

rpm -qp --requires /mnt/local_repo/quota* | head


[root@localhost /]# rpm -qp --requires /mnt/local_repo/quota* | head
[root@localhost /]# rpm -qp --requires /mnt/local_repo/quota* | head
/bin/sh
/bin/sh
/bin/sh
/bin/sh
config(quota) = 1:4.01-17.el7
libc.so.6()(64bit)
libc.so.6(GLIBC_2.2.5)(64bit)
libc.so.6(GLIBC_2.3)(64bit)
libc.so.6(GLIBC_2.3.4)(64bit)
libc.so.6(GLIBC_2.4)(64bit)
[root@localhost /]#

Recall that this is a list of files, commands, libraries, and software packages that need to be on the system for this
package to function correctly.

24.1.9 Step 9
Install the quota package by executing the following command:

rpm -i /mnt/local_repo/quota*
[root@localhost /]# rpm -i /mnt/local_repo/quota*

The quota package is being installed from a local repository, a collection of packages that have been downloaded
from the internet ahead of time for this lab.
24.1.10 Step 10
To demonstrate the use of the rpm2cpio command, first remove the /usr/sbin/edquota file:

rm /usr/sbin/edquota
y
[root@localhost /]# rm /usr/sbin/edquota
rm: remove regular file `/usr/sbin/edquota'? y
Remember that the rpm2cpio command is useful in that it will allow you to extract files from the rpm without
installing the files. This is useful to recover a single file from the package (such as when you accidentally delete a
key software file like edquota).

24.1.11 Step 11
Try to execute the edquota command:

edquota
[root@localhost /]# edquota
bash: edquota: command not found

The previous command failed because you deleted the command from the system.

24.1.12 Step 12
In most cases, you won't know what package a file belongs to. You can determine this if you know the full path to
the package, but this also is something that you may not automatically know. If the file was installed as part of a
package, you could execute the following command to determine the full path to the file:

rpm -q -a -s | grep edquota


[root@localhost /]# rpm -q -a -s | grep edquota
normal /usr/sbin/edquota
normal /usr/share/man/man8/edquota.8.gz

24.1.13 Step 13
Based on the output of the previous command, you can now use the rpm command to determine which package
provided the /usr/sbin/edquota file. Execute the following command:

rpm -q -f /usr/sbin/edquota
[root@localhost /]# rpm -q -f /usr/sbin/edquota
quota-4.01-17.el7.x86_64
24.1.14 Step 14
Execute the following commands to extract all of the files from the quota package into the /tmp directory:

cd /tmp
rpm2cpio /mnt/local_repo/quota* | cpio -imud
[root@localhost /]# cd /tmp
[root@localhost tmp]# rpm2cpio /mnt/local_repo/quota* | cpio -imud
1783 blocks

It isn't really necessary to extract all of the files, but there are a couple of reasons why you might. To begin with,
using the -imud option to the cpio command is easier than trying to specify a single file to extract. Another reason
to extract all of the files is that it is likely that more than one file is missing.

24.1.15 Step 15
Execute the ls command to view the files in the current directory:

ls
[root@localhost tmp]# ls
etc usr

Notice that this command extracted all of the files from the quota RPM file, but didn't install the files. They are
just placed in the /tmp directory.

24.1.16 Step 16
Execute the following ls command to view the new edquota file:

ls /tmp/usr/sbin
[root@localhost tmp]# ls /tmp/usr/sbin
convertquota quot quotaoff quotastats rpc.rquotad xqmstats
edquota quotacheck quotaon repquota setquota

4.1.17 Step 17
Execute the following command to copy this file to the correct location:

cp /tmp/usr/sbin/edquota /usr/sbin
[root@localhost tmp]# cp /tmp/usr/sbin/edquota /usr/sbin
24.1.18 Step 18
Execute the following command to verify that the edquota command has been recovered:

edquota -V
[root@localhost /]# edquota -V
Quota utilities version 4.01.
Compiled with: USE_LDAP_MAIL_LOOKUP EXT2_DIRECT HOSTS_ACCESS RPC RPC_SETQUOTA BSD_BEHAVIOUR
Bugs to jack@suse.cz

The fact that the command works verifies that the file was restored correctly.

Note that after recovering the file, you can delete all of the new files that were created. However, since you placed
them in the /tmp directory, they would eventually be deleted since old files in the /tmp directory are routinely
deleted.

24.1.19 Step 19
Your virtual system has been configured to act as a YUM repository. In order to be able to use this repository,
some changes need to be made to your system. Begin by moving all of the files from the /etc/yum.repos.d
directory into the /tmp directory:

ls /etc/yum.repos.d
mv /etc/yum.repos.d/* /tmp
ls /etc/yum.repos.d
ls /tmp
[root@localhost tmp]# ls /etc/yum.repos.d
CentOS-Base.repo CentOS-Sources.repo epel.repo
CentOS-CR.repo CentOS-Vault.repo mnt_local_repo_.repo
CentOS-Debuginfo.repo CentOS-fasttrack.repo
CentOS-Media.repo epel-testing.repo
[root@localhost tmp]# mv /etc/yum.repos.d/* /tmp
[root@localhost tmp]# ls /etc/yum.repos.d
[root@localhost tmp]# ls /tmp
CentOS-Base.repo CentOS-Sources.repo epel.repo
CentOS-CR.repo CentOS-Vault.repo etc
CentOS-Debuginfo.repo CentOS-fasttrack.repo mnt_local_repo_.repo
CentOS-Media.repo epel-testing.repo usr
Normally, you want these files in the /etc/yum.repos.d directory as they allow you to connect to repositories on
the internet or on local media devices (like your DVD drive). However, for this lab, these files conflict with the
local repository.
4.1.20 Step 20
Using the vi editor, create a file called Local.repo in the /etc/yum.repos.d directory:

cd /
vi /etc/yum.repos.d/Local.repo
[root@localhost tmp]# cd /
[root@localhost /]# vi /etc/yum.repos.d/Local.repo

24.1.21 Step 21
Type the letter i to enter Insert mode and then type the following:

[Local]
name=Local
baseurl=file:///mnt/local_repo
gpgcheck=0
enabled=1

The baseurl setting defines where the RPM files are stored. Normally this would be a network-based address,
either http or ftp based. The gpgcheck setting is set to 0 to prevent the yum command from checking the digital
signature of the packages. The enabled setting is set to 1 in order to make use of this repository.

24.1.22 Step 22
Press the Escape key to exit the Insert mode. Then type :wq to save and quit.

[ESC]
:wq

24.1.23 Step 23
Verify your work by executing the following command:

cat /etc/yum.repos.d/Local.repo
[root@localhost /]# cat /etc/yum.repos.d/Local.repo
[Local]
name=Local
baseurl=file:///mnt/local_repo
gpgcheck=0
enabled=1

24.1.24 Step 24
Remove the quota package by executing the following yum command. When prompted Is this ok, press the Y
key:

yum remove quota


y
[root@localhost /]# yum remove quota
Loaded plugins: fastestmirror, ovl
Resolving Dependencies
--> Running transaction check
---> Package quota.x86_64 1:4.01-17.el7 will be erased
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
Package Arch Version Repository Size
================================================================================
Removing:
quota x86_64 1:4.01-17.el7 @base 887 k

Transaction Summary
================================================================================
Remove 1 Package

Installed size: 887 k


Is this ok [y/N]: y
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Warning: RPMDB altered outside of yum.
Erasing : 1:quota-4.01-17.el7.x86_64 1/1
Verifying : 1:quota-4.01-17.el7.x86_64 1/1

Removed:
quota.x86_64 1:4.01-17.el7

Complete!

24.1.25 Step 25
Verify that the quota package is available on the local repository by executing the following yum command:

yum list available


[root@localhost /]# yum list available
Loaded plugins: fastestmirror, ovl
Loading mirror speeds from cached hostfile
Available Packages
cowsay.noarch 3.04-4.el7 Local
quota.x86_64 1:4.01-17.el7 Local
[root@localhost /]#

24.1.26 Step 26
Install the quota package by executing the following yum command. When prompted Is this ok, type the Y key:

yum install quota


y
[root@localhost /]# yum install quota
Loaded plugins: fastestmirror, ovl
Loading mirror speeds from cached hostfile
Resolving Dependencies
--> Running transaction check
---> Package quota.x86_64 1:4.01-17.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
quota x86_64 1:4.01-17.el7 Local 179 k

Transaction Summary
================================================================================
Install 1 Package

Total download size: 179 k


Installed size: 887 k
Is this ok [y/d/N]: y
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : 1:quota-4.01-17.el7.x86_64 1/1
Verifying : 1:quota-4.01-17.el7.x86_64 1/1

Installed:
quota.x86_64 1:4.01-17.el7

Complete!
24.2 Debian Package Management
Please use the Ubuntu image to complete the following steps. Select the Ubuntu PC by clicking on the tab in the
window on the right side of the screen.
In order to provide the functionality you need to apply these concepts, this VM may require a minute or two to
load.

Debian's package management system is based upon the format used to package the software files for the Debian
distribution; these package file names end in .deb. The Debian package management system is used by many other
distributions including Ubuntu and Mint Linux. These .deb files are archives that contain the software and the
information to configure it for installation or removal.

24.2.1 Step 1
Switch to the root account by typing the su command. When prompted, provide the root password.

su
netlab123
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.4.0-72-generic x86_64)

* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage

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.

This lab has two user accounts (username :: password )

root :: netlab123
sysadmin :: netlab123

Press the [Enter] key to begin...

No mail.
sysadmin@localhost:~$ su
Password:
root@localhost:~#
24.2.2 Step 2
The Debian package management system can install software from repositories listed in /etc/apt/sources.list.
In a networked environment, these Internet sites can usually be reached. In this virtual environment, none of the
repositories are reachable. Use the tail command to view a portion of this file:

tail /etc/apt/sources.list
root@localhost:~# tail /etc/apt/sources.list
## respective vendors as a service to Ubuntu users.
# deb http://archive.canonical.com/ubuntu bionic partner
# deb-src http://archive.canonical.com/ubuntu bionic partner

deb http://security.ubuntu.com/ubuntu bionic-security main restricted


# deb-src http://security.ubuntu.com/ubuntu bionic-security main restricted
deb http://security.ubuntu.com/ubuntu bionic-security universe
#deb-src http://security.ubuntu.com/ubuntu bionic-security universe
deb http://security.ubuntu.com/ubuntu bionic-security multiverse
# deb-src http://security.ubuntu.com/ubuntu bionic-security mul

24.2.3 Step 3
Since none of the repositories are reachable, rename the /etc/apt/sources.list file so a new file that points to a
local repository can be created during the next step:

mv /etc/apt/sources.list /etc/apt/sources.list.orig
root@localhost:~# mv /etc/apt/sources.list /etc/apt/sources.list.orig
root@localhost:~#

24.2.4 Step 4
Execute the following echo command to create a single repository in a new /etc/apt/sources.list file. This
repository exists on the local filesystem in the /var/www/debs/amd64 directory.

echo 'deb [arch=amd64 trusted=yes] file:/var/www/debs amd64/' > /etc/apt/sources.list


root@localhost:~# echo 'deb [arch=amd64 trusted=yes] file:/var/www/debs amd64/' >
/etc/apt/sources.list
root@localhost:~#
24.2.5 Step 5
Now that the /etc/apt/sources.list contains a reachable repository, execute the the following command to
receive the list of packages that are available:

apt-get update
root@localhost:~# apt-get update
Get:1 file:/var/www/debs amd64/ InRelease
Ign:1 file:/var/www/debs amd64/ InRelease
Get:2 file:/var/www/debs amd64/ Release
Ign:2 file:/var/www/debs amd64/ Release
Get:3 file:/var/www/debs amd64/ Packages
Ign:3 file:/var/www/debs amd64/ Packages
Get:3 file:/var/www/debs amd64/ Packages
Ign:3 file:/var/www/debs amd64/ Packages
Get:3 file:/var/www/debs amd64/ Packages
Ign:3 file:/var/www/debs amd64/ Packages
Get:3 file:/var/www/debs amd64/ Packages
Ign:3 file:/var/www/debs amd64/ Packages
Get:3 file:/var/www/debs amd64/ Packages
Ign:3 file:/var/www/debs amd64/ Packages
Get:3 file:/var/www/debs amd64/ Packages
Ign:3 file:/var/www/debs amd64/ Packages
Get:3 file:/var/www/debs amd64/ Packages [1589 B]
Reading package lists... Done
root@localhost:~#

24.2.6 Step 6
To install the updated versions of all available packages, execute the command below:

apt-get upgrade
root@localhost:~# apt-get upgrade
Reading package lists... Done
Building dependency tree
Reading state information... Done
Calculating upgrade... Done
The following package was automatically installed and is no longer required:
htop
Use 'apt autoremove' to remove it.
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
root@localhost:~#

Based on the previous output, zero packages were upgraded, newly installed, removed, or not upgraded. The output
also recommends removing the htop package as it is no longer needed.
24.2.7 Step 7
Remove the htop package using the following command. When prompted whether to continue, press Enter to
continue:

apt-get remove htop


y
root@localhost:~# apt-get remove htop
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages will be REMOVED:
htop
0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
After this operation, 221 kB disk space will be freed.
Do you want to continue? [Y/n] y
(Reading database ... 27628 files and directories currently installed.)
Removing htop (2.1.0-3) ...
Processing triggers for mime-support (3.60ubuntu1) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...

24.2.8 Step 8
To find packages to install, you can use apt-cache search keyword. Search for packages related to apt by
executing the following command:

apt-cache search apt


root@localhost:~# apt-cache search apt
python-apt-common - Python interface to libapt-pkg (locales)
libapt-pkg5.0 - package management runtime library
libapt-inst2.0 - deb package format runtime library
strace - System call tracer
python3-apt - Python 3 interface to libapt-pkg
apt-utils - package management related utility programs
isc-dhcp-client - DHCP client for automatically obtaining an IP address
apt - commandline package manager
libpcap0.8 - system interface for user-level packet capture

24.2.9 Step 9
View the dependencies of the aptitude package by executing the following command:

apt-cache depends apt


root@localhost:~# apt-cache depends aptitude
apt
Depends: adduser
|Depends: gpgv
|Depends: <gpgv2>
Depends: <gpgv1>
Depends: ubuntu-keyring
Depends: libapt-pkg5.0
Depends: libc6
Depends: libgcc1
Depends: libgnutls30
Depends: libseccomp2
Depends: libstdc++6
Breaks: <apt-transport-https>
Breaks: apt-utils
Breaks: <aptitude>
Recommends: ca-certificates
Suggests: <apt-doc>
|Suggests: <aptitude>
|Suggests: <synaptic>
Suggests: <wajig>
Suggests: dpkg-dev
|Suggests: gnupg
|Suggests: <gnupg2>
Suggests: <gnupg1>
Suggests: powermgmt-base
Replaces: <apt-transport-https>
Replaces: apt-utils

24.2.10 Step 10
View the details of the aptitude package by executing the following command:

apt-cache show apt


root@localhost:~# apt-cache show apt
Package: apt
Status: install ok installed
Priority: important
Section: admin
Installed-Size: 3815
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Architecture: amd64
Version: 1.6.10
Replaces: apt-transport-https (<< 1.5~alpha4~), apt-utils (<< 1.3~exp2~)
Provides: apt-transport-https (= 1.6.10)
Depends: adduser, gpgv | gpgv2 | gpgv1, ubuntu-keyring, libapt-pkg5.0 (>= 1.6.10), libc6 (>=
2.15), libgcc1 (>= 1:3.0), libgnutls30 (>= 3.5.6), libseccomp2 (>= 1.0.1), libstdc++6 (>=
5.2)
Recommends: ca-certificates
Suggests: apt-doc, aptitude | synaptic | wajig, dpkg-dev (>= 1.17.2), gnupg | gnupg2 |
gnupg1, powermgmt-base
Breaks: apt-transport-https (<< 1.5~alpha4~), apt-utils (<< 1.3~exp2~), aptitude (<< 0.8.10)
Conffiles:
/etc/apt/apt.conf.d/01-vendor-ubuntu 5232396660502461fc834c0a1229dbe4
/etc/apt/apt.conf.d/01autoremove 658942f22de597caf263e344fecf932f
/etc/cron.daily/apt-compat 49e9b2cfa17849700d4db735d04244f3
/etc/kernel/postinst.d/apt-auto-removal 4ad976a68f045517cf4696cec7b8aa3a
/etc/logrotate.d/apt 179f2ed4f85cbaca12fa3d69c2a4a1c3
Description: commandline package manager
This package provides commandline tools for searching and
managing as well as querying information about packages
as a low-level access to all features of the libapt-pkg library.
.
These include:
* apt-get for retrieval of packages and information about them
from authenticated sources and for installation, upgrade and
removal of packages together with their dependencies
* apt-cache for querying available information about installed
as well as installable packages
* apt-cdrom to use removable media as a source for packages
* apt-config as an interface to the configuration settings
* apt-key as an interface to manage authentication keys
Description-md5: 9fb97a88cb7383934ef963352b53b4a7
Original-Maintainer: APT Development Team <deity@lists.debian.org>
Some output has been omitted from the terminal above for brevity

24.2.11 Step 11
Unlike removing a package, purging will also remove configuration files used by the package. Purge the xfsprogs
package by executing the following command. When prompted whether to continue, press the Enter key to
continue:

apt-get purge xfsprogs


y
root@localhost:~# apt-get purge xfsprogs
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following package was automatically installed and is no longer required:
libreadline5
Use 'apt autoremove' to remove it.
The following packages will be REMOVED:
xfsprogs*
0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
After this operation, 3969 kB disk space will be freed.
Do you want to continue? [Y/n]
(Reading database ... 27682 files and directories currently installed.)
Removing xfsprogs (4.9.0+nmu1ubuntu2) ...
Processing triggers for libc-bin (2.27-3ubuntu1) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...

24.2.12 Step 12
Installing a package can be accomplished by executing the apt-get install command followed by the package
name. Execute the following command to install the xfsprogs package. When prompted whether to continue,
press the Y key and then press the Enter key to continue:

apt-get install xfsprogs


y
root@localhost:~# apt-get install xfsprogs
24.2.13 Step 13
While using Advanced Packaging Tools (APT) commands offers features like automatic dependency resolution
and remote repositories, the dpkg command can also be used to remove or install software packages. Use the dpkg
command to remove the xfsprogs package:

dpkg -r xfsprogs
y
root@localhost:~# dpkg -r xfsprogs
(Reading database ... 27691 files and directories currently installed.)
Removing xfsprogs (4.9.0+nmu1ubuntu2) ...
Processing triggers for libc-bin (2.27-3ubuntu1) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
root@localhost:~#

24.2.14 Step 14
The dpkg command can also be used to install software packages. Use the dpkg command to install the xfsprogs
package:

dpkg -i /var/www/debs/amd64/xfsprogs_4.9.0+nmu1ubuntu2_amd64.deb
root@localhost:~# dpkg -i /var/www/debs/amd64/xfsprogs_4.9.0+nmu1ubuntu2_amd64.d
eb
Selecting previously unselected package xfsprogs.
(Reading database ... 27631 files and directories currently installed.)
Preparing to unpack .../xfsprogs_4.9.0+nmu1ubuntu2_amd64.deb ...
Unpacking xfsprogs (4.9.0+nmu1ubuntu2) ...
Setting up xfsprogs (4.9.0+nmu1ubuntu2) ...
update-initramfs: deferring update (trigger activated)
Processing triggers for libc-bin (2.27-3ubuntu1) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
Processing triggers for initramfs-tools (0.130ubuntu3.7) ...

24.2.15 Step 15
The dpkg command is also useful for listing all of the packages that are currently installed on the system by
executing the dpkg -l command. An additional argument can be provided as a glob pattern; this will only list
packages that match that pattern. List all the packages that match the glob apt*:

dpkg -l 'apt*'
root@localhost:~# dpkg -l 'apt*'
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==============-============-============-=================================
ii apt 1.6.10 amd64 commandline package manager
un apt-doc <none> <none> (no description available)
un apt-listchange <none> <none> (no description available)
un apt-transport- <none> <none> (no description available)
ii apt-utils 1.6.10 amd64 package management related utilit
un aptitude <none> <none> (no description available)
24.2.16 Step 16
The status of an installed package can be displayed by executing the dpkg -s command followed by the name of
the package. Display the status of the xfsprogs package:

dpkg -s xfsprogs
root@localhost:~# dpkg -s xfsprogs
Package: xfsprogs
Status: install ok installed
Priority: optional
Section: admin
Installed-Size: 3876
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Architecture: amd64
Version: 4.9.0+nmu1ubuntu2
Replaces: xfsdump (<< 3.0.0)
Provides: fsck-backend
Depends: libblkid1 (>= 2.17.2), libc6 (>= 2.14), libreadline5 (>= 5.2), libuuid1
(>= 2.16)
Suggests: xfsdump, acl, attr, quota
Breaks: xfsdump (<< 3.0.0)
Description: Utilities for managing the XFS filesystem
A set of commands to use the XFS filesystem, including mkfs.xfs.
.
XFS is a high performance journaling filesystem which originated
on the SGI IRIX platform. It is completely multi-threaded, can
support large files and large filesystems, extended attributes,
variable block sizes, is extent based, and makes extensive use of
Btrees (directories, extents, free space) to aid both performance
and scalability.
.
Refer to the documentation at http://oss.sgi.com/projects/xfs/
for complete details.
Homepage: http://xfs.org/
Original-Maintainer: XFS Development Team <linux-xfs@vger.kerne
24.3 SUSE Package Management
Please use the SUSE image to complete the following steps. Select the OpenSUSE PC by clicking on the tab in the
window on the right side of the screen.

The SUSE package management system is based on the ZYpp/libzypp package management engine, which is
mainly implemented by openSUSE, SUSE Linux Enterprise and Ark. ZYpp/Libzypp is the background package
management engine for the zypper command line tool. This package management utility provides users with the
ability to query, install, remove, and update software packages as well as the ability to satisfy software
dependencies during these actions. In this portion of the lab, you will practice using the zypper command to
manage packages on the OpenSUSE operating system.

24.3.1 Step 1
Log in to the root account. When prompted, provide the root password:

su -
netlab123
This lab has two user accounts (username :: password )

root :: netlab123
sysadmin :: netlab123

Press the [Enter] key to begin...

sysadmin@localhost:~> su -
Password:

localhost:~ #

24.3.2 Step 2
The syntax used for the zypper command examples in this course is the following:

zypper [--global-opts] command [--command-opts] [command-arguments]

To begin using the zypper command, first ensure that the command has updated information about repositories by
using the following command:

zypper ref
localhost:~ # zypper ref
Repository 'localrepo' is up to date.
All repositories have been refreshed.
Please allow a few minutes for this command do produce output.

24.3.3 Step 3
To query the software repositories on a system, use the list repositories -lr option can be used with the zypper
command. Use the following command to list the repositories:

zypper lr
localhost:~ # zypper lr
Repository priorities are without effect. All enabled repositories share the sam
e priority.

# | Alias | Name | Enabled |


GPG Check | Refresh
---+---------------------------+------------------------------------+---------+-
----------+--------
1 | localrepo | localrepo | Yes |
( p) Yes | No
2 | repo-debug | Debug Repository | No |
---- | ----
3 | repo-debug-non-oss | Debug Repository (Non-OSS) | No |
---- | ----
4 | repo-debug-update | Update Repository (Debug) | No |
---- | ----
5 | repo-debug-update-non-oss | Update Repository (Debug, Non-OSS) | No |
---- | ----
6 | repo-non-oss | Non-OSS Repository | No |
---- | ----
7 | repo-oss | Main Repository | No |
---- | ----
8 | repo-source | Source Repository | No |
---- | ----
9 | repo-source-non-oss | Source Repository (Non-OSS) | No |
---- | ----
10 | repo-update | Main Update Repository | No |
---- | ----
11 | repo-update-non-oss | Update Repository (Non-Oss) | No |
---- | ----

In the output above, the localrepo repository is enabled on the system.

24.3.4 Step 4
To find a package to install, the search se command can be used to query the configured repositories on the
system. Use the following command to search for the python package:

zypper se python
localhost:~ # zypper se python
Loading repository data...
Reading installed packages...

S | Name | Summary | Type


--+---------------------+----------------------------------------------+--------
i | libpython2_7-1_0 | Python Interpreter shared library | package
i | python | Python Interpreter | package
i | python-base | Python Interpreter base package | package
i | python-gobject2 | Python bindings for GObject | package
i | python-pyliblzma | Python bindings for liblzma | package
i | python-rpm-macros | RPM macros for building of Python modules | package
i | python-urlgrabber | A high-level cross-protocol url-grabber | package
i | python-xml | A Python XML Interface | package
i | python2-cssselect | CSS3 selectors for Python | package
i | python2-dbus-python | Python bindings for D-Bus | package
i | python2-deltarpm | Tools to Create and Apply deltarpms | package
i | python2-gobject | Python bindings for GObject | package
i | python2-gpgme | A Python module for working with OpenPGP m-> | package
i | python2-iniparse | Python Module for Accessing and Modifying -> | package
i | python2-lxml | Pythonic XML processing library | package
i | python2-pycurl | PycURL -- cURL library module | package
i | python2-rpm | Python Bindings for Manipulating RPM Packa-> | package
i | python2-six | Python 2 and 3 compatibility utilities | package
i | python2-yum | YUM update notification daemon | package

Note that in the output above, the status field (S) contains the letter i, which means that the python package is
currently installed.

24.3.5 Step 5
Use the following command to search for the cowsay package:

zypper se cow*
localhost:~ # zypper se cow*
Loading repository data...
Reading installed packages...

S | Name | Summary | Type


--+--------+-----------------------------------------------------+--------
| cowsay | Configurable talking cow (and some other creatures) | package
localhost:~ #

In the output above, the S field does not contain an i which means the cowsay package is not currently installed.

24.3.6 Step 6
The zypper command can be used with the install in command to install packages.

zypper in package_name

Use the following command to install the cowsay package:

zypper in cowsay
localhost:~ # zypper in cowsay
Type the Y key to install the cowsay package:
y
Loading repository data...
Reading installed packages...
Resolving package dependencies...

The following 3 NEW packages are going to be installed:


cowsay libgdbm4 perl

3 new packages to install.


Overall download size: 6.6 MiB. Already cached: 0 B. After the operation,
additional 40.6 MiB will be used.
Continue? [y/n/v/...? shows all options] (y): y

Retrieving package libgdbm4-1.12-lp151.2.67.x86_64 (1/3), 75.7 KiB (251.7 KiB u


npacked)
Retrieving package perl-5.26.1-lp151.8.37.x86_64 (2/3), 6.5 MiB ( 40.4 MiB unp
acked)
Retrieving package cowsay-3.03-lp151.2.1.noarch (3/3), 26.2 KiB ( 29.1 KiB unpacked)
Checking for file conflicts: [done]
(1/3) Installing: libgdbm4-1.12-lp151.2.67.x86_64 [done]
(2/3) Installing: perl-5.26.1-lp151.8.37.x86_64 [done]
(3/3) Installing: cowsay-3.03-lp151.2.1.noarch [done]

24.3.7 Step 7
Run the following command to view package status, it should show i for installed:

zypper se cowsay
#localhost:~ # zypper se cowsay
Loading repository data...
Reading installed packages...

S | Name | Summary | Type


---+--------+-----------------------------------------------------+--------
i+ | cowsay | Configurable talking cow (and some other creature

24.3.8 Step 8
Run the following command to use your newly installed program:

cowsay Dare something worthy!


localhost:~ # cowsay Dare something worthy!
________________________
< Dare something worthy! >
------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||

Like other Linux programs, the cowsay command has many advanced features:
cowsay -f tux Learning Linux administration is a most worthy pursuit
localhost:~ # cowsay -f tux Learning Linux administration is a most worthy pursuit!
_________________________________________
/ Learning Linux administration is a most \
\ worthy pursuit! /
-----------------------------------------
\
\
.--.
|o_o |
|:_/ |
// \ \
(| | )
/'\_ _/`\
\___)=(___/
Chapter 25: Managing Shared Libraries

25.1 Introduction
Shared libraries, also known as shared objects or system libraries, are files that include the .so extension as part of
their name. By placing code that is used by many programs into library files that can be shared, each program file
can be smaller, the programs can use a more consistent base of code, and less disk space overall is consumed.

When a program is executed, the /lib/ld-linux.so dynamic linker will find and load the shared libraries needed
by a program, prepare the program to execute, and then run it. Older binaries in the a.out format are linked and
loaded by the /lib/ld.so program. Both programs will search for the libraries in the /lib directory, the
/usr/lib directory, the directories listed in the LD_LIBRARY_PATH environment variable, and from the
/etc/ld.so.cache cache file.
Managing shared libraries can be part of the management of the software of a system, especially if those libraries
are placed in unusual locations within the filesystem. Library files that are located in the /lib or /usr/lib
directories are normally configured to be automatically found by the programs that need them, but placing library
files in other locations, such as the /usr/local/lib directory, may require configuring the system to be able to
locate the shared libraries when needed.

25.2 /etc/ld.so.conf File


The /etc/ld.so.conf file is used to configure which directories are searched for library files by the ldconfig
command during the boot process or when executed by the administrator. The ldconfig command creates links
and caches the most recent shared libraries that are required by programs installed on the system. The
/etc/ld.so.conf files contains the following content:

include ld.so.conf.d/*conf

Instead of using the single file to contain a list of all the directories to search, the /etc/ld.so.conf.d directory
contains *.conf files, which specify the library directories. This modular approach allows for packages that might
be installed to add their own .conf file to the /etc/ld.so.conf.d directory. This, in turn, allows new libraries to
be easily found. It also allows for those packages to simply remove their .conf file from that directory when the
package is being removed. These actions would take place in the postinstall and postuninstall scripts.

As an example of a package that uses shared libraries, consider the mysql-libs package. This package installs a
/etc/ld.so.conf.d/mysql-i386 file, which contains the following:

/usr/lib/mysql

Although the mysql-libs package demonstrates how shared libraries can be specified in a .conf file, placed in the
/etc/ld.so.conf.d directory, note that the administrator doesn't have to do any additional work beyond installing
or removing the mysql-libs package. An administrator should not need to manually manage shared libraries for
software that is already packaged.

25.3 Manually Adding Library Files


If an administrator is compiling software from the source or using software that is not packaged, a .conf file needs
to be manually created. For example, the administrator may have downloaded and installed software that was not
packaged in an .rpm or a .deb file and then installed it in directories under the /usr/local directory structure,
with its library files located under the /usr/local/lib directory structure. In order for these library files to be
able to be loaded, create a /etc/ld.so.conf.d/local.conf file with the following content:

/usr/local/lib

After adding or removing files in the /etc/ld.so.conf.d directory, the administrator needs to execute the
1dconfig command to update the /etc/ld.so.cache cache file.

After updating the /etc/ld.so.cache file, the ldconfig command can be used to display useful information
about the system's libraries
To display the name and path information for all the libraries that have been added to the cache, use the ldconfig
command with the -p option:

sysadmin@localhost:~$ ldconfig -p | head -n 20


799 libs found in cache `/etc/ld.so.cache'
libzypp.so.1702 (libc6,x86-64) => /usr/lib64/libzypp.so.1702
libzio.so.1 (libc6,x86-64) => /usr/lib64/libzio.so.1
libz.so.1 (libc6,x86-64) => /lib64/libz.so.1
liby2util.so.5 (libc6,x86-64) => /usr/lib64/liby2util.so.5
liby2.so.4 (libc6,x86-64) => /usr/lib64/liby2.so.4
libyui.so.8 (libc6,x86-64) => /usr/lib64/libyui.so.8
libyelp.so.0 (libc6,x86-64) => /usr/lib64/libyelp.so.0
libycpvalues.so.6 (libc6,x86-64) => /usr/lib64/libycpvalues.so.6
libycp.so.5 (libc6,x86-64) => /usr/lib64/libycp.so.5
libyaml-0.so.2 (libc6,x86-64) => /usr/lib64/libyaml-0.so.2
libx86emu.so.1 (libc6,x86-64) => /usr/lib64/libx86emu.so.1
libxtables.so.12 (libc6,x86-64) => /usr/lib64/libxtables.so.12
libxslt.so.1 (libc6,x86-64) => /usr/lib64/libxslt.so.1
libxshmfence.so.1 (libc6,x86-64) => /usr/lib64/libxshmfence.so.1
libxml2.so.2 (libc6,x86-64) => /usr/lib64/libxml2.so.2
libxml-security-c.so.17 (libc6,x86-64) =>
/usr/lib64/libxml-security-c.so.17
libxklavier.so.16 (libc6,x86-64) => /usr/lib64/libxklavier.so.16
libxkbfile.so.1 (libc6,x86-64) => /usr/lib64/libxkbfile.so.1
libxkbcommon.so.0 (libc6,x86-64) => /usr/lib64/libxkbcommon.so.0

The output about above shows how many libraries are configured in the cache, and also displays the library names
and paths where they were found when added to the cache. Due to the very large number of libraries that a typical
Linux system has installed, the examples are limited by using the head command.

To display the list of library directories that are configured as well as their contents, the -v option can be used:

sysadmin@localhost:~$ ldconfig -v | head -n 20


/usr/local/lib64:
/usr/local/lib:
/usr/lib64/graphviz:
libgvplugin_neato_layout.so.6 -> libgvplugin_neato_layout.so.6.0.0
libgvplugin_dot_layout.so.6 -> libgvplugin_dot_layout.so.6.0.0
libgvplugin_core.so.6 -> libgvplugin_core.so.6.0.0
/lib:
/lib64:
libmultipath.so.0 -> libmultipath.so.0
libmpathpersist.so.0 -> libmpathpersist.so.0
libmpathcmd.so.0 -> libmpathcmd.so.0
libpamc.so.0 -> libpamc.so.0.82.1
libpam_misc.so.0 -> libpam_misc.so.0.82.1
libpam.so.0 -> libpam.so.0.84.2
libreadline.so.7 -> libreadline.so.7.0
libhistory.so.7 -> libhistory.so.7.0
libtirpc.so.3 -> libtirpc.so.3.0.0
libtinfow.so.6 -> libtinfow.so.6.1
libtinfo.so.6 -> libtinfo.so.6.1
libticw.so.6 -> libticw.so.6.1

The ldconfig command has several other options, which can be viewed by executing the man ldconfig
command.

sysadmin@localhost:~$ man ldconfig


25.4 LD_LIBRARY_PATH
Users without administrative access to the system can also configure directories that will be searched by setting the
LD_LIBRARY_PATH environment variable with the list of library directories. For example, if the user jose directory
installed a program in the /home/jose/app with the library files for that application in the /home/jose/app/lib
directory, then that user could execute:

sysadmin@localhost:~$ export LD_LIBRARY_PATH=/home/jose/app/lib

Once that line has been executed, then the library files found in the /home/jose/app/lib directory could be found
and located.

25.5 Idd Command


To verify or view the library files associated with a program, use the ldd command. For example, to view the
libraries that are used by the /bin/bash executable, execute the ldd /bin/bash command. The output from this
command would appear similar to the following:

sysadmin@localhost:~$ 1dd /bin/bash


linux-vdso.so.1 => (0x00007fffe7ffe000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5
(0x00007f280231e000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f280211a000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2801d53000)
/lib64/ld-linux-x86-64.so.2 (0x00007f280254d000)

If there is a problem with a library file not being loaded, then the line of the output may report not found. For
example, if the mysq1-libs package library files were not correctly configured, then executing the 1dd
/usr/bin/mysq1 command may display the following error output:

sysadmin@localhost:~$ 1dd /usr/bin/mysq1


ldd: /usr/bin/mysql: No such file or directory
Key Terms
/etc/ld.so.conf
One of the cache files used by ldconfig.
Section 25.1
LD_LIBRARY_PATH
A colon-separated set of directories where libraries should be searched for first, before the standard set of
directories.
Section 25.1 | Section 25.4
ldconfig
Creates the necessary links and cache to the most recent shared libraries and checks the header and
filenames of the libraries it encounters when determining which versions should have their links updated.
Section 25.3
ldd
Prints the shared libraries required by each program or shared library specified on the command line.
Section 25.5
LAB 25

25.0 Introduction
Shared libraries are important as they contain code that will be used by multiple executable programs. An issue
related to accessing one shared library may have a serious impact on multiple system commands and processes. As
a result, while not a common task, it is important to know how to manage these libraries.

25.1 Step 1
Execute the following command to switch to the root account. When prompted, provide the root password:

su – root
netlab123
[sysadmin@localhost ~]$ su - root
Password:
Last login: Mon Jul 1 15:00:15 UTC 2019 on pts/0
[root@localhost ~]#

25.2 Step 2
Execute the following commands to verify that there are no customizations to the ldconfig command on this
system:

more /etc/ld.so.conf
ls /etc/ld.so.conf.d
[root@localhost ~]# more /etc/ld.so.conf
include ld.so.conf.d/*.conf
[root@localhost ~]# ls /etc/ld.so.conf.d
mariadb-x86_64.conf
[root@localhost ~]#
25.3 Step 3
Execute the following command to display all of the libraries that the ldconfig utilizes:

ldconfig -v
[root@localhost ~]# ldconfig -v
ldconfig: Can't stat /libx32: No such file or directory
ldconfig: Path `/usr/lib' given more than once
ldconfig: Path `/usr/lib64' given more than once
ldconfig: Can't stat /usr/libx32: No such file or directory
/usr/lib64/mysql:
libmysqlclient.so.18 -> libmysqlclient_r.so
/lib:
/lib64:
libfipscheck.so.1 -> libfipscheck.so.1.2.1
libedit.so.0 -> libedit.so.0.0.42
libwrap.so.0 -> libwrap.so.0.7.6
libgpm.so.2 -> libgpm.so.2.1.0
libgomp.so.1 -> libgomp.so.1.0.0
libmpc.so.3 -> libmpc.so.3.0.0
libmpfr.so.4 -> libmpfr.so.4.1.1
libpipeline.so.1 -> libpipeline.so.1.2.3
librepo.so.0 -> librepo.so.0
libevent_openssl-2.0.so.5 -> libevent_openssl-2.0.so.5.1.9
Some output was omitted from the terminal above for brevity.

25.4 Step 4
To add a new library directory to the system, first create a new directory and then create a configuration file in the
/etc/ld.so.conf.d directory:

mkdir /usr/mylib
echo “/usr/mylib” > /etc/ld.so.conf.d/mylib.conf
[root@localhost ~]# mkdir /usr/mylib
[root@localhost ~]# echo "/usr/mylib" > /etc/ld.so.conf.d/mylib.conf
[root@localhost ~]#

25.5 Step 5
Normally, the next step would be to copy the library files into the /usr/mylib directory. In this case, we will copy
an existing one into this directory:

cp /lib64/ld-2.17.so /usr/mylib
[root@localhost ~]# cp /lib64/ld-2.17.so /usr/mylib
[root@localhost ~]#
25.6 Step 6
To verify that this library has been added to the system, execute the following command:

ldconfig -v | head -5
[root@localhost ~]# ldconfig -v | head -5
/usr/lib64/mysql:
libmysqlclient.so.18 -> libmysqlclient_r.so
/usr/mylib:
ld-linux-x86-64.so.2 -> ld-2.17.so (changed)
/lib:
[root@localhost ~]#

25.7 Step 7
To verify that this library has been added to the system, execute the following command:

ldconfig -v | head -5
[root@localhost ~]# ldconfig -v | head -5
/usr/lib64/mysql:
libmysqlclient.so.18 -> libmysqlclient_r.so
/usr/mylib:
ld-linux-x86-64.so.2 -> ld-2.17.so (changed)
/lib:
[root@localhost ~]#

25.8 Step 8
Display the libraries that are used by the /bin/ls command by executing the following command:

ldd /bin/ls
[root@localhost ~]# ldd /bin/ls
linux-vdso.so.1 => (0x00007ffdf914d000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f0152080000)
libcap.so.2 => /lib64/libcap.so.2 (0x00007f0151e7b000)
libacl.so.1 => /lib64/libacl.so.1 (0x00007f0151c71000)
libc.so.6 => /lib64/libc.so.6 (0x00007f01518a4000)
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f0151642000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f015143d000)
/lib64/ld-linux-x86-64.so.2 (0x0000559921cf8000)
libattr.so.1 => /lib64/libattr.so.1 (0x00007f0151238000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f015101c000)
[root@localhost ~]#
Chapter 26: Virtualization

26.1 Introduction
When we look at the term virtualization, it quickly becomes clear that several different meanings are possible
depending on the context and technologies involved. Broadly speaking, virtualization refers to systems or programs
that are running on software platforms rather than directly on computer hardware. Ultimately, all of these systems
are using physical computing resources, but several advantages can be gained by abstracting the computing
resources away from physical hardware. In this chapter, you will learn about virtualization concepts such as virtual
machines and containers, components of virtual machines, how virtual machines and containers are deployed, and
methods used to configure virtual machines.

26.2 Virtual Machines and Containers


The first type of virtualized system is a virtual machine, or VM. This is where a complete operating system is
installed on virtual hardware using a hypervisor to manage processes. The hypervisor is software that is installed
on top of hardware, such as a server, creating a virtualization layer and acting as a platform for VMs to be created
on. The hypervisor creates virtual resources such as CPUs, memory, hard disks and I/O communication interfaces
like network and serial ports.
There are two methods of installing virtualization on a computer system. The first method is to install a Type 1
hypervisor, also called a bare-metal hypervisor, directly on top of the hardware. The Type 1 hypervisor sits directly
between the hardware and the virtual machine. The second method is called hosted virtualization. To set up a
system with hosted virtualization, a Type 2 hypervisor, also called a hosted hypervisor, needs to be installed on top
of the operating system that already exists, the host operating system, instead of on the hardware like a bare metal
hypervisor.
The operating system running in a VM is called a guest operating system. This operating system is usually installed
as a pre-configured image, but it can also be built from installation sources such as CD, DVD, or PXE, to perform
whatever tasks are needed by users. This configuration, along with installing application software, security patches,
and network set-up is done by a systems administrator just as if it was a physical machine in a data center. Of
course, being virtual, the VM might be sharing hardware with a number of other VMs. It might also be halfway
around the world, physically closer to the clients that will be connecting to it.

Consider This

One of the main benefits of virtualization is that it makes computing resources more efficient. Traditionally,
hardware could only run one computing system at a time, which may not have been a problem for individual users,
however, with the growth of digital technology and increased needs for connectivity and data, data centers began
adopting virtualization as a solution for providing computing resources efficiently.

An outgrowth of virtualization, container technology is rapidly being adopted by software development


organizations. Linux Containers allow system designers to bypass traditional operating systems and access
computing resources differently. A containerized application relies on a container engine to communicate with the
host OS without a hypervisor, or a guest VM. When programmers design these applications, they include all the
dependencies needed to perform a specific task in the container. Also, typically, several containers are built which
communicate with each other to perform tasks which previously would have been done by one program running on
top of an OS.
Doing this provides several advantages, including requiring fewer resources, cutting release cycle times, and
abstracting program elements from host operating systems for better portability. Recently, there has been a move to
Hybrid Container architecture. This consists of a multi-layered approach where a hypervisor, running on physical
hardware, supports virtual machines that, in turn, host containers.

Organizations are weighing the pros and cons of the various configurations available today. Pros include:
containers use fewer physical resources than VMs, offer enhanced reliability, and scalability. They also require less
storage due to their lightweight nature and offer performance advantages both in startup time and application
throughput.

On the con side, when containers are run directly on hardware, they can require considerable effort to ensure
segregation and maintain security. When running on shared resources, the container engine needs to be tuned to
avoid interference between and within containers. The engine also needs to control access to resources such as
memory, I/O devices, and network connections. Finally, when programmers are allowed to create these small,
stand-alone resources, it becomes easier for their numbers to get out of control. The advantages of containerization
can quickly be outweighed by time and effort spent managing and maintaining them if discipline isn’t exercised
from the beginning. Fortunately, the open source community has embraced container development and the tools for
designing, deploying, and maintaining them continue to grow at a rapid pace.
26.3 Virtualization Options
When it comes to virtual machines, there are many different vendors and open source projects to choose between.
Careful consideration should be taken before deciding on a particular VM technology since compatibility between
them is difficult at best, and considerable effort is required to change between them. Virtual machines are typically
deployed from an image which contains the guest OS, application programs, and whatever customizations the
administrator has configured for system management. These images can be deployed somewhat automatically, but
they may require some human intervention to configure network and security settings.

VMware

One of the oldest and most widely deployed platforms is VMware, owned by Dell Technologies. VMware
develops and maintains a vast array of virtualization technologies as well as providing technical assistance for their
customers. Their vSphere and ESXi hypervisor platforms are nearly ubiquitous across industries where customers
value stability and support.

KVM

KVM, or Kernel-based Virtual Machine is an open source hypervisor that is built into Linux. It should not be
confused with a KVM (keyboard, video, mouse) switch, a hardware device that allows multiple computers to share
a single monitor. As an open source program, it has the advantage of being non-proprietary and lacking licensing
fees. Its deployment is quite widespread because of this and it is generally considered more scalable than VMware.
KVM is used extensively in the SUSE Linux Enterprise distribution.

Xen

The Xen project is another open source hypervisor. It is considered a Type 1 or bare metal system because it runs
directly on hardware without a host OS. This, along with its microkernel design, allows for very high performance
from a lightweight system. Although Xen is most frequently used with Linux, it’s not tied to any one OS. Xen is
currently the only bare metal hypervisor offered as open source software and is a Linux Foundation collaborative
project.

Hyper-V

Hyper-V is a hardware virtualization product offered by Microsoft. It’s popular in environments already running
Windows servers and desktop machines. Although it provides the appearance of a Type 2, or hosted hypervisor,
running on top of Windows Server, it is actually installed beneath any Windows or other OS software. It also
allows supported Linux distributions to be installed in a Windows environment.

Virtual Box

VirtualBox is a popular open source product from Oracle that is relatively easy to install and configure. It is a
Type 2 hypervisor that runs on Windows, Macintosh, and Linux hosts. It is billed as a “general-purpose full
virtualizer for x86 hardware”. Although it will run in a server environment it’s more suited to desktop users that
need to run different operating systems occasionally.

Docker

As noted previously, Linux containers are quickly becoming the industry standard model for networked application
development. The two most dominant forces in the containerization movement are Docker and Kubernetes
Docker is the container engine that allows programmers and system engineers to create containerized applications.
These applications are stand-alone components that do not rely on any host OS to perform their functions. Its
runtime, containerd, facilitates packaging application code and dependencies into a container that can run
consistently across different infrastructure, thus allowing applications to operate regardless of the underlying
infrastructure. As a top-level open source project of the Cloud Native Computing Foundation, containerd is
constantly being improved to meet industry needs.

Kubernetes

Kubernetes, originally developed by Google, was converted to an open source project in 2014. Kubernetes can be
described as a platform that “provides a container-centric management environment” for containers, microservices,
and cloud infrastructure. It provides labels and annotations to help users keep track of resources. It “orchestrates”
computing, network, and storage resources for container applications and workflows. It is also highly integrated
with Docker so both programs can work together.

Kubernetes is organized into clusters, nodes (formerly minions), pods, and containers. The master node is in charge
of maintaining the desired state in the cluster. It provides communication to the APIs, starts and stops processes,
and balances workloads.
26.4 IaaS
Collectively, the elements we have been discussing are the foundation for IaaS (Infrastructure as a Service). IaaS is
a form of cloud computing, which is the delivery of on-demand shared computing resources (software and/or data)
to organizations and users through the internet.

Cloud computing is a popular subject for discussion, and both organizations and individuals show a keen interest in
the advantages it can provide. As soon as it became feasible for computer systems to create and manage other
computer systems through virtualization and automation, programmers and system designers gravitated towards
software-defined systems and networking. As a result, organizations are increasingly looking at the cloud as
essential to their businesses and operations.

Consider This
You often hear that something is "in the cloud", but what does that mean? Physically, a cloud can be described as
computing resources from one or many off-site data centers which can be accessed over the internet.

By abstracting the machines being managed from physical hardware, it becomes possible and desirable to construct
systems in software as much as possible. By placing virtual machine instances on hardware managed by
hypervisors and networking them together using software, not only were physical demands reduced but speeds
were increased, as each part of a system only had to communicate within the APIs (application programming
interfaces) of an orchestrating technology. Orchestrating systems such as OpenStack, Apache Cloudstack, and
OpenNebula has made cloud computing possible.

These systems have been able to advance quickly because open source software development allows different,
often competing, companies to work together to create common standards and code bases. Each of these projects is
broken down into smaller sub-projects, which can be developed by teams that specialize in a specific technical
area. By working together, and sharing improvements in the code, they are able to construct robust systems that are
adaptable to many different needs.

Linux VMs have the ability to communicate with Linux containers, block storage pools, virtual network switches
and routers, database stores, and every other component that was once part of a monolithic program or data center
design. Ultimately, by creating hypervisors that run Linux VMs, today’s programmers and system architects have
collaboratively created our modern online world in much less time and with far fewer resources than any one
company could have achieved.
26.5 VM and Container Configuration
When a new virtual machine or container is created, it needs to be able to connect to the outside world. Like any
other computer or resource on a network, it will need a unique hostname and IP address along with proper subnet
mask, DNS, and default route. Since it is desirable to have images and containers created and managed by other
programs, initialization scripts are required to make changes to a base image.

The image, which is stored as a set of files and ready to use, will be lacking important information such as the
correct network settings, users, groups and permissions, paths to resources such as databases and storage blocks,
SSH keys, and any other configurations that would normally be done manually by a system administrator. These
scripts need to be flexible and addressable by other programs in order to minimize required inputs from human
operators, and also need to be secure since they may contain sensitive information like login credentials.

Fortunately, there are utilities such as cloud-init and kickstart scripts (for VMs) that can help simplify this
process. These utilities can call other programs through an API, read metadata from a server, or configure
instances. In kubernetes, there are even specialized containers, called Init containers, that run before application
containers start.

SSH, or secure shell, is used to communicate with and manage both VMs and containers. When a new virtual
machine or container is created from an image, the administrator can use a utility like cloud-init to generate new
SSH host keys. The key pair is a set of random mathematically related numbers generated by an algorithm that is
used to authenticate a user (which could also be another system). Administrators can also generate key pairs
manually with the ssh-keygen command. Incorrect or missing SSH keys are quite often the reason systems won’t
communicate with each other even when IP addresses and hostnames are correct.

Another factor that needs to be managed is the unique id of a system, or uuid. This uuid should be generated and
added to the D-Bus machine ID configuration file during installation or when first booting the VM or container.
The dbus-uuidgen command can be used to generate or read a universally unique ID for a system. This ID takes
the form of a 128-bit number that is unique, or at least very unlikely to be duplicated until the year 3400 A.D. The
uuid must remain unchanged until a system is rebooted so that processes know what kernel they are running on.
Additionally, the uuid can be used to identify any object in a cloud deployment and is often used by SQL databases
and other programming languages like JavaScript and Python to identify objects.

The cloud-init utility can be used to automate initial configuration parameters on a Linux virtual machine. In
addition to setting the hostname, SSH keys, and network configuration it can also set the root password, time zone,
mount points, and invoke custom scripts that provide additional configurations not supported by cloud-init settings.

Other critical settings to verify to ensure virtualized products, such as VMs and containers, function properly are
the virtualization extensions, which are effectively hardware support for virtualization that is built into the CPU,
such as Intel’s VT-x and AMD’s AMD-V extensions. These settings can be verified on a host system in the
/proc/cpuinfo file and in the system BIOS. For example, the flags in the /proc/cpuinfo file below can be used
to determine if Intel’s VT-x and AMD’s AMD-V extensions are installed:

sysadmin@localhost:~$ cat /proc/cpuinfo


Output Omitted...
physical id : 1
siblings : 8
core id : 0
cpu cores : 4
apicid : 32
initial apicid : 32
fpu : yes
fpu_exception : yes
cpuid level : 11
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca
cmov
pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdt scp lm
constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni
pclmulqdq dtes64 monitor ds_cplvmxsmx est tm2 ssse3 cx16 xtprpdcm pcid dca sse4_1 sse4_2
popcnt aes lahf_lm tpr_shadow vnmi flexpriority ept vpid dtherm ida arat
bugs :
bogomips : 4787.47
clflush size : 64

In the output above, in the flags field, the lm flag means that the system has a 64-bit CPU and the vmx flag means
that the Intel’s VT-x virtualization extension is enabled in the BIOS.

Consider This

To understand why virtualizations are needed, a brief explanation of CPU architecture is needed.

There are two main CPU architecture types: x86 and x64. The x86 architecture has roots that reach back to 8‐bit
processors built by Intel in the late 1970s. As manufacturing capabilities improved and software demands
increased, Intel extended the 8‐bit architecture to 16 bits. Later still, in 1985, Intel extended the architecture to 32
bits. The current 32-bit processor is what is known as x86. In 2003, AMD introduced a 64‐bit extension to the x86
architecture and later in 2004, Intel announced its own 64‐bit architectural extension. The current 64-bit processor
is known as x64. Understanding the difference between the 32-bit and 64-bit is important because virtualization
technology is compatible with 64-bit and but not with 32-bit.

To check which CPU type your Linux system is using, execute the lscpu command:

sysadmin@localhost:~$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Output Omitted...

Finally, sometimes virtualization platforms require a guest operating system to be supported with specific drivers,
called guest drivers or guest agents, that are not included in their standard distributions. Guest drivers provide
additional functionality and performance such as mouse support to allow your hardware mouse to communicate
with the VM, folder sharing between host and VM, automatic login settings, and time synchronization, to name a
few. These drivers are necessary because the way a hypervisor communicates with physical hardware is different
from how the OS would normally call hardware devices.
Key Terms

Application container
Applications that are packaged and deployed in a way that allows them to bypass traditional operating
systems and access computing resources.
Section 26.2
D-Bus machine id
The configuration file that contains the unique id of a system, or uuid. This uuid should be generated and
added to the D-Bus machine ID configuration file during installation or when first booting the VM or
container.
Section 26.5
Guest drivers
Virtualization software for guest operating systems that provides additional functionality and performance
such as mouse support to allow your hardware mouse to communicate with a VM, folder sharing between
host and VM, automatic login settings, and time synchronization.
Section 26.5
Linux container
A containerized application relies on a container engine to communicate with the host OS without a
hypervisor, or a guest VM.
Section 26.2 | Section 26.3
SSH host keys
A set of random mathematically related numbers generated by an algorithm that is used to authenticate a
user logging into another system.
Section 26.5
Virtual machine
A virtualized computing system that provides a complete operating system installed on virtual hardware
using a hypervisor to manage processes.
Section 26.2

Das könnte Ihnen auch gefallen