Linux For Developers - Jumpstart Your Linux Programming Skills (PDFDrive) PDF
Linux For Developers - Jumpstart Your Linux Programming Skills (PDFDrive) PDF
Developer’s Library titles cover a wide range of topics, from open source
programming languages and technologies, mobile application development,
and web development to Java programming and more.
Linux for
Developers
Jumpstart Your Linux Programming Skills
All rights reserved. Printed in the United States of America. This publication is protected by Proofreader
copyright, and permission must be obtained from the publisher prior to any prohibited SathishKumar
reproduction, storage in a retrieval system, or transmission in any form or by any means, Technical
electronic, mechanical, photocopying, recording, or likewise. For information regarding Reviewers
permissions, request forms and the appropriate contacts within the Pearson Education Matthew Helmke
Global Rights & Permissions Department, please visit www.pearsoned.com/permissions/. Keith Wright
ISBN-13: 978-0-13-465728-8 Editorial Assistant
Kim Boedigheimer
ISBN-10: 0-13-465728-4
Cover Designer
1 17 Chuti Prasertsith
Compositor
codeMantra
❖
“A best friend is the only one that walks into your life when
the world has walked out.”
— Shannon L. Alder
“Strong people don't put others down... They lift them up.”
— Michael P. Watson
3 The Filesystem 29
4 Essential Commands 47
5 Text Editors 67
6 System Administration 83
Index 189
Contents
Preface xii
2 Introduction to Linux 13
Accessing a Linux System 13
Choosing the Right Distribution 14
Logging In 15
Using the GUI 18
Basic Command-Line Execution 21
Command-Line Structure 22
Getting Help 22
Summary 28
3 The Filesystem 29
Understanding the Filesystem 29
Learning the Most Used Directories 30
Naming Considerations 30
Navigating the Filesystem 31
Managing the Filesystem 33
Managing Directories 36
Managing Files 37
Summary 45
viii Contents
4 Essential Commands 47
Command-Line Tools 47
Viewing Files 48
Finding Files 52
Comparing Files 54
Shell Features 55
Permissions 57
Developer Tools 59
File Compression Commands 59
The grep Command 62
Summary 66
5 Text Editors 67
The vi Editor 67
Why Learn vi? 68
What Is vim? 68
Essential vi Commands 69
Additional Editors 79
Emacs 79
gedit and kwrite 81
nano and joe 81
lime and bluefish 82
Summary 82
6 System Administration 83
Essential Tasks 83
Gaining Access to the Root Account 84
Displaying Disk Usage 86
Managing Software 88
Listing and Finding Software 89
Installing Software 90
User Accounts 91
Adding User Accounts 91
Modifying User Accounts 92
Deleting User Accounts 93
Understanding Groups 93
Managing Groups 93
Summary 94
Contents ix
Index 189
Preface
When I envisioned this book, I thought of it as the beginning of a journey. Your exact starting
point on this journey may differ from that of others, but the purpose of this book is to provide
you with what you need to know to start developing software on a Linux Operating System.
Some readers will already have software developing experience on Windows-based platforms.
For those folks, this book should serve as a guide to how software development differs on Linux
from the platform you are used to developing on.
Perhaps you already work in Linux, but want to start writing code. Again, this book will
provide you with an excellent starting point for that journey.
■ Chapter 8, “BASH Shell Scripting.” In this chapter you are introduced to the BASH
shell language. You learn how to create code that interacts with users as well as other
features of the BASH shell programming language.
■ Chapter 9, “Perl Scripting.” The focus of this chapter is how to program in the Perl
scripting language. Topics include flow control and variable usage.
■ Chapter 10, “Python Scripting.” You learn the basics of Python scripting in this
chapter, including the large variety of Python variable types, and how to reuse code
and flow control.
■ Chapter 11, “C, C++, and Java.” In this chapter you learn the essentials to create C,
C++, and Java code on Linux-based systems.
■ Lastly, Part IV, “Using GIT,” covers a very popular software revision control product called
Git. Using a revision control product, especially when working with teams of developers,
can save a lot of time, money, and effort.
■ Chapter 12, “GIT Essentials.” In this chapter you learn the concepts of GIT. Topics
include revision control concepts, GIT installation, and GIT features.
■ Chapter 13, “Manage Files with GIT.” In this chapter you learn how to use GIT features
such as staging, committing, and branches.
■ Chapter 14, “Manage Differences in Files.” The focus of this chapter is on how to deal
with different versions of files. You learn how to execute diffs (differences in files) and
merge files.
■ Chapter 15, “Advanced GIT Features.” You learn how to manage GIT repositories and
perform patching in this chapter.
Keith Wright and Matthew Helmke, thank your technical reviews. There is no doubt this is a
much better book than my original effort because of your feedback.
Chris Zahn: I couldn't have asked for a better editor. You make me look like I can put together a
coherent sentence—no small feat!
Debra Williams Cauley, thanks for seeing the value and providing a guiding hand throughout
this process.
About the Author
At the impressionable age of 14, William “Bo” Rothwell crossed paths with a TRS-80 Micro
Computer System (affectionately known as a “Trash 80”). Soon after, the adults responsible for
Bo made the mistake of leaving him alone with the TSR-80. He immediately dismantled it and
held his first computer class, showing his friends what made this “computer thing” work.
Since this experience, Bo’s passion for understanding how computers work and sharing this
knowledge with others has resulted in a rewarding career in IT training. His experience includes
Linux, Unix, and programming languages such as Perl, Python, Tcl, and BASH. He is the
founder and lead instructor of One Course Source, an IT training organization.
This page intentionally left blank
I
Open Source Software
One of the most important questions you need to answer when creating
software is, “Under what type of license will this software be released?”
Arriving at that answer can be a difficult journey.
You must determine what sort of protection you want to place on your
code as well as what you will allow others to do with the software that you
create. This part includes just one chapter, focusing on helping you decide
how to license your software. In this chapter, you learn the following:
■ The difference between closed and open source software
■ Open source protection concepts
■ The difference between primary open source licenses
This page intentionally left blank
1
Introduction to Open
Source Software
You have created an awesome program, and now you want to make it available to the public.
Now comes an important decision to make: what license to apply to your software.
This decision will have several important impacts, including the following:
Disclaimer
License issues can be complex and have a significant impact on how your software is used.
The discussion in this book is designed to provide you with a basic understanding of different
licenses but is not intended to provide any legal advice. The author of this book does not
intend to provide any legal advice. Always consider consulting proper legal advice before making
a decision regarding software licenses.
#include<stdio.h>
main()
{
printf("Hello World");
Typically, you can’t use this source code directly to run your program. Most languages require
a compile process in which the source code is converted into instructions that the operating
system can understand. The result is data that looks like garbage to a human but makes sense
to the operating system. See Figure 1.2 for a demonstration of source code that is converted
into compiled code.
#include<stdio.h>
main()
{
printf("Hello World");
If you choose to license your software as closed source, then you only provide the compiled
code to customers. Software open source licenses include access to the original source code.
Closed Source
Also called proprietary software, the purpose of closed source software is to keep the source
code a closely guarded secret. The idea is that if others can see the source code, then the source
code may be copied and illegally used. As a result, competitors of the organization that created
the software might end up having a negative impact on the financials of the organization that
created the software. As you can imagine, copying someone else’s software is much cheaper
than creating your own software.
Often the term closed source is used in place of the term commercial software, but this isn’t
accurate. Commercial software must be purchased in order to use it. Both closed and open
Defining Source Code 5
source software can be commercialized; the specific license determines whether the software is
commercial or “free.”1
■ Microsoft Windows
■ Adobe Photoshop
■ Apple macOS
Open Source
Software is considered open source when both the compiled and source versions of the code
are made available.2 The software license from the copyright holder grants certain rights to
view, modify, and distribute the software. A variety of open source licenses are available that
enable you to pick which rights are granted.
Although some open source software is free, in the economic sense, that isn’t a requirement
for open source software to be considered open source. Open source refers to the capability to
access the source code, not how the software can be used or any costs associated with
the software.
■ Linux3
■ Apache HTTP Server
■ Firefox
■ Git
■ Openoffice.org
“Free” Software
The concept of free in regards to software is not necessarily agreed upon by all. Some people
might consider free software to be software without cost. In other words, it doesn’t cost you
anything to obtain and use the software.
1 There is a reason why I put free in quotes. As you will soon read, the term free must be legally
defined in regards to software use.
2 Actually, some open source projects only provide the source code and leave it to the people who use
the software to compile it. Additionally, some languages don’t have a compile process, so a program
written in such a language would only include the source code.
3 Technically, Linux refers to the Linux kernel, which is the heart of the Linux operating system. Most of
the software found on Linux operating systems is also open source, but this isn’t a requirement for
inclusion in the OS.
6 Chapter 1 Introduction to Open Source Software
However, what does it mean to use software? Does this mean that the software can be used
in any way that the user wants, or are there some restrictions? Can this software be used
anywhere in the world, or are there geographic limitations? Are you free to modify the software
and distribute free copies of the modified format, or are these actions prohibited? As you can
see, free in terms of software isn’t so clear cut.
One way of defining the term free is to use the definition created by Richard Stallman and
published by Free Software Foundation (FSF):
“The word ‘free’ in our name does not refer to price; it refers to freedom. First, the freedom to
copy a program and redistribute it to your neighbors, so that they can use it as well as you.
Second, the freedom to change a program, so that you can control it instead of it controlling
you; for this, the source code must be made available to you.”
Note that the preceding definition mandates that free software also be open source software.
Not everyone agrees with this, and you will find some closed source freeware on the market.
Another way to define the term free is by the Four Freedoms, as defined by the Free Software
Foundation:
■ Freedom 0: “The freedom to run the program as you wish, for any purpose.”
■ Freedom 1: “The freedom to study how the program works and change it so it does your
computing as you wish. Access to the source code is a precondition for this.”
■ Freedom 2: “The freedom to redistribute copies so you can help your neighbor.”
■ Freedom 3: “The freedom to distribute copies of your modified versions to others. By
doing this you can give the whole community a chance to benefit from your changes.
Access to the source code is a precondition for this.”
These Four Freedoms are at the heart of what is referred to as FOSS (Free and Open Source
Software).4 FOSS attempts to address the challenge of defining what constitutes “free software.”
Note that the definition highlights the fact that not all free software is open source. Conversely,
not all open source software is licensed with the Four Freedoms.
Understanding the complex world of open source software and what part “freedom” plays
takes some time. See Figure 1.3 for a graphic that includes the various components of open
source software.
4 Often used interchangeably with the term FLOSS (Free/Libre and Open Source Software).
Choosing Open Source Licensing 7
Freedom Support
Distribute Utilize
Community Users
The graphic in Figure 1.3 highlights the complex combination of elements that make up open
source software. You can see that the developers write the source code, create documentation,
and provide support. However, the users of the software are often major components in
this process as well. In fact, some open source software includes little or no support or
documentation from the developer, but rather relies on a strong user base (the community) to
provide these critical elements.
Note that the freedoms to modify, distribute, and utilize are also depicted in the diagram in
Figure 1.3. Additionally, the software license is what provides these freedoms.
Options
Dozens of standard open source licenses and a large number of custom licenses are available.
Typically, they fall into one of the following four categories:
■ Standard—Regular licenses that are often reused for other software products. Typically,
these are specific to a country and many of them center around United States or
European laws.
■ International—Regular licenses that are often reused for other software products. Unlike
the standard licenses, these licenses are designed to be used throughout the world.
■ Special purpose—Licenses that are written for specific cases.
■ Nonreusable—Licenses that are not permitted to be used for any software product
besides the product the license was written for.
Key Terms
Regarding open source software licenses, you should understand a couple of key terms. One
term is copyleft, which ensures intellectual property (IP) can be copied or distributed as open
source software. The two forms of copyleft are
■ Strong—All derived works must maintain original copyleft.
■ Weak—Derived works don’t need to follow the original restrictions.
Another important open source license term is permissiveness. This term is related to derived
works and whether mixed licenses are allowed. The two forms of permissiveness are
■ Strict—Limited mixed licenses (no closed source or more permissive licenses)
■ Permissive—Allows mixed licenses
Examples
The following list describes some of the more popular open source licenses:
■ Very permissive
■ Non-copyleft
■ Use for any purpose
■ Must keep copyright message
■ User must agree that no warranty is provided
■ GNU General Public License (GPL):
■ Strong copyleft
■ Strict permissiveness
■ All derived works must be GPL
■ Two versions: v2 and v3
■ BSD License:
■ Very permissive
■ Non-copyleft
■ Three types:
■ Two-clause—Same as MIT
■ Three-clause—Derived work not endorsed by original holder
■ Four-clause—Advertising must acknowledge original holder
Useful Links
Hopefully, you now have a basic understanding of open source software and licenses. Clearly,
the topic is not a simple one, and spending additional time researching which license is the
best for your project and organization is important. In addition to consulting a legal expert,
you should find the following URL resources helpful:
■ http://choosealicense.com—This tool uses a series of questions to help you determine
which license works best for your situation. It provides a good start, but you should also
consult a legal expert before making a final decision.
■ http://fsf.org—The website for the Free Software Foundation offers a great deal of useful
information regarding open source software and licenses.
■ http://opensource.org—This is another great resource to learn more about open source
licenses.
Summary
In this chapter you learned the differences between closed and open source software.
The concept of free software was also explored. Lastly, you learned about some of the basics of
open source licenses. At this point you should be able to start the process of determining what
type of license under which to release your software. However, remember that you want to put
a lot of time, effort, and thought into this decision before releasing your software because these
licenses can have a powerful effect on how your software will be used by the community.
II
Linux Essentials
1 Certainly, the topics presented will also be useful to these sets of Linux users.
This page intentionally left blank
2
Introduction to Linux
What exactly is Linux? The answer can be a complex one. Technically, Linux is a piece of
software called the kernel. The kernel handles tasks such as booting the system and interacting
with hardware devices. By itself, the kernel doesn’t really provide users with any functionality.
The rest of the operating system (OS), consisting of the filesystem and a large number of
commands, is what provides users with useful features.
Although Linux is technically just the kernel, many people refer to the entire OS as Linux.
In reality, the collection of software that makes up the OS is known as a Linux distribution
(also called a distro). Many distros are available to choose from, which often results in some
confusion for novice Linux users.
What Is a Distribution?
A distribution is a collection of Linux software that is maintained by an organization. Each
distribution has features that make it unique. Some distributions are designed for general
use whereas others are designed for a very specific use case, like a firewall or a web server.
Picking the distro that works best for you might take some time. The website distrowatch.com
can aid you in this endeavor. Additional information is also provided later in this chapter.
■ During the installation, consider accepting the defaults. Typically, the defaults provide
you with the software that you need as a developer. You can always reinstall the distro
in the future or add additional software using the tools described in Chapter 6, “System
Administration.”
Although these might not be all the features you or your organization consider when choosing
a distro, the preceding list provides you with an idea of what features are normally considered.
Because literally hundreds of distros exist, I recommend exploring http://distrowatch.com, a
website devoted to monitoring these distros, their features, and their popularity.
2 Other families of distros exist, but these three are by far the most often used. If you want to see a
“family tree” (somewhat overwhelming), I suggest viewing the following graphic: https://upload.wikimedia
.org/wikipedia/commons/1/1b/Linux_Distribution_Timeline.svg
Accessing a Linux System 15
Regarding the information provided in this book, in most cases which distro you use does not
matter. However, for some topics the distro does matter. When these situations arise, I provide
detailed information regarding the differences between the distros. Otherwise, the examples
make use of different distros to highlight that core functionality is largely the same across
Linux distributions.3
Logging In
Typically, there are three ways to log in to a Linux system:
■ Via the GUI—On laptops, desktops, and some servers, a GUI-based login appears by
default.
■ Via the command line—Administrators commonly do not install the GUI software on
servers because that software is a huge hardware hog (CPU, RAM, and so on). On these
servers, you typically see a command-line login.
■ Via the network—A network-based login could either be via command line (very
common) or GUI (not as common). The machine that you log into must have special
software installed and enabled to allow this sort of access.
3 As a developer, you shouldn’t get too hung up on which distro to use. This is often the choice of the
company system administrator. Knowing the differences and which ones can affect a developer is
what you should focus on (and that is the approach for this book).
16 Chapter 2 Introduction to Linux
Figure 2.1 The default display manager on CentOS (left) and MintOS (right)
The good news is that regardless of which display manager you use, the basic operation
shouldn’t change. You either select your user name from a list or type your user name in the
dialog box provided. Then you are prompted for your password. As you become more experi-
enced, try exploring other options provided by your display manager, such as shutting down
your system.
4 If you are working in a virtual machine, this keystroke combination might vary.
Accessing a Linux System 17
To log out of a command-line environment, type exit and then press the Enter key. To return
to the GUI screen, press either Ctrl+Alt+F1 or Ctrl+Alt+F2.
5 Note that normally VNC requires installing a VNC server on the Linux box and configuring it.
6 Unless you have access to root privileges. See Chapter 6 for details regarding software.
18 Chapter 2 Introduction to Linux
In the following example, the “bob” user on the local machine logged in to the machine
named “remote” using the “student” account (Note: Instead of a machine name, an IP address
can be used):
bob@ubuntu:~$ ssh student@remote
The authenticity of host 'remote' can't be established.
ECDSA key fingerprint is 8a:d9:88:b0:e8:05:d6:2b:85:df:53:10:54:66:5f:0f.
Note the message about the key fingerprint. This is used in the future to verify that you are
logging in to the correct system and not some fake machine that has assumed the identity of
the remote system. This question only appears the first time you log in to this system.
With so many desktops available, you might ask yourself “Which one should I use?” To some
extent, that question might be answered for you when you choose your Linux distribution.
Most distros have a “favored default” desktop which will be installed and used automatically.
Although other desktops might be available for the distro, you typically need to install them
separately.
Using the GUI 19
In some cases, the developers of the distro might provide you the option of choosing your
desktop before you install the distro. For example, consider Figure 2.3, which displays the
download links for the Mint distribution.
Figure 2.3 shows the different install options provided, primarily divided by the type
of desktop. Additionally, a user with administrative access can install multiple desktops on a
single system. If there are multiple desktops, you could choose which desktop you want to use
before you log in, as demonstrated in Figure 2.4.
20 Chapter 2 Introduction to Linux
After you successfully log in, a desktop appears. The overall look and feel of the desktop varies.
However, figuring out where things are on a particular desktop shouldn’t take too long. For
example, look at Figure 2.5, which displays the default desktops for MintOS.
As you can see, the Cinnamon and MATE desktops look very similar. Both provide a menu
(bottom left) that enables you to access additional programs and features. Both have quick
launch icons and both provide system information (bottom right) such as date/time. The
choice comes down to exploring the desktop that you are using rather than memorizing where
features reside for a specific desktop.
The most common shell program in Linux is the BASH7 shell. This book shows BASH
shell–based examples.
7 BASH stands for Bourne Again SHell. It is based on an older Unix shell named the Bourne Shell.
22 Chapter 2 Introduction to Linux
Command-Line Structure
A command has three components:
Getting Help
You might be wondering how to tell what options and arguments a command will accept.
Several ways exist to display documentation that can help you use a command. One method
you could use is the help command:
bo@mintos:~ > help alias
alias: alias [-p] [name[=value] ... ]
Define or display aliases.
Options:
-p Print all defined aliases in a reusable format
Exit Status:
alias returns true unless a NAME is supplied for which no alias has
been defined.
As you can see from the output of the help alias command, the command accepts the
-p option. Because the option is enclosed within square brackets, the option is not required for
the command to run. Additionally, you can include a name or name=value argument with the
command. Again, the square brackets indicate that these arguments are not required and that
name does not require an =value argument.
One drawback of the help command is that is only works on built-in shell commands. These
commands are part of the BASH shell, not a separate executable.8 The majority of commands
that you will execute are not built-in shell commands, so the help command won’t be that
helpful.
However, almost all commands have documentation available via a command called the man
command (man is short for manual). To view a man page for a command, execute man cmd,
replacing cmd with the command name. For example, to view the man page for the cal
command, execute man cal.
Note
You will eventually discover that not only commands have man pages. Configuration files and
other things have man pages, too.
The man page for a given command9 can be quite large. To facilitate the process of reading the
man page, you can use several keys to move through the document:
■ <spacebar>—Move down one screen.
■ <ENTER>—Move down one line.
■ b—Move back one screen.
■ /term—Search for term.
■ h—Display help screen.
■ q—Quit displaying man page.
Note that these are just a few of the commands that you can use to display a man page.
The h key provides a full list of commands.
8 Executable is a term that essentially means program. If a file can be run like a program, it should
have the execute permission set.
9 Not only commands have man pages. Configuration files and other items have man pages, too.
24 Chapter 2 Introduction to Linux
Helpful Suggestion
When you are first learning Linux, you might find using man pages to be difficult. The format
and syntax of the output can be a challenge to follow. I highly suggest you get as much
practice as you can reading man pages. You can do this by looking at the man page for each
new command that you learn. Try to find a new feature or option for the new command. Test
your ability to run the command with different options based on what you learn from the man
page. Learning how to read man pages just comes down to practice.
A typical man page has several different sections. The output begins with a line like the following:
CAL(1) BSD General Commands Manual CAL(1)
This indicates the command and the category. This chapter covers man page categories a bit later.
The next section provides a brief description of the command like the following:
NAME
cal, ncal — displays a calendar and the date of Easter
After this description, you see a summary of how you can execute the command:
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]
Recall that square brackets indicate something that isn’t required but which is a valid option.
For example, you could just run the cal command with no options or arguments:
bo@mintos:~ > cal
July 2016
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
31
You could also use an option, such as -3:
bo@mintos:~ > cal -3
June 2016 July 2016 August 2016
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 1 2 1 2 3 4 5 6
5 6 7 8 9 10 11 3 4 5 6 7 8 9 7 8 9 10 11 12 13
12 13 14 15 16 17 18 10 11 12 13 14 15 16 14 15 16 17 18 19 20
19 20 21 22 23 24 25 17 18 19 20 21 22 23 21 22 23 24 25 26 27
26 27 28 29 30 24 25 26 27 28 29 30 28 29 30 31
31
Basic Command-Line Execution 25
The next section provides a greater level of detail regarding how the command and its
options work:
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 terminal.
If arguments are not specified, the current month is displayed.
The options are as follows:
-h Turns off highlighting of today.
Some commands also provide a See Also section that includes a list of related commands:
SEE ALSO
calendar(3), strftime(3)
Depending on the man page that you are viewing, you might see additional sections. However,
the critical ones have been described here.
These different types of man pages are broken into categories,10 as shown in the man page for
the man command:
bo@mintos:~ > man man
{output omitted}
The table below shows the section numbers of the manual followed by
the types of pages they contain.
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 eg /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]
In most cases, you don’t have to worry much about these categories. When you execute the
man command, it first searches category 1 for the man page. If it doesn’t find it, it then searches
the next category.11 Eventually it finds and displays the man page or displays an error if it can’t
find the man page in any category:
bo@mintos:~ > man nope
No manual entry for nope
In some cases you must specify the category. For example, there is a user command named
passwd (category 1) and a file format named passwd (category 5). If you execute the man passwd
command, the passwd command man page displays. To view the man page for the passwd file,
you must execute the man 5 passwd command.
Tip
Most distributions have a GUI-based man page viewer that you might find easier to use. Just
type xman to launch it.
Info Documentation
In addition to man pages, you might find info documentation helpful. Not all commands and
files have info documentation, but for those that do, using it can be easier than using man
10 I call them categories, but the man page calls them sections. I think this term is confusing because
sections is also used to refer to different pages within a single man page. So, I call these collections
of man pages categories to avoid confusion.
11 The following line in the man configuration file determines the order in which man page sections are
searched:
SECTION 1 1p 8 2 3 3p 4 5 6 7 9 0p n l p o 1x 2x 3x 4x 5x 6x 7x 8x
Basic Command-Line Execution 27
pages. To use an info document, execute the info command followed by the command to
display; for example, info ls.
The documentation found in info pages tends to be more verbose than in man pages. The
sections of info pages are also organized differently than man pages. Instead of one long docu-
ment of text, info pages appear in hyperlinked sections. For example, if you scroll down the
document for the ls command (use the down-arrow key on your keyboard), you see this:
* Menu:
* Which files are listed::
* What information is listed::
* Sorting the output::
* Details about version sort::
* General output formatting::
* Formatting file timestamps::
* Formatting the file names::
This is a menu of subcategories you can jump to by placing your cursor on a menu item and
pressing the Enter key. After you’re in a subcategory, type the letter u to go back up one level.
To see additional commands, press the H or ? key.
Note
In the help section, press l to exit help and return to the info page. Use q to quit the info
document and return to the command line.
Tip
You can learn a lot from info documentation. Try executing the info command with no
arguments. Then scroll down to the menu section, pick a category, press the Enter key, and
start exploring.
Additional Documentation
In addition to man pages and info documentation, you might find the files in the /usr/share/
doc directory to be useful. Chapter 3, “The Filesystem,” covers how to navigate the filesystem,
which will allow you to access the documentation in the /usr/share/doc directory. For now, just
realize that additional documentation exists in this directory (typically it is geared more toward
administrators, but some end user documentation exists in this directory, too).
Linux Humor
Ever wonder whether the computer is actually watching you as you are working? Type the xeyes
command in a terminal window (this only works in a GUI environment) to get the answer to this
question.
28 Chapter 2 Introduction to Linux
Summary
In this chapter you learned how to log in to an existing Linux distribution via the command
line, a graphical user interface, or across the network. You also learned about different desktops,
which provide the look and feel of a GUI. Lastly, you learned how to get additional help using
man pages and info documentation.
3
The Filesystem
Regardless of what you plan to use the Linux distribution for, you need to know how
to navigate the filesystem. The filesystem is how the files are structurally organized into
directories. Understanding this structure and how to manage the files is critical to using Linux.
For example, in Microsoft Windows, physical drives are assigned letters, such as C: or F:. They
may be visible under the My Computer icon. Linux doesn’t use drive letters or a My Computer
icon. Instead, all drives, including network drives and removable media, are located under the
root directory.
The root directory is symbolized by the / character. This character is also used to separate
directory and filenames in a path. Think of the path as directions to get to a file or directory.
For example, the path /home/bob/sample.txt refers to a file named sample.txt that is in the
bob directory. The bob directory is under the home directory, which in turn is under the root
directory. See Figure 3.1 for a small example of a Linux filesystem.
sample.txt
Naming Considerations
When you create a file or directory, you should take into consideration the following
guidelines:
■ Files and directories have same name rules.
■ Names are case sensitive. This means that a file named Data.txt is not the same as a file
named data.txt.
1 I realize this part might be a bit confusing because there are really three “roots” in Linux.
The /directory is called the root directory because it is the start of the filesystem. The system
administrator is called the root user and the home directory for the root user is the /root directory.
Linux users often refer to the root directory as the “slash” directory to avoid confusion with /root and
the root user.
Navigating the Filesystem 31
■ Special characters are permitted. However, you should avoid using whitespace (space
and tab characters) and certain special characters called metacharacters (*, ?, [, ], !, $, &,
and so on). Metacharacters are special characters to BASH, and they can create problems
when used in a file or directory name.
■ The / character is used to separate files and directory names: /usr/share/doc. As a result,
you cannot use the / character in file or directory names.
■ Extensions (.txt, .cvs, and so on) are permitted but normally have no special meaning to
BASH. In some rare cases they may be required for a specific command, but Linux and
the BASH shell typically don’t require specific extensions for files. However, extensions
are useful for users because understanding the purpose of a file is easier if the extension
is provided (some GUI interfaces also make use of extensions to determine which
GUI-based program to launch).
■ There are some special predefined directory names:
■ ~ —Represents the current user’s home directory
■ . —Represents the current working directory (the directory you are working in when
using a command-line shell)
■ .. —Represents one level above the current working directory
When you first open a shell, you are automatically placed in your home directory. The
directory you are in is referred to as your working directory or current directory. A common task
is to switch the working directory to another directory, a process called change directory.
A path or pathname is how you refer to a file or directory in the directory structure. The two
types of pathnames are
■ Absolute—A path that always starts from the root directory; for example, /home/bob/
sample.txt
■ Relative—A path that starts from the current directory; for example, if you are in the
/home directory and want to access the sample.txt file that is under the bob directory
(which is under the /home directory), you use bob/sample.txt.
Note
Absolute paths always start with a / character but relative paths never start with a / character.
To help understand the difference between an absolute and relative path, consider Figure 3.2.
32 Chapter 3 The Filesystem
In this example you are in the /home/julia directory and want to switch to the /usr/bin
directory. To switch directories, you can use the cd command, and to view the current directory
you can use the pwd2 directory. The following example demonstrates using an absolute path:
julia@mintos:~ > pwd
/home/julia
julia@mintos:~ > cd /usr/bin
julia@mintos:/usr/bin > pwd
/usr/bin
Note that the prompt (julia@mintos:/usr/bin) indicates the current directory, so the pwd
command isn’t always necessary. This isn’t always the case because the prompt is customizable.
The next example demonstrates using a relative path to move from the /home/julia directory
to the /usr/bin directory. Note that the cd command, when given no arguments, returns you
to your home directory:
julia@mintos:/usr/bin > cd
julia@mintos:~ > pwd
/home/julia
julia@mintos:~ > cd ../../usr/bin
julia@mintos:/usr/bin > pwd
/usr/bin
Why use ..? Because a relative path requires giving directions from the current directory, and
you have to tell the cd command to “go up” two levels before going down to the usr and bin
directories.
2 pwd stands for print working directory. In early Unix times, monitors were rare, so output was often sent to
an actual printer. Because Unix is the precursor to Linux, many of the commands are named the same.
Managing the Filesystem 33
Clearly, in this case, the absolute path was easier, but that isn’t always the case. For example,
now consider Figure 3.3.
You want
to go here.
Now you want to move from the /home/julia directory to the /home/sarah directory.
The first example uses an absolute path:
julia@mintos:/usr/bin > cd
julia@mintos:~ > cd /home/sarah
julia@mintos:/home/sarah > pwd
/home/sarah
The relative method is easier to use in this case. Consider if you were 20 levels deep in
the directory structure and you just wanted to move up one level and down to another
subdirectory. Using an absolute path would result in a lot of typing whereas a relative path
would be much less work. The lesson here is to know both methods because one is going to
be easier than the other most of the time.
By default the ls command displays all files in the current directory except hidden files.
A hidden file has a . character at the beginning of the filename. To see all files, including
hidden files, use the -a option to the ls command:
julia@mintos:/etc/sound/events > ls -a
. .. mate-battstat_applet.soundlist
Recall that . represents the current directory and .. represents the directory above the current
directories. You will always see these two hidden files3 regardless of which directory you are in.
To understand why some files are hidden, look at the files in a typical user’s home directory:
julia@mintos:/etc/sound/events > ls -a ~
. .bash_history .bashrc .config .gimp-2.8 .local .profile
.. .bash_logout .cache .face.icon .kde .mozilla
Each of the hidden files (in some cases they are directories) that you see in this output contain
information that modifies the user’s environment. For example, .bashrc and .profile modify
how the BASH shell works for the current user. The .mozilla directory contains configuration
settings for Firefox, a web browser provided by the Mozilla Foundation.
How could you tell if .bashrc was a file or .mozilla was a directory? Use the -l option:
julia@mintos:/etc/sound/events > ls -a -l ~
total 48
drwxr-xr-x 8 julia julia 4096 Jul 14 17:26 .
drwxr-xr-x 5 root root 4096 Jul 14 17:26 ..
-rw------- 1 julia julia 72 Jul 14 17:26 .bash_history
-rw-r--r-- 1 julia julia 220 Apr 8 2014 .bash_logout
-rw-r--r-- 1 julia julia 1452 Jan 5 2016 .bashrc
drwx------ 3 julia julia 4096 Jul 14 17:12 .cache
drwxr-xr-x 6 julia julia 4096 Jun 5 15:59 .config
lrwxrwxrwx 1 julia julia 5 Jun 5 14:40 .face.icon -> .face
drwxr-xr-x 2 julia julia 4096 Jan 5 2016 .gimp-2.8
drwxr-xr-x 3 julia julia 4096 Jan 5 2016 .kde
drwxr-xr-x 3 julia julia 4096 Jan 5 2016 .local
drwxr-xr-x 3 julia julia 4096 Jan 5 2016 .mozilla
-rw-r--r-- 1 julia julia 675 Apr 8 2014 .profile
When you use the -l option, each line describes detailed information for a file. See Figure 3.4
for a demonstration of the details that are provided.
3 You may be wondering if I accidently called . and .. a file. In Linux, everything is considered a file,
including directories. A directory is just a special file that holds other directories. Normally I would
refer to these as directories, but I wanted to take the opportunity to make this point as it could prove
important as you dive deeper into Linux.
Managing the Filesystem 35
■ File type—d means this is a directory whereas - means it is a plain file. There are
additional file types, but these are the primary two you should know.4
■ Permissions—These are used to allow or disallow access to the file. Chapter 4, “Essential
Commands” covers permissions.
■ Hard link count—A more advanced topic normally reserved for system
administrators, this is a file that is hard linked and shares the same data block space
with another filename.
■ User owner—The user who owns the file has special access to the file. For example, only
the user owner (and the root user) can change the permissions of a file.
■ Group owner—Group owners have special access to the file via permissions.
■ File size—The size of the file in bytes.5
■ Modification timestamp—The date and time the file was last modified.6
■ Filename—The name of the file.
Note
You can use many other options with the ls command. Recall the suggestion from Chapter 2,
“Introduction to Linux,” regarding viewing the man page for each new command that you learn.
This would be an excellent time to make use of that suggestion!
4 You may also want to know about l, which stands for symbolic link. A symbolic link is a file that
points to another file. If you have experience in Windows, symbolic links are akin to shortcuts on
your desktop.
5 File sizes in bytes can be difficult to comprehend, especially for large files. Consider including the -h
option to show file sizes in “human readable” sizes.
6 If the file was last modified within the past six months, the timestamp includes a month, day, and
time. If the file was last modified more than six months ago, the time is replaced with the year.
36 Chapter 3 The Filesystem
Managing Directories
To create a new directory, use the mkdir command:
julia@mintos:~ > ls
julia@mintos:~ > mkdir data
julia@mintos:~ > ls -l
total 4
drwxrwxr-x 2 julia julia 4096 Jul 15 09:34 data
This failure occurs because to make the samples directory in the test directory, the test
directory must exist. To make both the samples and test directory, use the -p option to the
mkdir command:
julia@mintos:~ > ls
data
julia@mintos:~ > mkdir -p test/samples
julia@mintos:~ > ls
data test
julia@mintos:~ > ls test
samples
To delete an entire directory structure, including all the files and subdirectories, use the rm
command with the -r option:
julia@mintos:~ > ls
test
julia@mintos:~ > rm -r test
julia@mintos:~ > ls
julia@mintos:~ >
Managing the Filesystem 37
Note
The rm command is normally used to delete files. With the -r option, it can delete
directories and files.
Be careful when using the rm -r command. You could accidentally delete files that you really
need to keep. Consider using the -i option when executing the rm -r command because this
enables you to pick which files to delete. When prompted, answer y for yes and n for no:7
julia@mintos:~ > rm -ri events
rm: descend into directory 'events'? y
rm: remove regular file 'events/mate-battstat_applet.soundlist'? y
rm: remove directory 'events'? n
Managing Files
To copy a file, use the cp command. You should have two arguments: what file to copy and
where to copy it:
julia@mintos:~ > ls
events
julia@mintos:~ > cp /etc/hosts.
julia@mintos:~ > ls
events hosts
Be careful when using the cp command because you can accidentally overwrite an existing file.
This happens when the destination (where to copy the file) contains a file with the exact same
name as an existing file:
ulia@mintos:~ > ls -l hosts
-rw-r--r-- 1 julia julia 221 Jul 15 10:47 hosts
julia@mintos:~ > cp /etc/passwd hosts
julia@mintos:~ > ls -l hosts
-rw-r--r-- 1 julia julia 2074 Jul 15 10:52 hosts
You can tell that the original file was overwritten because the file size changed (221 bytes to
2074 bytes) and the modification timestamp changed. To avoid overwriting an existing file,
use the -i option:
julia@mintos:~ > ls -l hosts
-rw-r--r-- 1 julia julia 221 Jul 15 10:56 hosts
julia@mintos:~ > cp -i /etc/passwd hosts
cp: overwrite 'hosts'? n
julia@mintos:~ > ls -l hosts
-rw-r--r-- 1 julia julia 221 Jul 15 10:56 hosts
7 The rm-ri command is the same as the rm -ir command, which is the same as the rm -r -i
command. In most cases, single character options can be combined and order doesn’t matter.
38 Chapter 3 The Filesystem
The -i option stands for “interactive” mode and prompts you if the cp command will end up
overwriting an existing file.
Wildcards
Suppose you want to copy all the files that end in .conf from the /etc directory to a directory
called config in your home directory. You look in the /etc directory and realize that there are
about 20 of these files. You don’t want to have to type in the name of each file. This is a case in
which you want to use wildcards.
With wildcards, you can make use of special characters to match file or directory names. For
example, you can list all the files in the /etc directory that end in .conf by executing the
following command:8
julia@mintos:~ > ls -d /etc/*.conf
/etc/adduser.conf /etc/insserv.conf /etc/pam.conf
/etc/apg.conf /etc/inxi.conf /etc/pnm2ppa.conf
/etc/avserver.conf /etc/kernel-img.conf /etc/request-key.conf
/etc/blkid.conf /etc/kerneloops.conf /etc/resolv.conf
/etc/brltty.conf /etc/ld.so.conf /etc/rsyslog.conf
/etc/ca-certificates.conf /etc/libao.conf /etc/sensors3.conf
/etc/casper.conf /etc/libaudit.conf /etc/sysctl.conf
/etc/colord.conf /etc/logrotate.conf /etc/ts.conf
/etc/debconf.conf /etc/ltrace.conf /etc/ucf.conf
/etc/deluser.conf /etc/mke2fs.conf /etc/uniconf.conf
/etc/fuse.conf /etc/mtools.conf /etc/updatedb.conf
/etc/gai.conf /etc/netscsid.conf /etc/usb_modeswitch.conf
/etc/hdparm.conf /etc/nsswitch.conf /etc/wodim.conf
/etc/host.conf /etc/ntp.conf /etc/wvdial.conf
The * character represents “zero or more characters in a filename.” So, you are asking to see
files in the /etc directory that begin with “zero or more characters, followed by .conf.” Using
the * character, you can copy these files into a directory under your home directory (don’t
worry if you get an error message for some of the files): 9
8 You may be wondering why I used the -d option with the ls command. Be patient; I will explain this soon.
9 The cp command in this example generates some error messages because of file permission issues.
Chapter 4 covers file permissions. For now, don’t worry if your command generates a few error mes-
sages like these.
Managing the Filesystem 39
Use the ? character to represent a single character. So, to display any files in the /etc directory
that have filenames that are exactly four characters in length, execute the following command:
julia@mintos:~ > ls -d /etc/????
/etc/acpi /etc/dkms /etc/init /etc/mono /etc/perl /etc/udev
/etc/cups /etc/dpkg /etc/kde4 /etc/mtab /etc/sgml /etc/xrdb
/etc/dhcp /etc/gimp /etc/ldap /etc/newt /etc/skel
The ? character will match any single character. If you want to match a specific character,
you can use a set of square brackets, []. For example, to match a file in the /etc directory that
begins with an a, b, or c character, execute the following command:
julia@mintos:~ > ls -d /etc/[abc]*
/etc/acpi /etc/avserver.conf /etc/chatscripts
/etc/adduser.conf /etc/bash.bashrc /etc/chromium-browser
/etc/adjtime /etc/bash_completion /etc/colord.conf
/etc/akonadi /etc/bash_completion.d /etc/compizconfig
/etc/alternatives /etc/bindresvport.blacklist /etc/console
/etc/anacrontab /etc/blkid.conf /etc/console-setup
/etc/apg.conf /etc/blkid.tab /etc/cracklib
/etc/apm /etc/bluetooth /etc/cron.d
/etc/apparmor /etc/brlapi.key /etc/cron.daily
/etc/apparmor.d /etc/brltty /etc/cron.hourly
/etc/apport /etc/brltty.conf /etc/cron.monthly
/etc/apt /etc/ca-certificates /etc/crontab
/etc/at.deny /etc/ca-certificates.conf /etc/cron.weekly
/etc/at-spi2 /etc/calendar /etc/cups
/etc/avahi /etc/casper.conf /etc/cupshelpers
Using a Range in [ ]
Note that [abc] is the same as [a-c]. Using a - enables you to specify a range of permitted
characters. Just be sure it is a valid range according to the ASCII text table. You can view this
table by executing the command man ascii.
40 Chapter 3 The Filesystem
The wildcard characters are not specific to any particular command. Instead, they are part of
the BASH shell. This is important to note because it means you can use wildcard characters with
any command. The BASH shell interprets the wildcard characters before the command runs.
In fact, the command doesn’t even know that wildcard characters are being used. For example,
consider the following command:
julia@mintos:~ > ls -d /etc/[xyz]*
/etc/xdg /etc/xemacs21 /etc/xml /etc/xrdb /etc/zsh
The argument /etc/[xyz]* isn’t passed into the ls command. BASH first converts the
wildcard pattern into the filename(s) that match. So, if you execute the ls -d /etc/[xyz]*
command, the command that is really executed is the ls -d /etc/xdg /etc/xemacs21 /
etc/xml /etc/xrdb /etc/zsh command.
This is also why when you use wildcards with the ls command, you should use the -d option.
When the ls command runs and is passed a directory name as an argument, the contents of
the directory are listed:
julia@mintos:~ > ls /etc/xdg
autostart menus Trolltech.conf user-dirs.conf user-dirs.defaults
When you use wildcard characters, some of the matching files could actually be directories.
This produces output that you likely don’t want to receive:
julia@mintos:~ > ls /etc/[xyz]*
/etc/zsh
/etc/xdg:
autostart menus Trolltech.conf user-dirs.conf user-dirs.defaults
/etc/xemacs21:
site-start.d
/etc/xml:
catalog docbook-xml.xml.old rarian-compat.xml xml-core.xml
catalog.old docbook-xsl.xml sgml-data.xml xml-core.xml.old
docbook-xml.xml docbook-xsl.xml.old sgml-data.xml.old
/etc/xrdb:
Editres.ad Emacs.ad General.ad Motif.ad Tk.ad Xaw.ad
To avoid having the contents of all of these directories, use the -d option to the ls command.
The -d option tells the ls command “if any argument happens to be a directory, don’t display
what is in that directory, just show the directory name.”
Managing the Filesystem 41
Redirection
Suppose you run a command and you decide that you want to store the output of the
command into a file for future use. In a situation like this, you can use a process called redirec-
tion. The idea is to redirect the output of a command into a file or another process. You can
also redirect the input to a command from a file.
■ Standard input (stdin)—The data that is sent into the command. This is not an
argument but rather additional information that is being sent into a command. Typically,
this data comes from a user who is executing the command. The user provides this data
via the keyboard. This input could be redirected from a file or another process.
■ Standard output (stdout)—The data that is sent from the command when all goes well.
Typically, this appears on the screen, but it can be sent to a file or to another command.
■ Standard error (stderr)—The data that is sent from the command when an error occurs.
Typically, this appears on the screen, but it can be sent to a file or to another command.
Note
You use the cat command to display small files; it is covered in Chapter 4.
You use the > character when you want to create a new file or overwrite the contents of an
existing file. If you want to append to an existing file, use two > characters:
julia@mintos:~ > cat mycal
December 2000
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
31
42 Chapter 3 The Filesystem
The output of the cal and date commands in the previous examples is considered standard
output because the command ran successfully. Notice that if a command fails for some reason
(such as improper options or arguments), the command’s output is not redirected to a file when
you use the > or >> characters:
julia@mintos:~ > cal -5 12 2000 > mycal
cal: invalid option -- '5'
Usage: cal [general options] [-hjy] [[month] year]
cal [general options] [-hj] [-m month] [year]
ncal [general options] [-bhJjpwySM] [-s country_code] [[month] year]
ncal [general options] [-bhJeoSM] [year]
General options: [-NC31] [-A months] [-B months]
For debug the highlighting: [-H yyyy-mm-dd] [-d yyyy-mm]
julia@mintos:~ > cat mycal
julia@mintos:~ >
When an error occurs, the command sends output to stderr. You can redirect this output by
using the 2> characters:10
julia@mintos:~ > cal -5 12 2000 > mycal 2> error
julia@mintos:~ > cat error
cal: invalid option -- '5'
Usage: cal [general options] [-hjy] [[month] year]
cal [general options] [-hj] [-m month] [year]
ncal [general options] [-bhJjpwySM] [-s country_code] [[month] year]
ncal [general options] [-bhJeoSM] [year]
General options: [-NC31] [-A months] [-B months]
For debug the highlighting: [-H yyyy-mm-dd] [-d yyyy-mm]
10 It might seem strange that you use > to redirect stdout and 2> to redirect stderr. However, the
official way you redirect stdout is by using the 1> characters. Because stdout is more commonly
redirected than stderr, the BASH shell permits you to drop the 1 before the > character.
Managing the Filesystem 43
■ The 2> characters either create a new file or overwrite the contents of an existing file. To
append stderr messages to an existing file, use 2>>.
■ To send all output, both stdout and stderr, to a single file, use the following11:
cmd > file 2>&1
■ Sometimes you will want to run a command without seeing any of the error messages. To
discard the output of a command, send it to the file. This file is called the “bit bucket” or
“black hole” because whatever you send to the file will be discarded.
Redirecting stdout and stderr is a fairly common practice. Conversely, redirecting stdin
(standard input) is much rarer. Before demonstrating redirecting stdin, consider the following
exercise, which demonstrates where stdin comes from by default. Start by executing the
following command:
julia@mintos:~ > tr 'a-z' 'A-Z'
It looks like this program hangs, but it is just waiting for stdin. You can provide stdin from the
keyboard. For example, type a sentence and then press the Enter key:
julia@mintos:~ > tr 'a-z' 'A-Z'
today is a good day to learn linux
TODAY IS A GOOD DAY TO LEARN LINUX
You can see what the tr command does with the input. It translates all lowercase letters to
uppercase letters. Clearly, performing this task on a file, not input from the keyboard, would
be much more useful. Unfortunately, the tr command doesn’t allow you to provide a filename
(By the way, to stop the current tr command, hold down the Ctrl key and press the C key. This
is normally written as Ctrl+C or just ^C):
julia@mintos:~ > tr 'a-z' 'A-Z' mycal
tr: extra operand 'mycal'
Try 'tr --help' for more information.
The tr command only accepts input from stdin. So, you need to tell the BASH shell to pull
stdin data from a file rather than from the keyboard. To do this, use the < character:
julia@mintos:~ > tr 'a-z' 'A-Z' < mycal
DECEMBER 2000
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
31
11 You can also use the following syntax in the BASH shell: cmd &> file
44 Chapter 3 The Filesystem
Note that the output of the tr command is sent to the screen via stdout. Essentially, it is now
lost, but you can also run the command and redirect stdout to a file (just make sure it is a
different file than the original):
julia@mintos:~ > tr 'a-z' 'A-Z' < mycal > mynewcal
julia@mintos:~ > cat mynewcal
DECEMBER 2000
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
31
Most commands that require input accept a file as an argument, so you won’t redirect stdin
nearly as often as you will redirect stdout or stderr. However, some advanced scenarios exist in
which knowing how to redirect stdin is very useful.
You can also redirect stdout into another command instead of a file. This is useful because
many of the commands on the system perform filtering or paging functions.12
For example, execute the following command: ls -l /etc. Typically, the /etc directory
contains hundreds of files, so the output of this ls command will quickly scroll by on the
screen. This can make viewing large amounts of information difficult. The solution is to send
the output of the ls command into another command that will display one page of data at a
time: ls -l /etc | more.
The | character is used to redirect stdout to another command. It becomes the stdin of the
command to the right of the | character, in this case the more command, which displays data
one page at a time. Chapter 4 covers the more command in greater detail. For now, use the
spacebar to scroll one page at a time and the q character to end displaying the output and
return to a prompt.
This process, called piping, is useful when you work in a command-line environment.
Understanding it might be a bit difficult if this is your first exposure, so a couple of diagrams
might be helpful. First consider Figure 3.5, which shows how the ls command functions when
piping is not used.
stderr
stdout
Now compare this to Figure 3.6 in which the stdout from the ls command is piped into the
more command.
stderr
keyboard stdin Is-1/etc screen
stdout
stderr
more screen
stderr
Notice in Figure 3.6 that only stdout is redirected when using piping. The command’s stderr
will still be displayed on the screen directly.
Linux Humor
There is no place like ~
Summary
In this chapter you learned how to manage the Linux filesystem, including how to handle files
and directories. The concept of using wildcards to match file and directory names was intro-
duced. In addition, you learned how to redirect the output and input of commands into either
files or other commands.
This page intentionally left blank
4
Essential Commands
This chapter focuses on the essential Linux commands that all developers should know. This
chapter builds on what you learned in Chapter 2 (basic command-line execution) and Chapter 3
(filesystem management commands) and provides you with a solid foundation for working in
a Linux command-line shell environment.
Command-Line Tools
At this point you might be wondering “Why command-line tools?” If your experience is
primarily with GUI-based systems, such as Microsoft Windows, you might consider the CLI
something that belongs in the dark ages of computing. However, good reasons exist for why
command-line tools have their place on modern operating systems:
■ Stability: Many Linux commands were derived from Unix and are essentially decades
old. This stability means Linux developers can focus on making more tools rather than
reinventing features that already exist.1
■ Speed of development: Developing command-line tools takes much less time than
developing GUI-based tools. As a result, the developers who create Linux tools can create
command-line tools faster than GUI-based tools.
■ Scripting: Suppose you want to execute a set of instructions each day. With a GUI-based
tool, you would have to do this manually every day. With command-line tools, you can
create a script, which is a collection of command-line tools. You will learn more about
this in Chapters 7 and 8.
1 It also means that you can wake up a Unix developer who was cryogenically frozen in the 1970s and
that developer would already understand the basics of working in Linux. Note that the process of
waking up cryogenically frozen developers is beyond the scope of this book.
48 Chapter 4 Essential Commands
■ Speed of use: Although you might not believe this initially, you can actually perform
tasks quicker on the command line (especially if you are good at typing on a keyboard).
Normally, GUI-based tools require both mouse and keyboard input (imagine doing
a “save as” of a document). This slows you down as you have to take your hands off
the keyboard to use the mouse (or vice versa). Additionally, in Linux you can quickly
re-execute previous commands as well as bring up previous commands, edit them, and
execute them. After you get used to all of this, you can accomplish system tasks more
quickly.
■ Power: You can combine commands to do things the original creator never conceived of
doing and complete tasks in a much more elegant, efficient, and useful way.
Viewing Files
A good number of the files on a Linux filesystem are text files. As a result, a lot of commands
exist to view the contents of text files. This section introduces many of these files.
If the output of the file command includes “text”, such as with the command file
/usr/share/dict/linux.words, then you can use the commands described in this section
to view its contents. However, you don’t want to use these commands to view ELF 64-bit,
gzip compressed data, or other non-text file types. In most cases, viewing these files will result
in “garbage” being displayed on your screen. In some cases it can even mess up your
terminal window.2
A useful cat option for developers is the -n option, which is used to number lines. This can
be helpful when viewing source code scripts that execute with an error message, as shown in
Listing 4.1.3
2 If you view a non-text file accidentally and it messes up your terminal display with “garbage”
characters, type the reset command and press the Enter key. Don’t worry if it looks like garbage
when you type the command, it will execute properly and fix your terminal display.
3 Are you wondering what this script actually does? Keep reading this chapter to find out!
50 Chapter 4 Essential Commands
To pause the display while displaying the contents of large files, use the more or the less
commands:
[student@localhost ~]$ more /usr/share/dict/linux.words
[student@localhost ~]$ less /usr/share/dict/linux.words
The more and less commands are also useful for pausing the display of a command that
produces a large amount of output. Use the pipe character that was covered in Chapter 3 to
send the output of a command to the more command:
[student@localhost ~]$ ls -l /etc | more
While viewing a file with the more or less command, you can use commands to control the
display. For example, press the spacebar to scroll down one screen of data. Use the Enter key to
move down one line at a time.
See the following for useful commands to control the display while using the more or less
commands:
■ Spacebar Scroll down one screen
■ Enter Scroll down one line
■ h Displays help screen (summary of commands)
4 This is about as funny as Linux jokes get. I apologize for all future Linux jokes made throughout
this book.
Command-Line Tools 51
■ q Exit
■ /{pattern} Search for {pattern}
■ n Find next occurrence of previous {pattern}
■ :f Displays filename and current line number
By default, these commands display ten lines. For example, Listing 4.2 demonstrates displaying
the top ten lines of the /usr/share/dict/linux.words file.
Use the -n option to specify how many lines to display. For example, the command
tail -n 5 /etc/passwd displays the last five lines of the /etc/passwd file.
The wc command
To display statistical information about a file, including the number of lines, words, and
characters in the file, use the wc command:
[student@localhost ~]$ wc display.sh
13 59 291 display.sh
The output displayed is the number of lines (13), the number of words (59), and number of
bytes (291) that are in the display.sh file. Because display.sh is a text file, the number of
bytes is actually the number of characters (1 character = 1 byte).
52 Chapter 4 Essential Commands
You can limit or modify the output of the wc command by using the following options:
Finding Files
There is bound to be a time when you have misplaced a file or just cannot remember where
a file is stored. In these cases, you can turn to the locate or find commands to search the
system for the missing file.
The locate command searches for any file that contains the pattern “linux.words,” which
might result in more output than expected:
[student@localhost ~]$ locate words | head
/etc/libreport/forbidden_words.conf
/etc/libreport/ignored_words.conf
/usr/include/bits/wordsize.h
/usr/lib64/perl5/CORE/keywords.h
/usr/lib64/perl5/bits/wordsize.ph
The find command searches the live filesystem, which takes more time than using the locate
command (searching databases is much faster), but it does find files that are currently on the
filesystem. The syntax for the find command is as follows:
find [starting location] [option/arguments]
For example, to search for the linux.words file, execute the following command:
[student@localhost ~]$ find /usr -name linux.words
find: '/usr/lib/firewalld': Permission denied
find: '/usr/lib64/Pegasus': Permission denied
Command-Line Tools 53
/usr/share/dict/linux.words
find: '/usr/share/Pegasus/scripts': Permission denied
find: '/usr/share/polkit-1/rules.d': Permission denied
find: '/usr/libexec/initscripts/legacy-actions/auditd': Permission denied
Note the error messages that appear are because directories existed that the current user was not
allowed to search. This is one of the reasons why you want to start your search in a subdirec-
tory, not in the / directory. Another reason is because a search of the entire filesystem, starting
from the root directory, might take a lot of time.
You can prevent these error messages by using the redirection method discussed in Chapter 3:
[student@localhost ~]$ find /usr -name linux.words 2> /dev/null
/usr/share/dict/linux.words
Another advantage of the find command over the locate command is that the find
command can search using a variety of different file attributes. For example, you can search for
files that are owned by specific users:
find /home -user student
Commonly used find options for specifying what to search for include the following:
■ -mmin n—Display files that were modified n minutes ago. Use -mmin +n to specify
“more than n minutes ago” or -mmin -n to specify “less than n minutes ago.”
■ -mtime n—Display files that were modified n days ago (technically n*24 hours ago).
Can use +n and -n like the -mmin option.
■ -group groupname—Display files owned by groupname.
■ -size n—Display files of a given size represented by n. Follow the n value with a
character to represent a unit of space. For example, -size +10M would display files that
were 10 megabytes or larger.
You can change what the find command does when it finds a file. For example, the -ls option
can provide detailed information about each file found:
[student@localhost ~]$ find /usr -name linux.words -ls 2> /dev/null
22096370 4840 -rw-r--r-- 1 root root 4953680 Jun 9 2014
➥/usr/share/dict/linux.words
Commonly used find options for specifying what to do with the files that are found:
Note
I know that the syntax here is very strange. In a nutshell, the find command generates a
series of commands like this: more file1; more file2; more file3. The {} represents
where to place the filename that was found and \; tells the find command “put a semicolon
between each command to treat them as separate commands.”
Comparing Files
As a developer, you are going to have different versions of files as you improve and bug-fix
existing programs. This can cause confusion because determining whether two files are the
same or somehow different is sometimes hard. In these cases, you should use the cmp and
diff commands.
The cmp command is also useful for comparing two non-text files. For example, you could
compare two files that contain compiled code.
The output of the diff command is essentially saying, “If you make these changes, then the
files will look the same.” Each section starts with a code that includes the line of the first file,
what action to take and the line of the second file. For example, 5c5 means “Change line 5 of
the first file to look like line 5 of the second file.”
Command-Line Tools 55
Additional lines after the “code” line indicate what the changes would look like:
< if [-d /etc]
---
> if [ -d /etc ]
The line that begins with < shows the current fifth line of the first file. The --- is just used
to separate the lines, and the line that begins with the > shows the current fifth line of the
second file.
Shell Features
The bash shell includes a large number of features designed to make it an easier and more
powerful command-line environment. Some of these features, such as wildcards and
redirection, have already been covered in Chapter 3.
In this section you learn about more bash shell features, including shell variables, aliases, and
history. Knowing how to use these features will make it much easier to work in the bash shell
and make you a more powerful software developer.
Shell Variables
Just like programming languages use variables to store values, the bash shell also stores critical
shell information in variables. To create a variable, use the following syntax: VAR=value. To
display a variable, use the echo command and place a $ character in front of the variable name:
[student@localhost ~]$ EDITOR=vi
[student@localhost ~]$ echo $EDITOR
vi
To display all variables, use the set command. There are many predefined variables, so you
might want to pipe the output to the more or head command to limit the output. See Listing 4.3
for an example.
DOCS=/usr/share/docs
■ To store useful information for the shell or a command. For example, the EDITOR
variable is used to tell commands like visudo and crontab which editor to use by
default. For this to work, you must convert the variable to an environment variable
(see the “Environment Variables” sidebar).
■ To store script data. When creating bash shell scripts, you will need to store
information. Variables are very useful for that purpose (see Chapter 8, “BASH Shell
Scripting,” for more details on BASH shell scripting).
Environment Variables
By default, variables are only available to the shell they are created in. However, you can tell
the shell to pass variables to other commands by making them environment variables.
For example, if you want to pass the EDITOR variable to any command that is executed in
the shell, execute the following commands:5
EDITOR=vi
export EDITOR
Aliases
If you find yourself using the find command daily to search the system for new shell scripts:
find / -name "*.sh" -ls
At some point you ask yourself, “Why do I need to type this long command every day?” The
fact is, you don’t need to. You can make an alias for this command, which can be much shorter
and easier to type. For example:
alias myfind='find / -name "*.sh" -ls'
Now when you execute the myfind alias, it will run that long find command. However, you must
create this alias every time you log in and every time you open a new shell. To have this happen
automatically, place this alias command in a file named .bashrc in your home directory. You
can also use this file to create variables that you want enabled every time you log in to the system.
History
Commands that you execute in a shell are saved in memory so you can execute them again.
To see these commands, execute the history command (the output could be hundreds of
commands, so limit the output with the tail command):
[student@localhost ~]$ history | tail -n 5
258 alias hidden='ls -ld .*'
Each command is assigned a number. You can re-execute a command by using this number
with an ! character preceding it:6
[student@localhost ~]$ !261
date
Sun May 1 01:06:21 PDT 2016
You can also bring up the previous command by pressing the up arrow key. This allows you to
modify a command before re-executing it.
Permissions
Understanding file and directory permissions is critical for Linux developers because Linux
is a multi-user environment and permissions are designed to protect your work from others.
To understand permissions, you first need to know the types of permissions that are available
in Linux and how these permissions differ when they are applied to files versus when they are
applied to directories.
You also need to know how to set permissions. Linux provides two methods: the symbolic
method and the octal (or numeric) method.
Viewing Permissions
To view the permissions of a file or directory, use the ls -l command:
[student@localhost ~]$ ls -l /etc/chrony.keys
-rw-r-----. 1 root chrony 62 May 9 2015 /etc/chrony.keys
The first ten characters of the output denote the file type (recall that - is for plain files and d is
for directories) and the permissions for the file. Permissions are broken into three sets: the user
owner of the file (root in the previous example), the group owner (chrony), and all other users
(referred to as “others”).
Each set has three possible permissions: read (symbolized by r), write (w), and execute (x).
If the permission is set, the character that symbolizes the permission displays. Otherwise,
a - character displays to indicate that permission isn’t set. So, r-x means “read and execute are
set, but write is not set.”
6 The ! character is often called the bang character in Linux. Other common character nicknames
include splat for * and hash for #.
58 Chapter 4 Essential Commands
The write permission on directories is potentially the most dangerous. If a user has write and
execute permission on one of your directories, then that user can delete every file in that
directory.
Changing Permissions
The chmod7 command is used to change permissions on files. It can be used in two ways:
symbolic method and octal method. With the octal method, the permissions are assigned
numeric values:
■ Read = 4
■ Write = 2
■ Execute = 1
With these numeric values, one number can be used to describe an entire permission set:
■ 7 = rwx
■ 6 = rw-
■ 5 = r-x
■ 4 = r--
■ 3 = -wx
■ 2 = -w-
■ 1 = --x
■ 0 = ---
7 Permissions used to be called modes of access, hence the origin of the name chmod (change mode
of access).
Developer Tools 59
So, to change the permissions of a file to rwxr-xr--, you execute the following command:
chmod 754 filename
With octal permissions, you should always provide three numbers, which will change all the
permissions. But what if you only want to change a single permission of the set? For that, use
the symbolic method by passing three values to the chmod command as shown in Table 4.1.
g = group owner − w
o = other = x
a = all sets
The following demonstrates adding execute permission to all three sets (user owner, group
owner, and others):
[student@localhost ~]$ ls -l display.sh
-rw-rw-r--. 1 student student 291 Apr 30 20:09 display.sh
[student@localhost ~]$ chmod a+x display.sh
[student@localhost ~]$ ls -l display.sh
-rwxrwxr-x. 1 student student 291 Apr 30 20:09 display.sh
Developer Tools
Knowing how to view files, modify file permissions, and use shell features are important for all
Linux users. Developers also should know how to compress files and how to use the powerful
filtering tool, the grep command.
Many commands in Linux enable you to create compressed files, including the gzip, bzip2,
and tar commands.
60 Chapter 4 Essential Commands
If you want both the compressed and original file, you have to use the -c option to send the
output to standard output and keep the original file. Of course, you don’t really want the
output to be sent to the screen, so redirect the compressed output to a file:
[student@localhost ~]$ ls -l linux.words
-rw-r--r--. 1 student student 4953680 May 1 09:19 linux.words
[student@localhost ~]$ gzip -c linux.words > linux.words.gz
[student@localhost ~]$ ls -l linux.words linux.words.gz
-rw-r--r--. 1 student student 4953680 May 1 09:19 linux.words
-rw-rw-r--. 1 student student 1476083 May 1 09:23 linux.words.gz
Note
Typically file extensions, such as .txt and .cvs, are unnecessary in Linux. However, they are
important for files that you create with the gzip command. This utility expects the extension of
.gz when it uncompresses a file. If you name the file linux.words.zipped, for example, the gzip
command will attempt to use the file named linux.words.zipped.gz when uncompressing the file
(and this will fail).
Fortunately, the developers of bzip2 decided to use the same options that the gzip utility uses:
[student@localhost ~]$ ls -l linux.words
-rw-rw-r--. 1 student student 4953680 May 1 09:23 linux.words
[student@localhost ~]$ bzip2 linux.words
[student@localhost ~]$ ls -l linux.words.bz2
-rw-rw-r--. 1 student student 1711811 May 1 09:23 linux.words.bz2
[student@localhost ~]$ bzip2 -d linux.words.bz2
[student@localhost ~]$ ls -l linux.words
-rw-rw-r--. 1 student student 4953680 May 1 09:23 linux.words
To create a tar file (also called a tar ball), use the following syntax:
[student@localhost ~]$ tar -cvf zip.tar /usr/share/doc/zip-3.0
tar: Removing leading '/' from member names
/usr/share/doc/zip-3.0/
/usr/share/doc/zip-3.0/CHANGES
/usr/share/doc/zip-3.0/LICENSE
/usr/share/doc/zip-3.0/README
/usr/share/doc/zip-3.0/README.CR
/usr/share/doc/zip-3.0/TODO
/usr/share/doc/zip-3.0/WHATSNEW
/usr/share/doc/zip-3.0/WHERE
/usr/share/doc/zip-3.0/algorith.txt
You use the -c option to create the tar file. The -v option stands for verbose and results in a list
of the files that are being merged into the tar file. You use the -f option to specify the name of
the resulting tar file.10
9 The command comes from the phrase Tape ARchive. Or it could be TApe aRchive. You pick.
10 Note that for the tar command, the - character before the options is optional. So, tar cvf is the
came as tar -cvf. A handful of Linux commands don’t require the - character before options.
62 Chapter 4 Essential Commands
Note
What happens when you try to create a tar file and forget to provide a name for it? You get the
following message:11
tar: Cowardly refusing to create an empty archive
To list the contents of an existing tar file, use the -t option (t for table of contents:
[student@localhost ~]$ tar -tf zip.tar
usr/share/doc/zip-3.0/
usr/share/doc/zip-3.0/CHANGES
usr/share/doc/zip-3.0/LICENSE
usr/share/doc/zip-3.0/README
usr/share/doc/zip-3.0/README.CR
usr/share/doc/zip-3.0/TODO
usr/share/doc/zip-3.0/WHATSNEW
usr/share/doc/zip-3.0/WHERE
usr/share/doc/zip-3.0/algorith.txt
To extract the files from the tar ball, use the -x option:
[student@localhost ~]$ tar -xf zip.tar
In the current directory there should now be a usr directory with a directory structure of usr/
share/doc/zip-3.0. All the extracted files are in the zip-3.0 directory.
By default, the tar command does not compress. However, you can have the tar command
use either gzip or bzip2 to compress by using the -z (gzip) or -j (bzip2) options.
Because the pattern could be a regular expression (regular expressions are covered in the next
section), ed documentation typically displayed this command as
:g/re/p
The individual who created the grep command (Ken Thompson) also created the ed feature, so
he naturally named the command after the feature.12
For example, to view all the comment lines in a shell script, execute the following command:
[student@localhost ~]$ grep "#" /etc/rc.local
#!/bin/bash
# THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES
#
# It is highly advisable to create own systemd services or udev rules
# to run scripts during boot instead of using this file.
#
# In contrast to previous versions due to parallel execution during boot
# this script will NOT be run after all other services.
#
# Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure
# that this script will be executed during boot.
By default, the grep command matches the pattern regardless of whether it is part of another
word. You can see the result of this by looking at line 2 of Listing 4.4 where the the is matched
within the word then.
If you only want to match a pattern as a separate word, use the -w option:
[student@localhost ~]$ grep -w the /etc/bashrc | cat -n
1 # will prevent the need for merging in future updates.
2 # Need to redefine pathmunge, it gets undefined at the end
➥of /etc/profile
Regular Expressions
Chapter 3 discussed wildcards, special characters that the bash shell uses to match filenames
in a directory. Wildcards are fairly simple to use, because filenames are typically small and not
64 Chapter 4 Essential Commands
very complex. However, text within a file can be much more rich and complex. To perform
flexible matching with the grep command, use regular expressions (think “wildcards
on steroids”).
Regular expressions are a huge topic (seriously, enough to fill up a book larger than the size of
this one). As a developer, you don’t need to know everything about regular expressions, so to
get you started, I just cover the basics.
As you can see from the following example, the grep command returns results regardless of
where on the line the pattern is found:
[student@localhost ~]$ grep "growths" /usr/share/dict/linux.words
growths
ingrowths
outgrowths
regrowths
undergrowths
upgrowths
If you only want to see the lines that begin with the pattern, use the regular expression
character ^ at the beginning of the pattern:
[student@localhost ~]$ grep "^growths" /usr/share/dict/linux.words
growths
If you only want to see the lines that end with the pattern, use the regular expression character
$ at the end of the pattern.
These lines took the output of the ls -l command and sent it to the grep command to
display file times. Lines from the ls -l command that begin with the letter d are directories.
By sending this output to the wc command, you get a count of how many directories are in the
/etc directory.
In Chapter 8, “BASH Shell Scripting,” you will learn about the rest of what this bash shell
script is doing.
Another useful regular expression character is the . character, which represents exactly one
character. In the following example, "r..t" matches “root” on lines 1 and 2. For line 3 "r..t"
matches “r/ft”:
[student@localhost ~]$ grep "r..t" /etc/passwd | cat -n
1 root:x:0:0:root:/root:/bin/bash
2 operator:x:11:0:operator:/root:/sbin/nologin
3 ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
Developer Tools 65
Additional useful grep regular expressions (some of which require using the -E option for
extended regular expressions) include
■ * Matches zero or more of the previous character.
■ + Matches one or more of the previous character (requires using the -E option).
■ . Matches any single character.
■ [ ] Matches a single character from a subset of characters; [abc] matches either
an a, b, or c.
■ ? Matches an optional character; a? means “match either the character ‘a’ or nothing”
(requires using the -E option).
■ | Match one or another; abc|xyz matches either abc or xyz (requires using the -e
option).
■ \ Escapes the special meaning of a regular expression character; \* matches simply
a * character.
Note
Regular expressions are extremely useful, not just for the grep command, but many other Linux
tools as well as many programming languages. This is a very good topic to expand your knowl-
edge on to become a more powerful developer.
When you use the grep command in this manner, you probably want to use the -l option,
which will list matching filenames (rather than listing every line in every file that matches).
You probably also want to redirect STDERR to suppress error messages for files and directories
that you don’t have permission to. See Listing 4.5 for an example that searches for all bash
shell scripts in the /etc directory structure.
/etc/NetworkManager/dispatcher.d/11-dhclient
/etc/NetworkManager/dispatcher.d/13-named
/etc/pki/tls/certs/renew-dummy-cert
/etc/ppp/ip-down
/etc/ppp/ip-up
/etc/ppp/ipv6-up
/etc/qemu-ga/fsfreeze-hook
/etc/rc.d/init.d/netconsole
/etc/rc.d/rc.local
/etc/rc.local
/etc/sysconfig/network-scripts/ifdown-eth
/etc/sysconfig/network-scripts/ifdown-tunnel
/etc/sysconfig/network-scripts/ifup-aliases
/etc/sysconfig/network-scripts/ifup-eth
/etc/sysconfig/network-scripts/ifup-sit
/etc/sysconfig/network-scripts/ifup-tunnel
/etc/sysconfig/network-scripts/ifup-wireless
/etc/sysconfig/network-scripts/ifdown-ib
/etc/sysconfig/network-scripts/ifup-ib
/etc/sysconfig/raid-check
/etc/vsftpd/vsftpd_conf_migrate.sh
/etc/X11/xinit/xinitrc.d/50-xinput.sh
/etc/X11/xinit/xinitrc.d/zz-liveinst.sh
/etc/X11/xinit/Xclients
/etc/X11/xinit/Xsession
Linux Humor
Who needs to go to the movies? Big screen Hollywood action is available right on your Linux
computer. Type the following command, grab some popcorn, and enjoy:
telnet towel.blinkenlights.nl
P.S. To stop the “movie,” hold down the Ctrl button and press the ] key. Then type quit at the
telnet> prompt and press the Enter key.
Summary
At this point you should have a solid foundation that will enable you to work in the Linux
command-line environment. You learned the essentials, such as how to view a file and make
use of bash shell features. You should now know how to secure your files using permissions.
In the next chapter you will build on these tools to learn some important system administrative
tasks of which developers should be aware.
5
Text Editors
As a developer, you will edit text files on a regular basis. This can sometimes pose a challenge
because Linux offers a variety of editors. In many cases, you should be able to pick your editor,
but sometimes you might be forced to use one of the standard editors, such as the vi editor.
This chapter focuses on the editors that are available on Linux distributions. The primary focus
is on the vi (or vim) editor because it has the advantage of always being available on whatever
Linux distribution you are working on. I introduce some additional editors to help you
determine which tool will work best for your situation.
The vi Editor
Consider the early days of Unix, the precursor to Linux: A developer would sit down at a
keyboard, ready to edit a program that he is working on. He stares at the printer (yes, printer,
not monitor) considering what commands to execute. Monitors were very rare in the early
1970s and even if a developer had one, it was primarily designed to display the output of
executed code, not to interactively edit files.
Instead, the developer would use a simple command-based editor, such as the ed editor.
With this editor a developer could perform operations such as list the contents of a file
(print the file), modify specific characters of a file, or save the contents of a file. However,
he accomplished all this in a way that might seem foreign today. The developer wouldn’t
see what he was editing, but rather just assume the commands were successful (or print the
file to verify).1
1 On some modern Linux distributions, the ed editor still exists. Try typing the command ed in a
terminal window. If the editor does exist on your system, you will be placed in the ed editor environ-
ment (essentially a blank prompt). In reality, the only ed command you want to know is q because
this quits the ed editor.
68 Chapter 5 Text Editors
When monitors became more commonplace, the ed editor seemed like a clumsy way to edit a
text file. In the mid-1970s a replacement editor named vi (short for visual) was introduced to
Unix.2 It was a great improvement over the ed editor3 because you could actually see and move
around in your document.
What Is vim?
The vim editor5 was released in 1991 as a clone of the vi editor. The vim editor has the same
base functionality as the vi editor, but it has several additional features. Some of these features
can be useful for software developers.
Your distribution might only have the vi editor. Many distributions have both the vi and vim
editor. On some distributions, the command vi is actually a link to the vim editor.
An easy way to tell whether you are using the vi or vim editor is to try executing the vi
command. If you are using vim, a message like the following appears: VIM – Vi IMproved.
If you don’t get this message, then you are using a standard vi editor.6
Note:
Unless stated otherwise, the commands shown in this chapter work in both the vi and vim edi-
tors. Any command that only works in vim is denoted as such.
Essential vi Commands
To become an expert vi user can take a lot of practice, but to be able to effectively edit files
requires the knowledge of a subset of the large amount of vi commands.
It helps to have a large file to edit. All Linux distributions should come with a /etc/services
file that is typically thousands of lines long. You can start by first copying this file to your
home directory and then edit the copy with the vi command:
[student@fedora ~]$ cp /etc/services.
[student@fedora ~]$ vi services
While in the command mode, you can’t insert new text into your document because all the
keyboard keys are assigned to command tasks. To insert new text, you must use the s command
to move from command mode to insert mode. These commands include the following:
■ i—New text will appear before the cursor position.
■ a—New text will appear after the cursor position.
■ I—New text will appear at the beginning of the line.
■ A—New text will appear at the end of the line.
■ o—Opens a new line below the line that contains the cursor; new text will be placed on
this line.
■ O—Opens a new line above the line that contains the cursor; new text will be placed on
this line.
See Figure 5.1 for a visual description of how these vi commands work.
= cursor position
O
O
# Note that it is presently the policy of IANA to assign a single well-known
I # port number for both TCP and UDP; hence, most entries here have two entries
# even if the protocol doesn’t support UDP operations.
i a o
Note that when you are using the vim editor and enter the insert mode, the bottom part of the
screen changes to indicate this. See the -- INSERT -- at the bottom of Figure 5.2.
If you are working in a standard vi editor, then -- INSERT -- does not appear at the bottom
of the screen by default. To enable this feature in a standard vi editor, type the following
command while in command mode:
:set showmode
When you want to return to command mode, just press the escape (Esc) key. This is normally
denoted in documentation as <ESC>. If you return to the command mode, then the -- INSERT --
should disappear from the bottom of the screen.
The vi Editor 71
Movement Commands
While in the command mode, you can move the cursor in your document by using a variety
of keys. One of the common methods is to move the cursor one character to the left or right or
one line up or down. You do this by using either the arrow keys on your keyboard or using the
h, j, k, and l keys7 as shown in Figure 5.3.
Cursor
j Position k
7 Why use the h, j, k, and l keys when you can use the arrow keys? When the vi editor was developed,
most keyboards didn’t have arrow keys. Even today, rack-mounted servers are sometimes connected
to dump terminals that have keyboards that lack arrow keys.
72 Chapter 5 Text Editors
Note that these are just some of the movement commands. Here’s a suggestion: spend some
time trying out these movement commands and then create a cheat sheet of the commands
that you feel will be most useful to you. Make this a cheat sheet that you can add more
commands to as you learn additional useful commands.8
Repeater Modifiers
In the previous section, you discovered that you can jump to a specific line in a document
by typing a number followed by a G while you are in the command-mode. For example, the
command 7G will take you to line number 7 in the document.
Placing a number before a command acts as a modifier. You can use modifiers on many
different command-mode commands; for example:
You can also use repeat modifiers on commands like deleting, copying, and pasting. Typically,
if there is a command-mode command that you would logically want to execute multiple
times, then repeat modifiers should work with that command.
8 Or visit the “Vi lovers” page (http://thomer.com/vi/vi.html) and download one of the reference
cards under the “Vi pages/manuals/tutorials” section. Personally, I prefer to make my own because
the commands that someone else finds useful, I might not find very helpful.
9 Be careful here. I once accidently typed the 8 key twice before pressing the i key to enter insert
mode. After typing pages of text, I pressed the Esc key and received 88 times the text that I typed.
Read on to learn how I fixed this problem quickly.
The vi Editor 73
Undoing
You can undo whatever change has been made to the document by typing the u character in
command mode. In the standard vi editor, you can only undo a single action;10 in fact, the u
command acts as an undo/redo key.
If you are using the vim editor, you can undo several actions. Just keep pressing the u character
to undo older modifications. You can perform a redo that undoes the changes performed by the
undo command by using the ^r (Ctrl+r) command.
Suppose you made a large number of changes since you opened the document and you want
to discard them all. In this case, you probably want to close the document without saving and
open it again. To close the document without saving changes, type the command :q!. You can
find more on this command and other ways to quit the vi editor in the “Saving and Quitting”
section later in this chapter.
You might be wondering “Why use the y character?” This is because the process of copying text
into the memory buffer used to be called yanking.
10 Actually, if you don’t move to another line, you can undo all changes on the current line by typing the
u character while in command mode. However, I think you will find that you’ll rarely use this feature
because the moment you move to a new line, these undos are lost.
74 Chapter 5 Text Editors
The following is a summary of commonly used deleting commands. Keep in mind, you should
execute these while in command mode:11
■ dw—Delete word; this command actually deletes from the current character in the word
until the end of the word (including punctuation) and the white space after the word.
So, if your cursor was on the h in “this is fun” the dw command would delete “his ”,
resulting in “tis fun.”
■ dd—Delete current line.
■ d$—Delete from current character to end of the line.
■ dG—Delete current line to the end of the document.12
■ x—Delete the character the cursor is currently on (like a delete key).
■ X—Delete the character before the character the cursor is currently on (like a
backspace key).13
Pasting commands can be a bit trickier because how they work depends on what you are
pasting. For example, suppose you had copied a word into the buffer. In this case, the following
describes how the paste commands would work:
■ p—Pastes the buffer contents before the cursor
■ P—Pastes the buffer contents after the cursor
The behavior is a bit different if you copy an entire line (or multiple lines) into the buffer:
■ p—Pastes the buffer contents in the line above the cursor
■ P—Pastes the buffer contents in the line below the cursor
11 Notice how similar these deleting commands are to the copying commands. Not only did this allow
me to avoid a lot of extra typing in this book (call me lazy, or just an effective developer who
“reuses” good “code”), but it highlights that most of the copying commands are just like deleting
commands, which should make the process of learning them easier.
12 In a previous footnote, I mentioned that I once accidently inserted several pages of text 88 times.
To fix this, I went to the first line in the second “set” and typed the dG command. This deleted all
but the first copy of what I had typed with minimal effort.
13 If you are using the vim editor, you can use the delete key to delete the character you are currently
on. However, the backspace key works like a back arrow key.
The vi Editor 75
Finding Text
Finding text is a critical function for a software developer who is using the vi editor because
error messages that appear when code is executed often include bits of code where the error
occurs. You can search for text by using one of the following methods:
■ / While in command mode, type the / key; this character appears in the bottom-left
corner of the terminal window. Now type what you want to search for and then press the
Enter key. The vi editor will search forward in the document for the text you asked it to
search for.
■ ? While in command mode, type the ? key; this character appears in the bottom-left
corner of the terminal window. Now type what you want to search for and then press the
Enter key. The vi editor will search backward in the document for the text you asked it to
search for.
Suppose your search didn’t find the specific match you were looking for. You can use the n
command to find the next match. The n command searches forward when your last search
started with the / key and searches backward when your last search started with the ? key.14
What if you searched for “/one” and realize you will need to press the n key many times to find
what you are looking for? After furiously typing n repeatedly, you realize you went past the
match that you wanted. To reverse the current search, use the N character (capital N rather than
lowercase). When you’re searching forward, N will reverse and search backward in the document.
When you’re searching backward, N will reverse and search forward in the document.
Case Sensitive
As with just about everything you use in Linux, the search function is case sensitive. In other
words, a search of /the will not match the following line:
The end is near
The values of x and y represent which lines you want to perform the search on. For example, to
search and replace on only the first ten lines of the document, use the following syntax:
:1,10s/I/we/
14 Remember the regular expressions that were covered in the section on the grep command in
Chapter 4? If not, go back and read that section again! Regular expressions show up in many tools
in Linux, including the vi editor. For example, if you search for ^The, the vi editor will only match lines
that begin with The, rather than The anywhere on the line.
76 Chapter 5 Text Editors
You can use the $ character to represent the last line in the document:
:300,$s/I/we/
So, to perform the substitution on the entire document, use the following:
:1,$s/I/we/
By default, only the first match on each line is replaced. Imagine if the line you are searching
for and replacing looked like the following:
The dog ate the dog food from the dog bowl
If the command :s/dog/cat/ were executed on the previous line, then the result would be:
The cat ate the dog food from the dog bowl
To replace all occurrences on a line, add a g15 at the end of the search command:
:s/dog/cat/g
Searching and replacing is case sensitive. Imagine if the line you are searching and replacing
looked like the following:
The Dog ate the dog food from the dog bowl
If the command :s/dog/cat/ were executed on the previous line, then the result would be:
The Dog ate the cat food from the dog bowl
The result matched the second dog because the first one had a capital D character. To perform a
case-insensitive search and replace, add an i at the end of the search command:
:s/dog/cat/i
Another operation you can do in this mode is save and quit your document:
:wq
Note
You must save before quitting, so you can’t execute the command :qw because that will
attempt to quit and then save.
15 You can think of g standing for get them all. It actually stands for global.
The vi Editor 77
You can also save to a different document, but there is a little gotcha to this operation that you
will discover. Suppose you want to save changes made to your services file into a file called
myservices. Execute the following:
:s myservices
The changes will be placed into this file. However, any further changes will be saved by default
into the original services file. Most modern editors “switch” the default save document to
whatever the last saved document was, but vi doesn’t do this. To see your current document,
type ^G (Ctrl+g).
So, if you want to edit the new file, you should quit the vi editor and open the new file.
If you make changes to a file and then try to quit without saving (:q), you receive an error
message like the following:
E37: No write since last change (add ! to override)
To force quit (quit without saving changes), execute the following command:
:q!
The vim editor has some very useful built-in documentation, but you must have a specific
software package installed on Red Hat–based distributions16 in order to be able to access this
documentation. Chapter 6 covers installing software in greater detail. For now, just make
sure you are logged in as the root user and execute the following command: yum install
vim-enhanced
If this package is installed, you can execute the command :help while in the vim editor to see
a help document. See Figure 5.4 for an example.
Use your arrow keys (or h, j, k, and l) to scroll through the document. About 20 lines down,
you will start to see some subtopics, as shown in Figure 5.5.
Each of these topics, such as quickref and usr_01.txt, are separate help topics. To view them,
first exit from the current help document by typing the :q command. Then type a command
like the following, replacing topic with the full name of the topic you want to view:
:help topic
For example, to see help on “Using syntax highlighting,” type the following command:
:help usr_06.txt
vimtutor
A great tool to help you learn the vi editor is the vimtutor command. This command takes you
into vi and provides a useful guide to learning the vim editor.
Additional Editors
A large number of editors are available that you can use in Linux. The focus of this section is to
make you aware of these editors, not to teach you how to use them.
Note
It is likely that not all of these editors will be installed on your distribution. You might need to
install additional software packages to have access to them.
Emacs
Like the vi editor, the Emacs editor was developed in the mid-1970s.17 Linux users who like
Emacs will praise how easy it is to use and how customizable it is. If you launch Emacs (just
run the emacs command) while in a GUI-based terminal, it should open a GUI-based version
of the program as shown in Figure 5.6. As you can see, the GUI-based version has menus in
addition to the commands that you can execute via the keyboard.
17 Emacs versus vi/vim has been referred to as a “religious war” between the users of these editors.
It is a war that I’ve always avoided; be aware that there are some in the Linux community who
take this war very seriously.
80 Chapter 5 Text Editors
If you execute the Emacs editor in a command line–only environment, the editor will look like
Figure 5.7.
GUI vim?
If you install the vim-X11 software package, you get access to a GUI-based version of the vim
editor. Just execute gvim or vim -g on Red Hat–based distributions or vim-gtk on Debian-based
distributions.
The gedit editor typically is installed on distributions that use the GNOME desktop by default.
The kwrite (or KATE) editor typically is installed on distributions that use the KDE desktop
by default. However, you can easily install gedit on a system that uses KDE desktop or install
kwrite on a GNOME desktop system.
The nano and joe editors provide a simple interface for editing text files. They are command
line–only editors, so no GUI is required. See Figure 5.8 for an example of the nano editor.
If you are going to make a career of coding on Linux, you should start to explore these tools
(or many of the other similar editing tools). See Figure 5.9 for an example of the bluefish editor.
Linux Humor
Try this one in your shell:
bo@mintos:~ > cd /
bo@mintos:/ > touch me
touch: cannot touch 'me': Permission denied
Summary
The focus of this chapter was editors, primarily the vi or vim editor. We covered the basics of
editing files in vi/vim, including how to start the editor, the three modes of operation, how
to add and delete text, and some more advanced features. You were also introduced to some
additional editors that are available in Linux. At this point, using these editors comes down to
practice, which you should get plenty of when you start writing code on Linux.
6
System Administration
System administration is a huge topic that incorporates tasks such as configuring services,
maintaining the health of the operating system, and keeping the system secure. Whole
volumes have been devoted to teaching individuals how to administer a Linux distribution.
As a developer, you should consider leaving the heavy lifting aspects of system administration
to full-time system administrators.
However, that doesn’t mean that you should never take on some of the responsibilities of
system administration. Some tasks you will want to be able to accomplish without having to
bother a system administrator. These tasks include installing software and maintaining user
accounts. This chapter focuses on the essential system administration tasks that all software
developers should have in their skill set.
Essential Tasks
In almost all cases, you should log in to the system using a regular user account and avoid
logging in as the root user (the system administrator account). Routinely executing commands
as the root user is just asking for trouble.
The root user has full control over the system, including the capability to delete all files and
directories. The problem with working as the root user on a regular basis is that you can
potentially damage your operating system, making it unusable. For example, consider the
following command (but don’t run this command!):
[root@fedora ~]$ rm -rf /
If you ran the preceding command while you were logged in as the root user, every file and
directory on the system would be removed. As a regular user, this could result in loss of files in
your home directory, but even that could be avoided by pressing Ctrl+C after you noticed all
the error messages that would appear as you try to delete files that you don’t have permission
to delete.
So to summarize, the best practice is this: Log in as a regular user and only assume the identity
of the root user if you need to perform a specific task as the root user.
84 Chapter 6 System Administration
■ Log in directly as the root user: As previously mentioned, this is not the ideal method.
Even system administrators avoid logging in directly as the root user.
■ Use the su command: With the su command you can switch user to the root account
if you know the root password. This command opens a new shell, and in that new shell
you can commands as the root user. To return to your regular user account, you close the
shell by executing the exit command.
■ Use the sudo command: With the sudo command, you can execute commands as the
root user without having to even know the root password. However, this feature does
need to be set up by the system administrator to work properly.
Note that the id command displays your current user account. In this case the id command
wasn’t necessary because you can see the current user name in the prompt.
You will often see the argument root omitted when using the su command. If you don’t
specify a user account name, the root user is assumed by default:
[student@localhost ~]$ su -
Password:
[root@localhost ~]# id
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_
t:s0-s0:c0.c1023
The - option is not only strange because it lacks a character after the -, but it is also very
important.1 Without the - character, you will not fully switch to the root user account because
the login scripts for the root user do not execute. The best way to demonstrate the difference
between using the - and not using it is by looking at the code in Listing 6.1.
Note that in Listing 6.1 when the - was not used, the current directory did not change and the
value of the $PATH variable didn’t change to the value for the root user. Using the - character
fully switches you to the root account, the current directory switches to the root user’s home
directory, and the $PATH variable is set to the proper value for the root user (look at the end:
/root/bin).
In many cases, it won’t matter if you use the - character or not. However, sometimes not
fully switching to the root user account can cause problems. The best practice is to use
the - character when switching to the root account.
Important Note
Always remember that when you finish executing commands that require root privileges, switch
back to your regular user account by executing the exit command.
Note that the password that was requested was not the root password, but rather the password
of the current user (the bo user in this case). The sudo command takes another command as its
argument and will execute that other command as the root user provided the correct password
is provided and the sudo command has been set up correctly.
86 Chapter 6 System Administration
To set up the sudo command, add a line like the following in the /etc/sudoers file2:
bo ALL=(ALL:ALL) ALL
The previous line would allow the user bo to use the sudo command to execute commands
as the root user. Note that you can also apply this feature to entire groups3 as shown in the
following:
bo@mintos:~ > sudo grep %sudo /etc/sudoers
%sudo ALL=(ALL:ALL) ALL
bo@mintos:~ > id
uid=1000(bo) gid=1000(bo) groups=1000(bo),4(adm),24(cdrom),27(sudo),30(dip),
46(plugdev),108(lpadmin),111(sambashare)
So, the reason why the bo user in the previous example can execute commands as the root user
using the sudo command is because the bo user is a member of the sudo group.
If you need to give sudo access to a user or group, first switch to the root account and then
execute the visudo command. This command automatically edits the /etc/sudoers file using
the vi or vim editor. One advantage of using the visudo command rather than the regular vi
or vim editor is that the visudo command performs some basic error checking when you save
your changes.
On a Linux system, the space on the hard drive is broken into chunks called partitions or
volumes. This is also true on other operating systems, such as Microsoft Windows; however,
typically the result is a bit different. Making a partition out of an entire hard disk is common
practice on Windows OS, whereas in Linux creating several partitions (or volumes4) on one
hard disk is common.
2 Note that this is a very simple example and perfectly fine for a standalone system. However, for a
system in which security is a concern, you should learn more about the sudo command or have a
system administrator set up this feature.
3 A group in Linux is a collection of user accounts. Managing groups is covered in detail later in this
chapter.
4 The difference between a partition and a volume is not critical for developers to understand. If you
choose to become a system administrator, the difference becomes very important because they
are managed differently. Because this book is for developers, I have chosen not to describe these
differences. Consider them both to be a container where files and directories can be stored.
Essential Tasks 87
To display these partitions, including how much space is available, execute the df command
as shown in the following:5
[student@localhost ~]$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/centos-root 6.7G 4.1G 2.6G 61% /
devtmpfs 1.9G 0 1.9G 0% /dev
tmpfs 1.9G 88K 1.9G 1% /dev/shm
tmpfs 1.9G 17M 1.9G 1% /run
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
/dev/sda1 497M 196M 302M 40% /boot
tmpfs 389M 8.0K 389M 1% /run/user/0
The Mounted on column indicates to which directory structure the partition or volume is
attached. Recall that, unlike Microsoft Windows, devices are not assigned drive letters but
rather are placed under directory structures, like the /boot directory.
Based on the output of the df command, you can see how much space is available. For
example, in the previous output, the /boot directory structure could support up to 302MB
more data. The following directory structures are normally the most critical for developers
to be aware of the available space:
■ /usr—Location where new software will be installed
■ /home—Home directories for regular users, including your own account
■ /tmp—A location to store temporary files. As a developer you might need to create a file
to hold data while your program is executing. Placing this file in the home directory
of the user who is running the program is not ideal (they might delete it accidently).
The /tmp directory is the best place to store such a file.
Note
If you don’t see /usr, /home, or /tmp in the Mounted on column of the output of the df
command, then these directories are not separate partitions or volumes, but rather are part of
the / directory structure.
Determining how much space the files in a specific directory use on the hard disk is also
useful. This can be important when you want to see how much space the removal of some
large files within a directory can free up. To see how much space the files in a directory
(and all subdirectories) are using, use the du command:
[student@localhost ~]$ du -sh /usr/sbin
54M /usr/sbin
5 Use the -h option to show the output in human-readable sizes rather than one kilobyte block sizes.
88 Chapter 6 System Administration
The -s option displays a summary of the entire base directory, rather than each separate
subdirectory. The -h option shows human-readable sizes.
Managing Software
Most of what appears in this book works the same (or at least similarly) on different
distributions. Software management is different, because three different sets of tools are
available to enable you to add and remove software. Which set of tools you use depends on
the distribution on which you are working:
■ yum and rpm—These tools enable you to manage software on Red Hat Enterprise Linux,
CentOS, Fedora, and other Red Hat–based distributions.
■ apt-get and dpkg—These tools enable you to manage software on Debian, Ubuntu,
Mint, and other Debian-based distributions.
■ zypper and rpm—These tools enable you to manage software on SUSE and SUSE-based
distributions.
The rpm and dpkg commands perform very similar tasks. Historically, they were designed
to install software packages that had been downloaded to the local system. This function is
now normally handled by the yum, apt-get, and zypper commands, which are used to both
download the package and install it. These commands download the package from a server
called a repository.
The advantage of the yum, apt-get and zypper commands over the rpm and dpkg commands
is that package dependencies are automatically taken care of. So, if a package needs three other
packages to work successfully, the yum, apt-get, and zypper commands would also download
and install these packages.
You can also use all of these commands to remove software packages. Again, the yum, apt-get,
and zypper commands have an advantage over the rpm and dpkg commands because they
check dependency issues before removing the package. So, if you try to remove a package that
is required by another package, an error message appears.
So why would you ever use the rpm or dpkg commands? The yum, apt-get, and zypper
commands are really front-end programs that eventually run rpm and dpkg commands. The
rpm and dpkg commands have some more powerful options that can’t be accessed by the yum,
apt-get, or zypper commands, particularly options regarding querying information regarding
packages. This is much more critical for system administrators than it is for developers, so you
will likely run the yum, apt-get, and zypper commands much more often than rpm or dpkg.
Developers often install new software packages to enhance what features (or programming
languages) they can use on the system. Keep in mind that installing and removing software
requires root privileges.
Managing Software 89
The yum search command can produce a lot of output, so consider using the grep command
to perform a secondary filter:
[root@localhost ~]# yum search editor | grep GUI
nedit.x86_64 : A GUI text editor for systems with X
root-guibuilder.x86_64 : GUI editor library for ROOT
torrent-file-editor.x86_64 : Qt based GUI tool designed to create and edit
To search for a package on a Debian-based system, use the apt-get search term command
(replace term with your search term). To install a package on a SUSE-based system, use the
zypper search -t term command.
To list currently installed packages on Red Hat–based systems, use the yum list installed
command:
[root@localhost ~]# yum list installed | tail
yelp-libs.x86_64 1:3.14.2-1.el7 @base
yelp-xsl.noarch 3.14.0-1.el7 @base
yum.noarch 3.4.3-132.el7.centos.0.1 @base
yum-langpacks.noarch 0.4.2-4.el7 @base
yum-metadata-parser.x86_64 1.1.4-10.el7 @anaconda
yum-plugin-fastestmirror.noarch 1.1.31-34.el7 @base
yum-utils.noarch 1.1.31-34.el7 @base
zenity.x86_64 3.8.0-5.el7 @base
zip.x86_64 3.0-10.el7 @anaconda
zlib.x86_64 1.2.7-15.el7 @base
The yum list installed command also produces a lot of output. Consider piping the output
to the more or grep command. Note that the first column of the output of this command
displays the package name, the second column displays the version of the package, and the
third column displays the repository name where the package was installed from.
90 Chapter 6 System Administration
To list all installed packages on a Debian-based system, use the dpkg -l command. To list all
installed packages on a Red Hat–based system, use the rpm -qa command.
Installing Software
On Red Hat–based systems, install a package using the yum install command as shown in
Listing 6.2.
Dependencies Resolved
==========================================================================
Package Arch Version Repository Size
==========================================================================
Installing:
kernel-doc noarch 3.10.0-327.28.2.el7 updates 13 M
Transaction Summary
==========================================================================
Install 1 Package
Total download size: 13 M
Installed size: 48 M
Is this ok [y/d/N]: y
Downloading packages:
kernel-doc-3.10.0-327.28.2.el7.noarch.rpm | 13 MB 00:03
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : kernel-doc-3.10.0-327.28.2.el7.noarch 1/1
Verifying : kernel-doc-3.10.0-327.28.2.el7.noarch 1/1
Installed:
kernel-doc.noarch 0:3.10.0-327.28.2.el7
Complete!
User Accounts 91
To install a package on a Debian-based system, use the apt-get install command. To install
a package on a SUSE-based system, use the zypper install command.
Removing Packages
Although developers often want to install packages on their own systems, wanting to remove
or perform more advanced package manipulation commands is not as common. The rpm
and dpkg commands were mentioned in the event you want to learn more about package
management, but this is normally something that interests system administrators more.
In the event you do want to remove a software package, switch to the root account and run
the proper command for your distribution:6
yum remove package_name
apt-get remove package_name or apt-get purge package_name
zypper remove package_name
User Accounts
Typically, maintaining user accounts is the responsibility of the system administrator. However,
this can also be an important task for a software developer because you might want to be
able to test your software using different user accounts. For example, you might want to have
different accounts to test access for unprivileged users to a database.
This section focuses on the basics of creating, modifying, and deleting user accounts, and also
explores the topic of group accounts.
To create a user account, execute the useradd command as shown in the following:
[root@localhost ~]# useradd julia
[root@localhost ~]# tail -1 /etc/passwd
julia:x:1001:1001::/home/julia:/bin/bash
[root@localhost ~]# ls /home
julia student
Notice the new entry in the /etc/password file, one of the files that contains user account
information. To see details about the format of this file, execute the man 5 passwd command.
6 The purge argument to apt-get removes the package entirely. The remove argument removes
everything except the configuration files (left behind in case you reinstall the software at a later date).
92 Chapter 6 System Administration
The new user was provided with a home directory automatically (/home/julia). This does
not happen on all distributions; on some distros you must specify the name of the home
directory with the -d option and tell the useradd command to create this home directory
with the -m option:
[root@localhost ~]# useradd -d /home/julia -m julia
Typically the default settings for the user account are fine for accounts that you are creating
for testing purposes. A few settings that you might want to modify include the following:
■ -s Specify the login shell. For example: -s /bin/tcsh
■ -g Specify the primary group for the account. For example: -g sudo
■ -G Specify the primary group(s) for the account. For example: -G sudo,payroll
After creating the user account, assign the new account with a password by executing the
passwd command as shown in the following:
[root@localhost ~]# passwd julia
Changing password for user julia.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
Bad Passwords
You might get a warning message like the following when assigning a password to a user
account:
BAD PASSWORD: The password fails the dictionary check - it is based on a
dictionary word
If the system you are working on has access to the Internet, you should heed this warning
and use a more complex password. However, if this is an internal-only system, making a more
complex password can be more trouble than it is worth.
Ask yourself, “Will I ever connect this system to the Internet?” If the answer is “yes,” make
a more complex password.
If you look at the last field of data in the “julia” line of the /etc/passwd file, you can see that
the login shell has changed from /bin/bash to /bin/tcsh.
User Accounts 93
Understanding Groups
Chapter 4, “Essential Commands” mentioned group accounts during the discussion on permis-
sions. To understand how important group membership is, consider the output of the following
commands:
[root@localhost ~]# id sarah
uid=1002(sarah) gid=1002(sarah) groups=1002(sarah)
[root@localhost ~]# ls -l /tmp/sample.txt
-rw-r-----. 1 root wheel 158 Aug 16 21:11 /tmp/sample.txt
Based on the output of the previous id command, you can see that the user sarah is a member
of one group (the group named sarah). If you look at the output of the previous ls -l
command, you can see that the /tmp/sample.txt file is owned by the user root and the wheel
group. So, in this situation, the permissions for the user sarah are ---, the “others” section of
permissions.
What if the root user wanted the user sarah to be able to view this file? By adding the user
sarah to the wheel group, she would have the permissions r--, allowing her to view the
contents of the file:
[root@localhost ~]# usermod -aG wheel sarah
[root@localhost ~]# id sarah
uid=1002(sarah) gid=1002(sarah) groups=1002(sarah),10(wheel)
[root@localhost ~]# ls -l /tmp/sample.txt
-rw-r-----. 1 root wheel 158 Aug 16 21:11 /tmp/sample.txt
Managing Groups
To create a new group, use the groupadd command:
[root@localhost ~]# groupadd staff
To add a user to a group, use the -G option to the usermod command. Very important: Make
sure you use the -a option with the -G option. Using -G alone removes the user from all of
their secondary groups. See the following for the wrong way to do this:
[root@localhost ~]# id sarah
uid=1002(sarah) gid=1002(sarah) groups=1002(sarah),10(wheel)
[root@localhost ~]# usermod -G staff sarah
[root@localhost ~]# id sarah
uid=1002(sarah) gid=1002(sarah) groups=1002(sarah),1003(staff)
94 Chapter 6 System Administration
Notice the output of the previous id commands. You can see that the usermod command
removed the user sarah from the wheel group. The following demonstrates the right way to add
a user to a group:
[root@localhost ~]# id sarah
uid=1002(sarah) gid=1002(sarah) groups=1002(sarah),10(wheel)
[root@localhost ~]# usermod -a -G staff sarah
[root@localhost ~]# id sarah
uid=1002(sarah) gid=1002(sarah) groups=1002(sarah),10(wheel),1003(staff)
To remove a group, you might want to first use the find command to search the filesystem for
all files owned by that group:
[root@localhost ~]# find / -group staff -ls 2> /dev/null
27304379 4 -rw-r----- 1 root staff 158 Aug 16 21:11 /tmp/sample.txt
This is an important step because you should change the group ownership of these files to
another group before removing the group. After you change the group ownership, you can use
the groupdel command to delete the group:
[root@localhost ~]# chgrp wheel /tmp/sample.txt
[root@localhost ~]# ls -l /tmp/sample.txt
-rw-r-----. 1 root wheel 158 Aug 16 21:11 /tmp/sample.txt
[root@localhost ~]# groupdel staff
Linux Humor
If you are like me (or 99% of folks who work in Linux), you will eventually end up typing the
command sl instead of the ls command. Why not make the result a bit more interesting than
bash: sl: command not found...?
First, install the package named sl (choose the right command for your distribution):
yum install sl
apt-get install sl
zypper install sl
Summary
A system administrator performs many additional tasks that were not covered in this chapter.
However, the chapter did cover the administrative tasks that you, as a software developer,
might routinely perform. You should now know to switch to the root account to perform
system administration tasks. You also learned how to display disk usage, add and remove
software, and manage group and user accounts.
III
Linux Programming
Languages
Most Linux programming languages1 can be placed into two general categories: scripting
languages (sometimes called interpreted languages) and compiled languages (sometimes called
structured languages). There isn’t a strict definition that separates these categories, but the
following provides the essential differences:
■ Complied languages cannot be executed directly from source code. The source code must
be converted into compiled code first.
■ Scripts traditionally are not compiled.
■ Scripting languages are typically easier to learn.
■ Scripts typically take less coding to perform a task.
As an example of how these categories are not strictly defined, consider this: Perl is a popular
scripting language that is executed directly from source code, but before executing it is
compiled into memory and the compiled form of the code is executed.
Scripting Languages
Many scripting languages are available for Linux, making it difficult to create a complete list in
this book. However, you should find that the languages described in this section are the most
popular and widely used on Linux distributions.
1 Although I refer to these languages as “Linux programming languages,” be aware that most of these
languages could also be available on other platforms, including Microsoft Windows.
98 Chapter 7 Overview of Linux Programming Languages
Instead of executing each of these commands manually, day after day, you can place all the
commands into a file, make the file executable, and then run the file as a program:
[root@fedora ~]$ more /root/checkhome.sh
#!/bin/bash
cd /home
ls -l /home > /root/homedirs
du -s /home/* >> /root/homedirs
date >> /root/homedirs
[root@fedora ~]$ chmod a+x /root/checkhome.sh
[root@fedora ~]$ /root/checkhome.sh
Because you can use Linux commands natively in BASH shell scripts, this scripting language
can be extremely powerful. Another advantage of using this language is that you can be
confident that just about every Linux (and UNIX) distribution will have the BASH shell,
making it easy to port a script from one system to another.
In addition to being able to use Linux commands in BASH shell scripts, you should be aware
that this language has other programming features, such as:
■ Variables
■ Loop controls (if, while, and so on)
■ Exit status values
■ The ability to source code from other files
With all of its advantages, BASH shell scripting has some disadvantages, including:
■ It lacks some advanced programming features, such as object-oriented programming.
■ It is often much slower than executing other languages as each command is normally
executed as a separate process.3
2 Given that BASH stands for Bourne-Again SHell, it is actually redundant to refer to the scripting com-
ponent of BASH as “BASH shell scripting.” However, just as the term ATM machine (ATM=Automated
Teller Machine) has become standard, the term BASH shell scripting has become standard.
3 This isn’t always the case as some commands are built-in shell commands that don’t require a
separate process.
Scripting Languages 99
Even with these disadvantages, BASH shell scripting is very popular in Linux. In fact, a search
for BASH scripts (files that end in .sh) on a typical Linux distribution normally yields hundreds
of results:
[root@fedora ~]$ find / −name "*.sh" | wc −l
578
Because of this, Chapter 8, “BASH Shell Scripting,” is devoted to additional details regarding
BASH shell scripting.
Perl Scripting
In the mid-1980s, a developer named Larry Wall began work on a new scripting language that
would eventually be named Perl. At the time he was working on UNIX-based systems, which
had tools such as the C programming language, the Bourne Shell scripting language (precursor
to BASH), and sed and awk (more about these tools later). However, none of these tools worked
as he wanted them to, so he created his own language.
Of course, Larry didn’t want to lose the features that he did like about these tools, so he
combined the features that he liked into his new language. This resulted in a language that
looks a bit like C, a bit like shell scripting, and a bit like a hodgepodge collection of UNIX
utilities.
■ You can very quickly write Perl code because much of what you need for basic scripting is
already built into the core language.
■ Perl code is very flexible; you are not limited by the structure as much as some other
languages.
■ Perl’s syntax is fairly simple, derived primarily from the C language.
4 Warning: Discussions on this matter often escalate to the level of a serious “religious war.”
100 Chapter 7 Overview of Linux Programming Languages
Although Perl can be used for many different applications, it is often used for the following:
■ Data parsing—Perl has powerful regular expression features that make it ideal for data
munging (pulling chunks from data and generating reports).
■ Web development—Perl is often a component of LAMP-based5 technology because of its
web development features, including Common Gateway Interface (CGI).
■ Code testing—Because Perl is easy and quick to code, developers often use it to create
tools to test their applications.
■ GUI programs—Additional Perl modules (libraries), such as WxPerl and Tk, provide Perl
programmers with the option of easily creating a GUI-interface for users to interact with
the Perl code.
■ Administrative tools—System administrators create Perl scripts to help them automate
administrative tasks.
Chapter 9, “Perl Scripting,” provides additional details regarding the creation of Perl programs.
Python Scripting
The beginnings of Python are best described by Guido van Rossum, its creator, who wrote the
following as a forward for a book on Python published in 1996:
Over six years ago, in December 1989, I was looking for a “hobby” programming
project that would keep me occupied during the week around Christmas.
My office … would be closed, but I had a home computer, and not much else on my
hands. I decided to write an interpreter for the new scripting language I had been
thinking about lately: a descendant of ABC that would appeal to Unix/C hackers.
I chose Python as a working title for the project, being in a slightly irreverent mood
(and a big fan of Monty Python’s Flying Circus).
Little did he know that Python would one day become one of the world’s most popular scripting
languages. Since that fateful Christmas break in the late 1980s, Python has developed over
time into a robust programming language that is the core of many Linux tools and open
source projects.
5 LAMP = Linux, Apache HTTP Server, MySQL, and Perl (or PHP). LAMP is a collection of technologies
that make up a solution stack to provide web services.
Scripting Languages 101
One of the driving philosophies of Python is well-structured code. Python enforces this with
rules such as a very rigid indentation scheme. You can see how seriously Python developers
take the concept of well-structured code by reading some of the rules defined by the document
“Zen of Python”:
■ Beautiful is better than ugly.
■ Explicit is better than implicit.
■ Simple is better than complex.
■ Complex is better than complicated.
■ Flat is better than nested.
■ Sparse is better than dense.
■ Readability counts.
Although Python can be used for many different applications, it is often used for the following:
■ Network-based applications—By using Twisted, a Python-based network framework,
network-based applications can be developed.
■ Web development—The Apache Web Server provides the option of using Python scripts
for dynamic websites.
■ Scientific applications—Several libraries are available for Python that make it a good
choice to create scientific applications.
■ System tools—Linux developers often use Python to create system tools for the operating
system.
Additional details regarding the creation of Python programs are provided in Chapter 10,
“Python Scripting.”
Ruby
Developed in the mid-1990s by Yukihiro Matsumoto, Ruby’s origin is best described by
its creator:
Initially Ruby wasn’t as popular as Perl and Python, although it was praised for being a good
object-oriented scripting language. Ruby became more popular when Ruby on Rails, a web
application framework, was introduced.
Ruby Essentials
Is it installed?
root@centos:~# which ruby
/usr/bin/ruby
PHP
PHP is a recursive acronym that stands for PHP: Hypertext Preprocessor, although when it
was originally released PHP stood for Personal Home Page. Like Ruby, PHP was developed in
the mid-1990s. Created by Rasmus Lerdorf to dynamically create web pages, it has become a
popular scripting language for website designers.
PHP is an important part of the LAMP architecture. Seeing embedded PHP code within an
HTML document is common. PHP can also be used as a standalone scripting language.
PHP Essentials
Is it installed?
root@centos:~# which php
/usr/bin/php
JavaScript
In the mid-1990s the World Wide Web was just starting to become popular. An organization
named Mosaic Communications (later becoming Netscape Communications) had just
104 Chapter 7 Overview of Linux Programming Languages
developed a graphical web browser and was exploring the possibility of using a programming
language to enhance HTML. Initially they chose to incorporate Java. However, they soon
decided that a scripting language would be a better solution.
JavaScript was designed to be similar to Java in terms of syntax. However, it is not a “spin-off”
or extension of Java, but rather a scripting language that has similar syntax.
In addition to being heavily used, JavaScript is also used as an embedded scripting language in
many products including Adobe Acrobat, MongoDB, and extensions for the Chrome and Opera
web browsers.
JavaScript Essentials
Is it installed?
JavaScript is executed as part of the web browser, not typically installed. However, you can
download and install an executable version from http://www. http://
javascript-exe.com.
Sample script—embedded HTML example:
<html>
<head>
<title></title>
</head>
<body>
<script>
console.log("hello world");
</script>
</body>
</html>
Tcl
Tcl7 was created in the late 1980s by John Ousterhout. The tool was originally created for his
students to use while he was a professor at the University of California, Berkeley. As addi-
tional features were added to the language and these students graduated, the popularity of the
language grew.
In the early 1990s, the scripting language market was growing crowded and it was hard for a
newer language to build traction. One of the main reasons Tcl became popular was the intro-
duction of Tk, the Tool Kit extension to the Tcl language. Essentially a separate language itself,
Tk made use of Tcl as a base language and added features that enabled developers to quickly
and easily create graphical-based, platform-independent programs. The combination of Tcl and
Tk is referred to as Tcl/Tk.
Tcl/Tk Essentials
Is it installed (Tcl=tclsh, Tk=wish)?
root@centos:~# which tclsh
/usr/bin/tclsh
root@centos:~# which wish
/usr/bin/wish
Sample Tk s cript:
root@centos:~# more hello.tk
#!/usr/bin/wish
button .hello -text "Hello World" -command { exit }
pack .hello
root@kali:~# chmod a+x hello.tk
root@kali:~# ./hello.tk
#Note: output is a graphical program
preform some sort of change to a document. For example, the following sed command replaces
all numbers with an X character:8
root@centos:~# more /etc/hosts
127.0.0.1 localhost
127.0.1.1 centos
The awk utility is designed to work on database-based information, such as a system file.
For example, consider the following data from the /etc/passwd file:
root@centos:~# 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
With the awk utility, we either display or modify fields of data. For example, to print just the
user name (first field) and login shell (seventh field), use the following awk command:
root@centos:~# head /etc/passwd | awk -F : '{print $1, $7}'
root /bin/bash
daemon /usr/sbin/nologin
bin /usr/sbin/nologin
sys /usr/sbin/nologin
sync /bin/sync
games /usr/sbin/nologin
man /usr/sbin/nologin
8 Does the syntax 's/[0-9]/X/g' look familiar? It should remind you of the search and replace feature of
the vi editor (see Chapter 5, “Text Editors”). This is because, like vi, sed was derived from older UNIX editors.
Compiled Languages 107
lp /usr/sbin/nologin
mail /usr/sbin/nologin
news /usr/sbin/nologin
Both sed and awk are not only powerful command-line utilities, but they also have simple
programming features, such as variable usage and flow control. For more details on creating
sed scripts, view the man page for sed or see https://www.gnu.org/software/sed/manual/sed.
html. The awk utility also has a good man page in addition to the following website: https://
www.gnu.org/software/gawk/manual/gawk.html.
Compiled Languages
The primary focus of this book is to introduce developers to Linux and languages that are
specifically popular in Linux. Complied languages, such as C, C++, and Java9 are not covered in
great detail in this book for several reasons:
■ These languages are huge topics and more difficult to learn than scripting languages.
■ Although these languages certainly exist and are popular in Linux, they are even more
widely used on non-Linux platforms, such as Microsoft Windows (particularly C++ and
Microsoft's C#). In other words, they aren't languages that are primarily popular in Linux
but standard languages commonly found on many platforms.
■ The assumption is that you are already a developer and likely already know one or more
of these complied languages.
Although this book won't include specifics on how to create C, C++, or Java programs, Chapter 11,
“C, C++, and Java,” does cover topics specifically related to writing code in these languages on
Linux platforms. This includes the following:
■ Handling system libraries
■ Building packages
■ Java installation
C Programming Basics
In the event that you are not familiar with the C language, here are some basics that you
should be aware of:
■ It’s an older and well-established language.
■ It lacks object-oriented features.
9 Technically Java isn’t a complied language, but it belongs more in this category than the scripting
language category.
108 Chapter 7 Overview of Linux Programming Languages
IDEs
As a developer you might already be familiar with Integrated Development Environments
(IDEs). For example, if you have developed C or C++ code on Microsoft Windows platforms,
you are likely familiar with Microsoft Visual Studio.
An IDE provides you with tools to make the process of developing code easier. These tools
could include a debugger program, a special editor that provides syntax highlighting and other
features or features that enable you to insert new code quickly (and without error).
Many IDEs are available for Linux. Some are very specific to a language, whereas others are a
bit more generic. It is also important to note that some of these IDEs are free, but others might
require a fee of some sort to use them.
The goal of mentioning IDEs is to encourage you to explore what is available. Suppose, for
example, you explore the different Linux programming languages and decide that Python is
Summary 109
the best language for you. Before diving into the language further, explore the available IDEs
(more than a dozen exist just for Python) and make a point to learn how to use the one that
best meets your needs.10
Programming Humor
Algorithm (noun): Word used by software developers when they do not want to explain what
their code does.
Summary
This chapter provided you with a foundation in programming languages that are commonly
used on Linux distributions. You learned the difference between a scripting language and a
structured language. You were also introduced to several different scripting languages that are
popular on Linux. The topics described in this chapter lay the groundwork for the next four
chapters in which you will learn more about BASH, Perl, and Python scripting as well as essen-
tials regarding writing C, C++, and Java code on Linux distributions.
10 If you follow my advice on IDEs, you will not be sorry. I can’t tell you how many developers I have
spoken to who are using simple text editors to create their code and not taking advantage of great
debugging tools that are available. They waste hours of time by using inadequate tools. Save your-
self future headaches and find a good IDE now, not sometime in the future!
This page intentionally left blank
8
BASH Shell Scripting
The primary benefit of BASH scripting is that you can use everything that is available in the
BASH shell within a BASH script. Because your Linux distribution has hundreds (maybe even
thousands) of commands, each of which can be used in a BASH script, BASH shell scripting can
be a very powerful tool.
This chapter focuses on providing you a firm understanding of how to write basic BASH scripts
as well as introducing you to some of the more advanced features.
To start a BASH script, enter the following as the first line of the script file:
#!/bin/bash
This special sequence is called the sha-bang, and it tells the system to execute this code as a
BASH script.
Comments in a BASH script start with a # character and extend to the end of the line.
For example:
echo "hello world" #prints "hello" to the screen
112 Chapter 8 BASH Shell Scripting
As shown in the preceding example, you can use the echo command to display information to
the user who is running a program. The arguments to the echo command can contain any text
data and can also include the value of a variable:
echo "The answer is $result"
After creating your BASH script and saving it, you then make it executable:
[student@OCS ~]$ more hello.sh
#!/bin/bash
#hello.sh
Note the need to place ./ before the name of the command. This is because the command
might not be in one of the directories specified by the $PATH variable:
[student@OCS ~]$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/
games
To avoid the need to include ./ whenever you want to run your script, you can modify the
$PATH variable to include the directory in which your script is stored. Typically, regular users
create a “bin” directory in their home directory and place scripts in this location:
[student@OCS ~]$ mkdir bin
[student@OCS ~]$ cp hello.sh bin
[student@OCS ~]$ PATH="$PATH:/home/student/bin"
[student@OCS ~]$ hello.sh
hello world!
In addition to the built-in variables that were discussed in Chapter 4, variables are available in
BASH scripts that represent the arguments being passed into the script. For example, consider
the following execution of a script called test.sh:
[student@OCS ~]$ test.sh Bob Sue Ted
The values “Bob,” “Sue,” and “Ted” are assigned to variables within the script. The first argu-
ment (“Bob”) is assigned to the $1 variable, the second argument is assigned to the $2 variable,
and so on. Additionally, all arguments collectively are assigned to the $@ variable.
For additional details regarding these positional parameters variables, or anything related the
BASH scripting, consult the man page for bash:
[student@OCS ~]$ man bash
Conditional Expressions 113
Conditional Expressions
Several conditional statements are available for the BASH shell, including the if statement:
if [ cond ]
then
statements
elif [ cond ]
then
statement
else
statements
fi
color=$1
if [ "$color" = "blue" ]
then
echo "it is blue"
elif [ "$color" = "red" ]
then
echo "it is red"
else
echo "no idea what this color is"
fi
Quoting variables
Get in the habit of putting double quotes around your variables in BASH scripts. This is
important in the event the variable hasn’t been assigned a value. For example, suppose the
script in Listing 8.1 was execute with no arguments. The result would be that the color variable
is unassigned and the resulting conditional statement would be if [ "" = "blue" ]
The result would be false, but without the quotes around $color, the result would be an
error message and the script would exit immediately. This is because the resulting conditional
statement would be missing one of its key components after the value of $color has been
returned: if [ = "blue" ]
This syntax performs an implicit call of a BASH command named test that you can use to
perform several comparison tests. This can include integer (numeric) comparisons, string compari-
sons, and file testing operations.1 For example, use the following syntax to test whether the string
value that is stored in the $name1 variable does not equal the string stored in the $name2 variable:
[ "$name1" != "$name2" ]
Important Note
The spacing around the square brackets is very important. There should be a space before and
after each square bracket. Without these, an error message occurs.
In addition to determining whether two strings are equal or not equal to each other, you might
also find the -n option useful.2 This option determines whether a string is not empty, which is
useful when testing user input. For example, the code in Listing 8.2 reads data from user input
(the keyboard), assigns the input to the $name variable, and tests to make sure the user typed
something for the name.
if [ -n "$name" ]
then
echo "Thank you!"
else
echo "hey, you didn't give a name!"
fi
[student@OCS ~]$./name.sh
Enter your name
1 See the man page for test to learn more about its comparison operations: man test
2 A similar option, -z, returns true if the string contains zero characters.
Flow Control Statements 115
Bo
Thank you!
[student@OCS ~]$./name.sh
Enter your name
hey, you didn't give a name!
Integer Comparisons
If you want to perform integer (numeric) comparison operations, use the following:
The egrep command from the previous example may be a bit tricky to understand. To begin
with, the regular expression pattern is matching a value that is exactly five digits. The –v
option is used to return a value if the pattern is not found. So, if $ZIP contains a valid
five-digit number, then egrep returns a false result because it is trying to find lines that don’t
contain a five-digit number. The egrep command returns a true result if the $ZIP contains
something besides a five-digit number.
Why the > /dev/null 2>&1? Because we don’t want to display anything from the egrep
command, just make use of its true/false return value. All OS commands return true or false3
when executed, and that is what is needed here. Any STDOUT or STDERR from the command is
unnecessary and only serves to confuse matters if it is displayed to the user.
Loop Control
Like most languages, BASH scripting provides a way to prematurely exit a loop or to stop the
current iteration of a loop and start a new iteration of a loop. Use the break command to
immediately exit a while, until, or for loop. Use the continue command to stop the current
iteration of a while, until, or for loop and start the next iteration.
3 Technically they return 0 for “true” and a positive number for “false.”
User Interaction 117
For the preceding syntax example, var represents a variable’s value that you want to
conditionally check. For example, consider the following code:
name="bob"
case $name in
ted) echo "it is ted";;
bob) echo "it is bob";;
*) echo "I have no idea who you are"
esac
The “condition” is a pattern that uses the same matching rules as file wildcards. An * matches
zero or more of any character, a ? matches a single character, and you can use square brackets
to match a single character of a specific range. You can also use a |character to represent “or.”
For example, consider Listing 8.3, which is used to check a user’s answer to a question:
case $answer in
y|ye[sp]) echo "you said yes";;
n|no|nope) echo "you said no";;
*) echo "bad response";;
esac
User Interaction
The example in Listing 8.3 is a bit of a puzzle because it is intended to check user input.
However, the variable is hard coded. Using actual user input, which the read statement can
gather, would make more sense:
read answer
118 Chapter 8 BASH Shell Scripting
The read statement prompts the user to provide information and reads that data (technically
from STDIN) into a variable that is specified as the argument to the read statement. See Listing 8.4
for an example.
case $answer in
y|ye[sp]) echo "you said yes";;
n|no|nope) echo "you said no";;
*) echo "bad response";;
esac
Additional Information
Do you want to learn more about creating BASH scripts? The following are good resources for
additional information:
■ man bash—The man page for the BASH shell has a great deal of information about
writing BASH scripts.
■ http://tldp.org—A website that is (sadly) mostly out of date.4 However, it has one gem of
a document called the “Advanced Bash-Scripting Guide.” Click on the Guides link under
the Documents section and scroll down until you see this guide. The author of this guide
normally updates it on a regular basis. Because the guides are listed by publication date,
this guide is almost always at the top of the list.
Summary
This book does not cover some additional features of BASH scripting. However, the goal of this
chapter was to provide you with enough information to determine whether BASH scripting is a
good language for you. If you liked the features and syntax of BASH scripting, consider explor-
ing the documentation provided to learn more about this flexible language.
4 It has a few up-to-date documents, but most are very much outdated. Look at the publication date of
the document and realize that anything older than a couple of years is probably no longer accurate
(but still might provide you with some useful information).
9
Perl Scripting
Although Perl might have started as a simple scripting language, it has grown into a robust
language designed to tackle many different coding situations. There is a great deal to learn
about Perl scripting (as well as the other programming languages discussed in this book), so
don’t expect to become an expert overnight.
This chapter’s focus is to give you a firm understanding of how to write basic Perl scripts as well
as provide an understanding of some of Perl’s more advanced features.
Note that a semicolon (;) is used to end a statement in Perl. Also note that the \n string
represents a newline character. The print statement doesn’t naturally display a newline
character, which makes for awkward output when multiple print statements are executed.
Comments in Perl begin with a pound sign character (#) and extend to the end of the line.
For example:
# This is my first Perl script
print "hello\n"; #displays "hello"
1 Just because it could be written this way doesn’t mean you should write your code like this. As with
all languages, you should try to write Perl code that is easy to read.
120 Chapter 9 Perl Scripting
Typing the perl command before each execution can become annoying. To avoid that, make
use of the #! line:
[student@OCS ~]$ more hello.pl
#!/bin/perl
print "hello\n";
[student@OCS ~]$ chmod a+x hello.pl
[student@OCS ~]$ ./hello.pl
hello
You can also make use of a feature called the Perl debugger to execute Perl code interactively.
Start by executing the following command: perl -d -e "1;"
The -d option enters the Perl debugger, which requires valid Perl code. The -e option means
“execute the code provided on the command line.” The "1;" is valid Perl code; it doesn’t do
anything but return the value of true. The result of this command should be a prompt like the
one shown in Listing 9.1.
Enter h or 'h h' for help, or 'man perldebug' for more help.
main::(-e:1): 1;
DB<1>
At the DB<1 prompt you can type a Perl statement. Press the Enter key to execute the
command. This enables you to test Perl code interactively.2 A couple of things to note:
■ Normally you need to place a ; character after each Perl statement. In the Perl debugger,
the Enter key acts like a ; character. This means you don’t need a ; character at the end
of a Perl statement within the debugger.
2 This method also provides a way for me to demonstrate Perl features without having to create a full
Perl script.
Basics of Perl Scripting 121
■ A few things don’t work in the Perl debugger (for example, a regular expression feature
called backreferencing). However, almost everything that works in a Perl script also
works in the interactive Perl debugger.
■ To exit the Perl debugger, type q and then press the ENTER key.
The perldoc command is especially useful. Try running the following command:
perldoc perl
Man page-like output appears that provides information about Perl. Included in this is a list of
additional categories as shown in Figure 9.1.
So, if you want to learn about Perl regular expressions, you could execute the perldoc
perlrequick or perldoc perlretut commands. You can view dozens of different categories
to learn more about Perl. As you learn more details about Perl while reading this book, consider
diving into this documentation as well.
■ Scalar—A single data type that can be used as either a string or a number.
■ Array—An ordered list of scalar values, separated by commas.
■ Hash—A collection of unordered values that are referenced by using a scalar key. Also
called an associate array.
Enter h or 'h h' for help, or 'man perldebug' for more help.
main::(-e:1): 1;
DB<1> $name="Bob"
DB<2> print $name
Bob
Note
To read data from the user (the keyboard), use the syntax $name=<STDIN>;
Several useful built-in Perl statements are used on scalars, including the statements shown
in Listing 9.2.
Enter h or 'h h' for help, or 'man perldebug' for more help.
Basics of Perl Scripting 123
main::(-e:1): 1;
DB<1> $name=<STDIN> #grabs data from keyboard and assigns to $name
Bob Smith
DB<2> print $name #prints "Bob Smith\n"; \n is a newline character
Bob Smith
DB<3> chomp $name #removes newline character at the end of string
DB<4> print $name #prints "Bob Smith" without newline character
Bob Smith
DB<5> $name=lc ($name) #returns lower case "bob smith"
DB<6> print $name
bob smith
One confusing element of Perl is how you refer to individual elements in an array. Because
those individual elements are scalar values, you use a $ character to display a single value.
For example, to display the first element in an array you do something like the following:
DB<1> @colors=("red", "blue", "green")
DB<2> print $colors[0]
red
You can perform an operation on each element in an array by using the foreach statement:
DB<1> @names=("Smith", "Jones", "Rothwell")
DB<2> foreach $person (@names) {print "Hello, Mr. $person\n";}
Hello, Mr. Smith
Hello, Mr. Jones
Hello, Mr. Rothwell
124 Chapter 9 Perl Scripting
Creating an array can be a pain because of all the quotes3 and commas. To make life easier, use
the qw or qq statements:
DB<1> @colors=qq(red blue green) #same as @colors=("red", "blue", "green")
DB<2> @colors=qw(red blue green) #same as @colors=('red', 'blue', 'green')
A hash (called a dictionary in some other languages) provides a way to associate a key with a
value. For example, to keep track of the favorite color of some people, you could use the follow-
ing code:
DB<1> %favorite=("Sue" => "blue", "Ted" => "green", "Nick" => "black")
DB<2> print $favorite{"Ted"}
green
Special Variables
Several variables in Perl have a special meaning to the language. Typically these variables have
cryptic names, such as $| or $_. For example, the $$ variable contains the process ID of the
Perl process itself.
Some of these variables hold important information whereas others can be modified to change
the behavior of how Perl functions. To see a description of all of these special variables, visit
this URL: http://perldoc.perl.org/perlvar.html.
Flow Control
Perl supports many traditional flow control statements, including the if statement:4
$name=<STDIN>;
chomp $name;
3 Yes, you should use quotes around strings, even though it seems like you don’t need them in Perl.
By default, Perl tries to use an unquoted value as a function and replaces the function call with the
return value of the function. Placing quotes around the string prevents function calls.
4 Note the formatting of this code. Perl really doesn’t care about formatting, but someone reading your
code will. There is no standard convention as to how you format your Perl code, but I suggest that
you at least be consistent within the program that you are writing to make it easier to read.
Flow Control 125
if ($name eq "Tim")
{
print "Welcome, Tim!";
}
elsif ($name eq "Bob")
{
print "Welcome, Bob!";
}
else
{
print "Welcome, stranger!";
}
elsif?
Be careful when writing Perl if statements because the “else if” statement is oddly spelled.
It is a single word, with the second “e” missing!
Another common conditional statement is the while loop. With the while loop, a conditional
check is performed and, if the condition is true, a block of code is executed. After the block of
code is executed, the conditional check is performed again. See Listing 9.3 for an example.
The ^Code and ^Test are regular expressions and are covered later in this chapter.
Many languages support loop control statements such as break and continue. Perl also
supports loop control statements, but they are called last and next instead of break and
continue. You can use these loop controls statements in while, until for, and foreach loops.
Conditions
Perl supports a large variety of conditional expressions, including numeric comparison, string
comparison, file testing operations, and regular expressions. You can also use the outcome of
a Perl statement, but be aware that only a handful of built-in Perl statements return a natural
true or false value.
Example:
if ($age < 35) {}
■ <= Determine whether one number is less than or equal to another number.
Example:
if ($age <= 35) {}
Conditions 127
Example:
if ($age > 35) {}
■ >= Determine whether one number is greater than or equal to another number.
Example:
if ($age >= 35) {}
Example:
if ($name eq “Bob”) {}
Example:
if ($name ne “Bob”) {}
Example:
if ($name lt “Bob”) {}
Example:
if ($name le “Bob”) {}
Example:
if ($name gt “Bob”) {}
Example:
if ($name ge “Bob”) {}
5 Note that when you look at Perl documentation, file test operators are not listed in the section
regarding operators, but rather under the “Functions” section. Look for –X under functions to learn
more about file test operators.
128 Chapter 9 Perl Scripting
Regular expressions are a powerful feature in the Perl programming language. For example, you
can see whether a pattern exists inside of a scalar variable by using the following code:
$name=<STDIN>;
if ($name =~ m/Bob/)
{
print "yes"
}
When reading Perl code, you should be aware of a few regular expression features:
■ The $_ variable is called the default variable and is often used by default. For example:
if ($_ =~ /Bob/) {} is the same as if (/Bob/) {}
Additional Features
In addition to reading from the keyboard (STDIN), you can open files and read directly from
the files. This is referred to as opening a filehandle:7
open (DATA, "<file.txt");
$line=<DATA>;
close DATA; #when finished, close the filehandle
6 I know the wording of this seems odd, but a directory is technically a file in Linux. It is a file that
contains specific data, a list of files that are in the directory.
7 Several techniques actually exist for reading from a file. This is just one of them.
Additional Features 129
Another important feature in Perl is functions. To create a function, use the following syntax:
sub welcome
{
print "This is my function";
}
By default, any variable created in the main part of the program is available in a function.
Additionally, any variable in a function is available in the main part of the program:
sub total
{
$z=$x + $y; # $x and $y from main program
}
$x=10;
$y=5;
&total;
print $z; # $z from total subroutine
my $x=10;
my $y=5;
&total;
print $z; # $z is not set here
To reuse code in other programs, Perl has a feature called modules. Modules are like libraries in
other languages. By calling a module, you will have access to functions that are shared by that
module to your program.
For example, the following module call provides a function called cwd, which displays the
current directory:
[student@OCS ~]$ perl -d -e "1;"
8 This is a very simplistic view of variable scope in Perl. In reality, Perl provides you with the capability
to have a much more robust (and complex) scoping process.
130 Chapter 9 Perl Scripting
Enter h or 'h h' for help, or 'man perldebug' for more help.
main::(-e:1): 1;
DB<1> use Cwd;
DB<2> print cwd;
/home/student
■ By convention, module names begin with a capital letter. If you see a use statement that
calls something that is in all lowercase characters, it isn’t a module, but rather another
Perl feature called a pragma. Pragmas are used to change the default behavior of Perl and
are well documented on perldoc.perl.org in the “Pragmas” section.
■ Perl comes with literally hundreds of built-in modules that enhance the functionality of the
language greatly. These are all well documented on perldoc.perl.org in the “Modules” section.
■ Which functions are provided by the module depend on the developer who created the
module. View the module documentation to determine which functions are provided.
■ You can create your own modules, but that topic is beyond the scope of this book. See
perldoc.perl.org → language → perlmodlib for details.
Perl Humor
Larry Wall continues to oversee further development of Perl and serves as the benevolent
dictator for life of the Perl project. His role in Perl is best conveyed by the so-called 2 Rules,
taken from the official Perl documentation:
1. Larry is always by definition right about how Perl should behave. This means he has final
veto power on the core functionality.
2. Larry is allowed to change his mind about any matter at a later date, regardless of
whether he previously invoked Rule 1.
Got that? Larry is always right, even when he was wrong.
Summary
As a robust language, Perl has many additional features that were not covered in this chapter.
However, the goal of this chapter was to provide you with enough information to determine
whether Perl is a good language for you. If you liked the features and syntax of Perl, considering
exploring the documentation sources provided to learn more about this flexible language.
10
Python Scripting
Python is a robust programming language that provides many different features that you would
expect from a modern language. One of its many benefits is the fact that it is object-oriented
by nature, making it a good language for large task programs.
This chapter’s focus is to give you a firm understanding of how to write basic Python scripts as
well as provide you with an understanding of some of Python’s more advanced features.
When you create a block of code, you must indent the entire block with the same number of
white space characters. For example, consider the following code fragment, focusing on how
the code is indented:
x = 25
if x > 15:
print x
a = 1
else:
print x
a = 2
The preceding code fragment results in a compile time error message because the second print
statement isn’t properly indented. The positive thing about enforced structure is that it makes
your code easier to read (for both others and yourself when you look over code that you wrote
months or years ago). The negative thing is that it can be a pain when you miss a space or
accidently use a tab instead of four spaces.1
1 You might be thinking, “Why did he say four spaces and not five or eight?” Python Enhancement
Proposals (PEPs) are a major component of Python development. PEP8 is the “Style Guide for Python
Code,” and it states that the standard for indentation is four spaces.
132 Chapter 10 Python Scripting
Note that the python command not only displays the version of Python, but it also places you
into an interactive Python shell where you can test Python code on the fly. To exit this Python
shell, enter the quit() statement as shown in the previous example.
To execute a Python script that is stored in a file, use the following syntax:
[student@OCS ~]$ python script.py
Typing the python command before each execution can become annoying. To avoid that,
make use of the #! line:
[student@OCS ~]$ more hello.py
#!/bin/python
print "hello"
[student@OCS ~]$ chmod a+x hello.py
[student@OCS ~]$ ./hello.py
hello
As demonstrated from the previous example, the print statement in Python is used to produce
output. By default, this output goes to STDOUT.
These files are created when a Python library is called. The idea is that the compile process
takes time and each time a library is called, its code would have to be compiled. To make the
process more efficient, Python automatically saves this code into files that end in .pyc. So, if
you call a library called input.py, you should expect to see a file called input.pyc after the pro-
gram that calls the library is executed.
When Python is invoked with the -O option, a .pyo file is generated. Like .pyc files, this is
compiled code, but it is optimized complied code.
Additional Documentation
Initially you probably want to look at the man page for python: man python. This provides
you with some of the basics of the python executable, but there isn’t much focus on how to
write code in Python.
However, at the bottom of the python man page are some very useful links to additional docu-
mentation, as shown in Figure 10.1.
The URL http://docs.python.org/ will likely be the most useful resource when you start learning
Python, but the other links will also prove valuable over time.
■ Numeric variables—A single data type that is used to store numeric values.
■ String variables—A single data type that is used to store string values.
■ Lists—An ordered list of numeric or string values.
■ Dictionaries—A collection of unordered values that are referenced by using a key.
Numbers and strings are different in that you can perform certain operations on numbers
(addition, subtraction, and so on) but not on strings as demonstrated in Listing 10.1.
134 Chapter 10 Python Scripting
Note the error that occurred in the last statement of Listing 10.1 when the string variable was
used in a numeric operation.
Python has a rich set of operations that can be performed on strings. For example, you can use
the following to capitalize a string:
>>> name="ted"
>>> name=name.capitalize()
>>> print name
Ted
Python is an object-oriented language. Variables store typed objects (numeric type, string type,
and so on), and to call a method on an object, you use the notation var.method(). So, name.
capitalize() calls the capitalize method on the object in the name variable.
Note that Python has a few traditional functions as well. For example, consider the
following code:
>>> name="ted"
>>> print len(name)
3
The len function takes an object as an argument and returns the length of the object. Granted,
using both method calls and functions can sometimes be confusing, but keep in mind that
most of Python consists of method calls, and functions are fairly rare.
The Tuple
You are likely to come across another data structure that works much like a list called a tuple.
Consider a tuple to be a list that, once created, can’t be modified. Technically, tuples are immu-
table, a fancy way of saying unchangeable. They are a clever way of having constant-like data
structures.
Times occur when you will want to get a list of all the keys of a dictionary. To accomplish this,
use the keys() method:2
>>> age={'Sarah': 25, "Julia": 18, "Nick": 107}
>>> print age.keys()
['Sarah', 'Nick', 'Julia']
2 Note that the return value of the keys are not in the order they were originally created in. Remember
that a dictionary is an unordered collection of key-value pairs.
136 Chapter 10 Python Scripting
Flow Control
Python supports many traditional flow control statements, including the if statement:
age=15
if age >= 16:
print "you are old enough to drive"
elif age == 15:
print "you are old enough for a permit"
else:
print "sorry, you can't drive yet"
Another common conditional statement is the while loop. With the while loop, a conditional
check is performed and, if the condition is true, a block of code is executed. After the block of
code is executed, the conditional check is performed again. See Listing 10.2 for an example.
Note that in Listing 10.2, the raw_input() function gets data from the user (STDIN, likely the
keyboard) and the int() function converts this data into an integer object.
Many languages support loop control statements such as break and continue. Python has
these statements, which you can use in while loops or for loops. The break statement exits
the loop prematurely and the continue statement stops the current iteration of the loop and
starts the next iteration. Python also supports an else statement that you can use to execute
additional code if the loop is terminated without a break statement.
Conditions
Python supports a large variety of conditional expressions, which enable you to perform
comparison operations on like objects. For example, you can compare strings to strings,
dictionaries to dictionaries, and so on.
Additional Features
In addition to reading from the keyboard, you can open files and read directly from the files.
For example:
>>> data=open('test.py', 'r')
>>> print data
<open file 'test.py', mode 'r' at 0x7f4db20ba1e0>
The first argument to the open statement is the filename to open. The second argument is how
to open it. The value 'r' means to open the file for reading. You can also open a file and write
to the file by using the value of 'w'.
You can use several methods for reading from and writing to a file after opening it:
Another important feature in Python is functions. To create a function, use the following
syntax:
def welcome():
print "This is my function"
To reuse code in other programs, Perl has a feature called modules. By calling a module, you
have access to functions that are shared by that module in your program.
For example, the following module call provides a function called path that displays a list of
directories where Python libraries are held:
>>> import sys
>>> print sys.path
['', '/usr/lib64/python27.zip', '/usr/lib64/python2.7', '/usr/lib64/python2.7/plat-
linux2', '/usr/lib64/python2.7/lib-tk', '/usr/lib64/python2.7/lib-old', '/usr/lib64/
python2.7/lib-dynload', '/usr/lib64/python2.7/site-packages', '/usr/lib64/python2.7/
site-packages/gtk-2.0', '/usr/lib/python2.7/site-packages'] /home/student
Programming Humor
Definition of recursion:
1. Stop when you understand the definition.
2. See definition of recursion.
Summary
This chapter serves as an introduction to the Python language. As with most languages
discussed in this book, Python offers many other features. The purpose of this chapter was
to introduce you to the language to determine whether it might meet your software
development needs.
11
C, C++, and Java
The purpose of this chapter is different from the last three chapters. Although the goals of
Chapters 8–10 were to introduce you to new languages, the assumption in this chapter is that
you already have a background coding C, C++, or Java. These languages are popular on all
operating systems, including Microsoft Windows.
Instead of covering the basics of C, C++, and Java, the focus on this chapter is on topics
that are related to these languages. Specifically, the goal is to provide you with information
regarding the Linux operating system’s impact on how you create programs in these languages.
Another program calls libraries via the #include statement in the source code. For example:
#include <stdio.h>
Usually, shared library files are stored in one of the following locations on Linux distributions:
■ /lib or /lib64
■ /usr/lib or /usr/lib64
■ /usr/local/lib or /usr/local/lib64
If your operating system is a 32-bit distribution, expect to see the libraries under /lib, /usr/
lib, and /usr/local/lib. On 64-bit platforms, the /lib64, /usr/lib/64, and /usr/local/
lib64 directories are where you can expect to file libraries. You may also see file libraries under
the 32-bit directories because some applications may run as 32-bit even under a 64-bit operat-
ing system. See Figure 11.1 for an example of the /lib64 directory.
These shared libraries follow the naming convention of libname.so.ver. In this case, the
name is a unique name for the library and ver is used to indicate the version number of this
library—for example, libkpathsea.so.6.1.1.
The idea of managing shared libraries on the system is to add or remove libraries as needed.
This requires access to the system as the root user because only the root user can modify the
configuration files.
Understanding System Libraries 141
The primary configuration file for shared libraries is the /etc/ld.so.conf file. However,
typically only a single line is in this file:
[root@localhost ~]# more /etc/ld.so.conf
include ld.so.conf.d/*.conf
The include line in this file tells the system to also use all the configuration files in the speci-
fied directory. In the case of the preceding example, that would be all the files that end in
.conf in the /etc/ld.so.conf.d directory:
[root@localhost ~]# ls /etc/ld.so.conf.d
dyninst-x86_64.conf libiscsi-x86_64.conf
kernel-3.10.0-327.el7.x86_64.conf mariadb-x86_64.conf
A big advantage exists for using this include method. Suppose you create some software that
requires some shared libraries. To install that software on a system, you need to tell the system
where these new libraries are. Instead of having to create an installation program that modifies
the primary configuration file (/etc/ld.so.conf), your installation program can simply copy
a configuration file into the /etc/ld.so.conf.d directory. Conversely, the uninstall program
that you create to remove the software could simply delete this file from the /etc/ld.so.
conf.d directory.
The configuration file itself is simple. It just contains a directory in which the shared libraries
are stored:
[root@localhost ~]# more /etc/ld.so.conf.d/libiscsi-x86_64.conf
/usr/lib64/iscsi
[root@localhost ~]# ls /usr/lib64/iscsi/
libiscsi.so.2 libiscsi.so.2.0.10900
To add new shared libraries to the system, you first download the libraries to the system and
place them into a directory. After adding new libraries, you create a configuration file in the
/etc/ld.so.conf.d directory and then execute the ldconfig command.1 You should perform
all of these tasks as the root user:
[root@localhost ~]# ls /usr/lib64/test
mylib.so.1
[root@localhost ~]# cat /etc/ld.so.conf.d/libtest.conf
/usr/lib64/test
[root@localhost ~]# ldconfig
Regular users can’t successfully execute the ldconfig command. However, if a regular user
wants to use a custom shared library, then the user can download this file into her home direc-
tory and make use of the LD_LIBRARY_PATH to indicate the location of custom library files:
[student@localhost ~]$ ls lib
mylib.so.1
[student@localhost ~]$ export LD_LIBRARY_PATH=/home/student/lib
1 No news is good news for the ldconfig command. No output means the command worked
successfully.
142 Chapter 11 C, C++, and Java
The purpose of using the ldd command is to troubleshoot problems with code that you are
writing. This command tells you not only what libraries are being called, but specifically which
directory each library is being called from. This can be extremely useful when a library is not
behaving as you would expect it to behave.
Building Packages
You have successfully completed creating your software and are ready to package the software
so it can be installed. The two common techniques for packaging software are by using RPM
and Debian.2 Typically, you use RPM to build packages on Red Hat–based distributions
(RHEL, Fedora, CentOS, and so on) and Debian on Debian-based systems (Debian, Ubuntu,
Mint, and so on).
Note
Creating a software package with RPM or Debian can be very complex. The examples provided
in this chapter are very general and designed to provide an overview of how to build packages.
2 Other methods you might want to consider include APK, TGZ, and PET. For example, TGZ is when you
use the tar command to merge all files into a single file and then the gzip command to compress
the tar file.
Building Packages 143
Dependencies Resolved
Transaction Summary
======================================================================================
======================================
Install 1 Package (+5 Dependent packages)
1/6
Verifying : perl-srpm-macros-1-8.el7.noarch
2/6
Verifying : perl-Thread-Queue-3.02-2.el7.noarch
3/6
Verifying : rpm-build-4.11.3-17.el7.x86_64
4/6
Verifying : dwz-0.11-3.el7.x86_64
5/6
Verifying : patch-2.7.1-8.el7.x86_64
6/6
Installed:
rpm-build.x86_64 0:4.11.3-17.el7
Dependency Installed:
dwz.x86_64 0:0.11-3.el7 patch.x86_64 0:2.7.1-8.el7
perl-Thread-Queue.noarch 0:3.02-2.el7
perl-srpm-macros.noarch 0:1-8.el7 redhat-rpm-config.noarch 0:9.1.0-68.el7.centos
Complete!
The next step is a bit tricky because you need to create a directory structure that contains
various files, including your software and instructions on how to install the software.
I recommend downloading the source code of a sample project and using that as a template.
For example, after downloading the source code for the dovecot package, you can expand the
source code by using the rpm command as demonstrated in Listing 11.3.3
3 For this example, I actually break a best practice policy: don’t build packages while logged in as root.
However, I am just reviewing the basics of package building. Consider exploring the use of mock, a
system that can be used to build RPMs using a regular user account rather than the root account.
Exploring Java Installation and Basics 145
dovecot-2.2.10-CVE_2014_3430.patch dovecot.tmpfilesd
dovecot-2.2.10.tar.gz prestartscript
[root@localhost ~]# ls rpmbuild/SPECS
dovecot.spec
Your source code is stored in the SOURCES directory. The spec file is used to define how to
install the software. As you can tell from the following output, this file can be quite large:
[root@localhost ~]# wc -l rpmbuild/SPECS/dovecot.spec
1849 rpmbuild/SPECS/dovecot.spec
Yes, the spec file for the dovecot package is 1,849 lines long. Not all spec files will be this large
(although some will be larger). Spec files are a large topic by themselves. However, they are
much like BASH shell scripts, so if you read a few existing spec files, you should be able to
figure out how to create your own (or modify an existing spec file).
After your source files are in the correct directory and you have created a spec file, you can
build your package using the following command:
rpmbuild -ba ~/rpmbuild/SPECS/name.spec
This command creates two new subdirectories: RPMS and SRPMS. In those directories will be
your package’s RPM files.
If Java isn’t installed, you can use the apt-get command on Debian-based systems to install it.
The package name for Java on Debian-based systems is openjdk-X.X.X.jdk (X.X.X represents
the version number).
If Java isn’t installed on a Red Hat–based system, you can use the yum command to install it.
The package name for Java on Debian-based systems is java-X.X.X-openjdk.
Programming Humor
Real programmers count from 0!
Summary
This chapter introduced some key concepts and features of Linux that are related to
programming in C, C++, and Java. You learned how library files are managed and how to
package software for distribution. You should also now know how to determine whether
Java is installed and, if not, how to install a version of Java.
IV
Using Git
One of the biggest headaches that developers must deal with is different
versions of source code. Sometimes you just need to “go back” to a
previous version of code. Maintaining these versions manually can be
cumbersome and time consuming.
Compounding the problem is when multiple programmers work together
on a single piece of source code. A large program can be tens of
thousands of lines of code with different programmers responsible
for different portions of the code.
Version control software like Git can handle the complicated task of
maintaining different versions of source code.
This page intentionally left blank
12
Git Essentials
This chapter introduces you to Git, including how to install the necessary software to access Git
servers where your software project will be stored.
This generation of version control software made use of a technique called file locking.
When a developer checked out a file, it was locked and no other developer could edit the file.
Figure 12.1 illustrates the concept of this type of version control.
Examples of first-generation version control software include Revision Control System (RCS)
and Source Code Control System (SCCS).
■ Only one developer can work on a file at a time. This results in a bottleneck in the
development process.
■ Developers have to log in directly to the system that contains the version control
software.
These problems were solved in the second generation of version control software. In the second
generation, files are stored on a centralized server in a repository. Developers can check out
150 Chapter 12 Git Essentials
separate copies of a file. When the developer completes work on a file, the file is checked in to
the repository. Figure 12.2 illustrates the concept of this type of version control.
Local Computer
File Version 3
File Version 2
File Version 1
File
Version Database
Version 3
Version 2
Computer B Version 1
File
If two developers check out the same version of a file, then the potential for issues exists. This
is handled by a process called a merge.
What Is a Merge?
Suppose two developers, Bob and Sue, check out version 5 of a file named abc.txt. After
Bob completes his work, he checks the file back in. Typically, this results in a new version of
the file, version 6.
Sometime later, Sue checks in her file. This new file must incorporate her changes and Bob’s
changes. This is accomplished through the process of a merge.
Version Control Concepts 151
Depending on the version control software that you use, there could be different ways to
handle this merge. In some cases, such as when Bob and Sue have worked on completely dif-
ferent parts of the file, the merge process is very simple. However, in cases in which Sue and
Bob worked on the same lines of code in the file, the merge process can be more
complex. In those cases, Sue will have to make decisions, such as whether Bob’s code
or her code will be in the new version of the file.
After the merge process completes, the process of committing the file to the repository
takes place. To commit a file essentially means to create a new version in the repository;
in this case, version 7 of the file.
Server
Version Database
Version 3
Version 2
Version 1
Host A Host B
File File
Version 3 Version 3
Version 2 Version 2
Version 1 Version 1
Another (very big) difference between the second and third generation of version control
software has to do with how the merge and commit process works. As previously mentioned,
the steps in the second generation are to perform a merge and then commit the new version
to the repository.
With third-generation version control software, files are checked in and then they are merged.
To understand the difference between these two techniques, first look at Figure 12.4.
Phase 1 Phase 2
file-ver1 file-ver1
file-ver2 file-ver2
file-ver3 file-ver3
basever3 basever3 basever3 basever3
file-ver4
Phase 3 Phase 4
file-ver1 file-ver1
file-ver2 file-ver2
file-ver3 file-ver3
basever3
file-ver4 file-ver4
In phase 1 of Figure 12.4, two developers check out a file that is based on the third version. In
phase 2, one developer checks that file in, resulting in a version 4 of the file.
In phase 3 the second developer must first merge the changes from his checked-out copy with
the changes of version 4 (and, potentially, other versions). After the merge is complete, the new
version can be committed to the repository as version 5.
If you focus on what is in the repository (the center part of each phase), you will see that there
is a very straight line of development (ver1, ver2, ver3, ver4, ver5, and so on). This simple
approach to software development poses some potential problems:
Version Control Concepts 153
A better, although arguably more complex, technique can be employed. It is called Directed
Acyclic Graph (DAG), and you can see an example of how it works in Figure 12.5.
Phase 1 Phase 2
file-ver1 file-ver1
file-ver2 file-ver2
file-ver3 file-ver3
basever3 basever3 basever3 basever3
file-ver4
Phase 3 Phase 4
file-ver1 file-ver1
file-ver2 file-ver2
file-ver3 file-ver3
basever3
file-ver4 file-ver4
file-ver6
file-ver5 file-ver5
Phases 1 and 2 are the same as shown in Figure 12.4. However, note that in phase 3 the second
“check in” process results in a version 5 file that is not based on version 4, but rather indepen-
dent of version 4. In phase 4 of the process, versions 4 and 5 of the file have been merged to
create a version 6.
154 Chapter 12 Git Essentials
Although this process is more complex (and, potentially, much more complex if you have
a large number of developers), it does provide some advantages over a “single line” of
development:
■ Developers can commit their changes on a regular basis and not have to worry about
merging until a later time.
■ The merging process could be delegated to a specific developer who has a better idea of
the entire project or code than the other developers have.
■ At any time, the project manager can go back and see exactly what work each individual
developer created.
Certainly an argument exists for both methods. However, keep in mind that this book focuses
on Git, which uses the Directed Acyclic Graph method of third-generation version control
systems.
Installing Git
You might already have Git1 on your system because it is sometimes installed by default (or
another administrator might have installed it). If you have access to the system as a regular
user, you can execute the following command to determine whether you have Git installed:
ocs@ubuntu:~$ which git
/usr/bin/git
If Git is installed, then the path to the git command is provided, as shown in the preceding
command. If it isn’t installed, then you either get no output or an error like the following:
[ocs@centos ~]# which git
/usr/bin/which: no git in (/usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/local/sbin:/usr/
bin:/usr/sbin:/bin:/sbin:/root/bin)
As an administrator on a Debian-based system, you could use the dpkg command to determine
whether the git package has been installed:
root@ubuntu:~# dpkg -l git
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 git 1:1.9.1-1ubun amd64 fast, scalable, distributed
➥revision con
1 When I refer to Git with a capital I, I am referring to the software project. When I refer to git with a
lowercase g and in code font, I am referring to either the command or the software package (most
often the command).
Git Concepts and Features 155
As an administrator on a Red Hat–based system, you could use the rpm command to determine
whether the git package has been installed:
[root@centos ~]# rpm -q git
git-1.8.3.1-6.el7_2.1.x86_64
If Git isn’t installed on your system, you must either log in as the root user or use sudo or su to
install the software. If you are logged in as the root user on a Debian-based system, you can use
the following command to install Git:
apt-get install git
If you are logged in as the root user on a Red Hat–based system, you can use the following
command to install Git:
yum install git
Git Stages
It is very important to remember that you “check out”3 an entire project and that most of the
work you do will be local to the system that you are working on. The files that you check out
will be placed in a directory under your home directory.
To get a copy of a project from a Git repository, you use a process called cloning. Cloning doesn’t
just create a copy of all the files from the repository; it actually performs three primary functions:
■ Creates a local repository of the project under the project_name/.git directory in your
home directory. The files of the project in this location are considered to be “checked
out” from the central repository.
2 It appears that all those Linux “jokes” have rubbed off on me.
3 I use parentheses around “check out” because in Git the process is really called cloning. However,
some developers who are used to second-generation version control software are more comfortable with
the term “check out.” I tend to use the terms interchangeably when initially explaining the Git process.
156 Chapter 12 Git Essentials
■ Creates a directory where you can directly see the files. This is called the working area.
Changes made in the working area are not immediately version controlled.
■ Creates a staging area. The staging area is designed to store changes to files before you
commit them to the local repository.
This means that if you were to clone a project called Jacumba, the entire project would be
stored in the Jacumba/.git directory under your home directory. You should not attempt
to modify these directly. Instead, look directly in the ~/Jacumba directory and you will see
the files from the project. These are the files that you should change.
Suppose you made a change to a file, but you have to work on some other files before you were
ready to commit changes to the local repository. In that case, you would stage the file that you
have finished working on. This would prepare it to be committed to the local repository.
After you make all changes and stage all files, then you commit them to the local repository.
See Figure 12.6 for a visual demonstration of this process.
Stage Fixes
Commit
Realize that committing the staged files only sends them to the local repository. This means
that only you have access to the changes that have been made. The process of “checking in”
the new versions to the central repository is called a push.
I explain each of these steps in greater detail later. Consider this to be an introduction to the
concepts that will help you understand the process better when I introduce the Git commands.
It is only bad news because it means you really need to spend some time researching the pros
and cons of the different hosting organizations. For example, most don’t charge for basic
Git Concepts and Features 157
hosting but do charge for large-scale projects. Some only provide public repositories (anyone
can see your repository) whereas others allow you to create private repositories. There are many
other features to consider.
One of the features that might be high on your list is a web interface. Although you can do just
about all repository operations locally on your system, being able to perform some operations
via a web interface can be very useful. Explore the interface that is provided before making
your choice.
Consider This
I am not going to make a suggestion regarding which Git host you should use because it
really does vary based on what your needs are. Many websites provide up-to-date comparisons
between the various Git hosts, and I strongly recommend you do your homework before
deciding on one.
At the very least, I recommend considering the following:
■ https://bitbucket.org
■ http://www.cloudforge.com
■ http://www.codebasehq.com
■ https://github.com
■ http://gitlab.com
Note that I chose gitlab.com for the examples in the book. Any of the hosts in the preceding
list would have been just fine for the book; I just chose gitlab.com because it happened to be
the one I used on my last Git project.
Configuring Git
Now that you have gotten through all the theory,4 it is time to actually do something with Git.
This next section assumes the following:
■ You have installed the git or git-all software package on your system.
■ You have created an account on a Git hosting service.
The first thing you want to do is perform some basic setup. Whenever you perform a commit
operation, your name and email address will be included in the metadata. To set this informa-
tion, execute the following commands:
ocs@ubuntu:~$ git config --global user.name "Bo Rothwell"
ocs@ubuntu:~$ git config --global user.email "[email protected]"
Obviously you will replace "Bo Rothwell" with your name and "[email protected]"
with your email address. The next step is to clone your project from the Git hosting service.
Note that before cloning, only one file is in the user's home directory:
ocs@ubuntu:~$ ls
first.sh
After successful execution, notice a new directory in the user’s home directory:
ocs@ubuntu:~$ ls
first.sh ocs
If you switch to the new directory, you can see what was cloned from the repository (only one
file so far exists in the repository):
ocs@ubuntu:~$ cd ocs
ocs@ubuntu:~/ocs$ ls
README.md
Next, create a new file in the repository directory. You can either create one from scratch or
copy a file from another location:
ocs@ubuntu:~/ocs$ cp ../first.sh
Remember, anything placed in this directory is not version controlled because this is the
working directory. To put it in the local repository, you first have to add it to the staging area
and then you need to commit it to the repository:
ocs@ubuntu:~/ocs$ git add first.sh
ocs@ubuntu:~/ocs$ git commit -m "added first.sh"
[master 3b36054] added first.sh
1 file changed, 5 insertions(+)
create mode 100644 first.sh
The git add command places the file in the staging area. The git commit command takes
all the new files in the staging area and commits them to the local repository. You use the -m
option to add a message; in this case the reason for the commit was given.
It is important to highlight that no changes have been made to the repository on the server.
The git commit command only updates the local repository. You can see that the server
repository has not been modified by looking at Figure 12.7, which shows a screenshot of the
web-based interface of the current project. Notice that the original file, README.md, was pushed
to the server several days ago, but the new file, first.sh, does not have an entry.
Git Concepts and Features 159
Figure 12.7 Server repository is unchanged after executing the git commit command
Most likely you would make additional changes to your local project and then "check in"
(push) the changes to the server’s repository:
ocs@ubuntu:~/ocs$ git push -u origin master
Username for 'https://gitlab.com': borothwell
Password for 'https://[email protected]':
Counting objects: 4, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 370 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://gitlab.com/borothwell/ocs.git
12424f5..3b36054 master -> master
Branch master set up to track remote branch master from origin.
Figure 12.8 Server repository is changed after executing the git push command
160 Chapter 12 Git Essentials
At this point all changes of the files from the staging area have been updated to the local repos-
itory and the central server repository.
Git Humor
Wiser words may have never been spoken: “Commit early, commit often. A tip for version
controlling—not for relationships.”
—Anonymous
Summary
This chapter focused on the key concepts of Git. You should now understand the concepts of
version control in addition to specifics about how to perform version control with Git.
13
Manage Files with Git
Git provides a rich collection of features, but the core set of features are the ones that you are
going to use the most often. This includes commands that enable you to stage files and commit
files to the local repository, as well as create branches. This chapter focuses on these topics as
well as a few related ones.
Basic Configuration
You might want to perform several configuration operations. For example, you can set your
default editor by executing the following command:
ocs@ubuntu:~/ocs$ git config --global core.editor vi
You can view current configuration settings by executing the git config --list command:
ocs@ubuntu:~/ocs$ git config --list
user.name=Bo Rothwell
[email protected]
core.editor=editor_name
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
remote.origin.url=https://gitlab.com/borothwell/ocs.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
You can store configuration information in multiple locations. One location is in your own
home directory:
ocs@ubuntu:~/ocs$ more ~/.gitconfig
[user]
name = Bo Rothwell
email = [email protected]
[core]
editor = vi
162 Chapter 13 Manage Files with Git
An administrator can also store configuration information for all users in the /etc/gitconfig
file. The additional settings that you see when you execute the git config --list command
are either default settings or are derived from the information in the local repository.
Getting Help
Besides looking at man pages for information about git commands, you might consider
the git help command. When run with no additional arguments, the git help command
provides a synopsis of how the command should be executed followed by a summary of
git commands (config, add, clone, commit, push, and so on).
To see information about a specific command, execute git help command. For example: git
help config. This automatically puts you in the man page for that command.
git status
In Chapter 12, “Git Essentials,” you learned how to clone an existing repository from a central
repository server. You also learned the lifecycle of how local files are committed to the local
repository and then pushed to the central repository server:
2. Add the file to the staging area with the git add command.
3. Commit the file to the repository with the git commit command.
4. Push the file to the central server with the git push command.
Note
You can combine the git add and git commit commands into a single operation by using
the -a option to the git commit command.
Imagine you are working on some files one day and it’s getting late. It is Friday afternoon and
you just can’t wait for the weekend to start. On the following Monday you arrive at work and
realize you have no idea in what area you left your file. Were they added to the staging area?
All of them or just some? Did you commit any of them to the local repository?
Note
It makes a difference which directory you are in when you execute the git status command.
For example, if you are in your home directory, all the files in this directory
will be checked to see whether they are in the repository:
ocs@ubuntu:~$ git status
On branch master
Initial commit
Untracked files:
(use "git add <file>..." to include in what will be committed)
.bash_history
.bash_logout
.bashrc
.gitconfig
.lesshst
.profile
.viminfo
ocs/
nothing added to commit but untracked files present (use "git add"
➥to track)
Make sure you are in the repository directory before running this command!
If you make changes to a file and don’t add it to the staging area, then the output of the git
status command will look like the following:
ocs@ubuntu:~/ocs$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
modified: first.sh
no changes added to commit (use "git add" and/or "git commit -a")
164 Chapter 13 Manage Files with Git
Notice in the previous output the Changes not staged for commit section. The command
output also is helpful in showing you how you can stage the command with the git add
command or stage and commit with the git commit -a command.
If a file has been added to the staging area, but not committed to the local repository, then the
output of the git status command will look like the following:
ocs@ubuntu:~/ocs$ git add first.sh
ocs@ubuntu:~/ocs$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: first.sh
Changes to be committed means the modified file is in the staging area but not in the local
repository. If a file has been committed to local repository, but not committed to the central
repository server, then the output of the git status command will look like the following:
ocs@ubuntu:~/ocs$ git commit -m "demostrating status"
[master 9eb721e] demostrating status
1 file changed, 2 insertions(+), 1 deletion(-)
ocs@ubuntu:~/ocs$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
Note that nothing to commit, working directory clean means the staging area no
longer contains any files and the working directory reflects the current contents of the local
repository. Also note the message that states Your branch is ahead of 'origin/master'
by 1 commit. This makes it clear that you need to execute git push to push the contents of
the local repository to the central repository server.
Executing the git status command after successfully executing the git push command results
in the output demonstrated in the original example of this chapter as shown in Listing 13.1.
To https://gitlab.com/borothwell/ocs.git
3b36054..9eb721e master -> master
Branch master set up to track remote branch master from origin.
ocs@ubuntu:~/ocs$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: first.sh
modified: first.sh
In the output of Listing 13.2, you can see that the first.sh file is listed both as Changes to
be committed and Changes not staged for commit. Now you must make a choice:
■ Commit both versions of the file—First execute the git commit command, then
execute git add, and then execute git commit again.
■ Commit the last version of the file—First execute git add and then execute git
commit.1
1 The resulting output of this git commit command tends to cause confusion: 1 file changed,
2 insertions(+), 1 deletion(-). Because two versions of the file were staged (two
insertions), one had to be deleted before the other was committed to the repository.
166 Chapter 13 Manage Files with Git
A useful option to the git status command is the -s option, which shows a much more
condensed output:
ocs@ubuntu:~/ocs$ git status -s
M first.sh
A showmine.sh
?? hidden.sh
Each file is preceded by up to two characters. The first character indicates the status in the
staging area and the second character indicates the status in the working directory. The first.
sh file has been modified in the working directory, but you can tell that it has not been staged
yet because of the space character in front of the "M" character. Note the difference if the file is
staged:
ocs@ubuntu:~/ocs$ git add first.sh
ocs@ubuntu:~/ocs$ git status -s
M first.sh
A showmine.sh
?? hidden.sh
The A for the showmine.sh file means this is a new file that has been staged (because the A is
in the first column), but it hasn’t been committed to the repository yet. The ?? means that
hidden.sh is new and hasn’t been staged or committed yet. Any file that is up to date in the
local repository is not listed when you execute the git status -s command.
To have git commands ignore a file, create a file named .gitignore in the working directory
and place the filename to ignore inside of this file:
ocs@ubuntu:~/ocs$ touch notes
ocs@ubuntu:~/ocs$ git status -s
?? notes
ocs@ubuntu:~/ocs$ vi .gitignore #added notes as shown below:
ocs@ubuntu:~/ocs$ cat .gitignore
notes
ocs@ubuntu:~/ocs$ git status -s
?? .gitignore
Notice that you must also place the .gitignore file itself in the .gitignore file:
ocs@ubuntu:~/ocs$ git status -s
?? .gitignore
ocs@ubuntu:~/ocs$ vi .gitignore #added .gitignore as shown below:
git status 167
Note
You can also use wildcard characters (*, ?, and [range]) in the .gitignore file to match
a collection of files. For example, I like to name my own files with a .me extension. In the
.gitignore file I include the pattern *.me to have the git commands ignore all of my files.
You can use a pattern that ends with a / to indicate an entire directory.
However, this isn't critical to the topic at hand, so I opted not to show this in the main text.
In the future, if I do some "behind the scenes" commands, I will mention the commands that
I executed in a footnote. That way if you are following along, you should end up with the same
results that I do.
168 Chapter 13 Manage Files with Git
Removing Files
Suppose one day you create a file purely for testing purposes and then, without really thinking
about it, you commit it to the local repository:2
ocs@ubuntu:~/ocs$ git add test.sh
ocs@ubuntu:~/ocs$ git commit "update 27"
Later, you realize your mistake and want to remove the file. Simply removing it from the
working directory isn’t enough, as demonstrated in Listing 13.3.3
deleted: test.sh
no changes added to commit (use "git add" and/or "git commit -a")
Notice the suggestion to execute the git rm command, which will stage the file for removal
from the repository. See Listing 13.4 for an example of the git rm command.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: test.sh
2 This potential mistake might be the reason why you must execute git add and then git commit
for new files (you can't just execute git commit -a to add a new file).
3 However, nothing is wrong with executing a regular rm command because you probably want to delete
this file from the working directory. This just isn't going to end up removing it from the repository.
Handling Branches 169
Lastly, perform a git commit command to remove the file from the repository:
ocs@ubuntu:~/ocs$ git commit -m "deleting test.sh file"
[master 2b44792] deleting test.sh file
1 file changed, 1 deletions(-)
delete mode 100644 test.sh
Handling Branches
You decide that you want to test some new features of the project that you are working on, but
you don’t want this to impact the current development process. This is an ideal time to create
a branch.
When you first create a project, the code is associated with a branch called master. If you want
to create a new branch, execute the git branch command:
ocs@ubuntu:~/ocs$ git branch test
This doesn’t mean you are suddenly working in the new branch. As you can see from the
output of the git status command, the git branch command doesn’t change your current
branch:
ocs@ubuntu:~/ocs$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
(use "git push" to publish your local commits)
The first line of the output of the previous command, On branch master denotes that you are
still working in the master branch. To switch to the new branch, execute the git checkout
command:4
ocs@ubuntu:~/ocs$ git checkout test
Switched to branch 'test'
The second item makes more sense with a demonstration. First, observe the following
commands, which will end up with a new version of the hidden.sh file being placed in the
test branch repository:
4 You can create a branch and switch to it by using the -b option to the git checkout command:
git checkout -b test
170 Chapter 13 Manage Files with Git
Note what the file looks like in the current working directory:
ocs@ubuntu:~/ocs$ more hidden.sh
#!/bin/bash
#hidden.sh
If we switch the project back to the master branch, you can see how the hidden.sh file in
the working directory is different (note the missing echo line, which was added for the test
branch only):
ocs@ubuntu:~/ocs$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 2 commits.
(use "git push" to publish your local commits)
ocs@ubuntu:~/ocs$ more hidden.sh
#!/bin/bash
#hidden.sh
ls -ld .* $1
You can see the changes that are made on different branches, along with the comments you
provided for each change, by using the git log command:
ocs@ubuntu:~/ocs$ git log --oneline --decorate --all
ef2d7d5 (test) changed hidden.sh
2b44792 (HEAD, master) deleting test.sh file
19198d7 update 27
07bb91c (origin/master, origin/HEAD) adding showmine.sh and hidden.sh
75d717b added first.sh
9eb721e demostrating status5
3b36054 added first.sh
12424f5 add README
The--online option has the git log command provide a one-line summary of each change.
The--decorate option requests additional information such as the branch name. The--all
option asks to see the log for all branches, not just the current branch.
5 Just a side note for those of you paying close attention: the spelling error (demostrating, when it
should be demonstrating) is actually how the output of the command was displayed.
Summary 171
Pushing Branches
Recall the command to push changes to the central repository server:
git push -u origin master
Did you wonder at the time what the word master meant? You can probably guess now that it
was the branch that you were pushing to the central repository. If you wanted to push the
test branch, then you would have to execute the following command as well:6
git push -u origin test
There is more to the story of branching besides just creating a branch and switching back
and forth between branches. For example, at some point you might want to merge files from
branches together. You might also want to see how versions of files are different between differ-
ent branches. Chapter 14, “Manage Differences in Files” covers these topics.
Git Humor
“Be careful not to remove the branch you're standing on."
—Anonymous
Summary
After reading this chapter, you should have a firm understanding of how the working directory,
staging area, and local repository work. You should also know how to determine which of these
locations a file is currently "in" as well as how to specify files that the git commands should
ignore. You should understand the basics of branching, including how to create branches,
switch between branches, add/commit in different branches, and push different branches to
the central repository server.
6 If are following along, you should know that I did execute both git push commands to update the
master and test branch. I use this data in Chapter 14 examples.
This page intentionally left blank
14
Manage Differences in Files
Typically, developers love writing code. Unfortunately, writing code is not the only responsibility
of software developers. Searching for differences between two versions of source code files and
merging them into a new version is a major part of writing code.
The Git software tries to make this process easier by providing you with tools that display the
difference between files and help you merge files together. These tools are the focus of this chapter.
Executing Diffs
You arrive at work Monday morning, ready to start on your project. Executing the git status
command when you haven't worked on the project for a while is always a good habit, so you
execute the command and discover that you have a file in the working area that hasn't been staged:
ocs@ubuntu:~/ocs$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
modified: hidden.sh
no changes added to commit (use "git add" and/or "git commit -a")
You could just stage and commit the file, but you wonder what changes were made to this file.
Maybe you didn't finish making the changes last Friday. This might pose problems, so compar-
ing the version of the file in the working directory with the version that has most recently been
committed to the local repository is best. You can do this by executing the git diff command:
ocs@ubuntu:~/ocs$ git diff hidden.sh | cat -n
1 diff --git a/hidden.sh b/hidden.sh
2 index 05151ce..714482b 100644
3 --- a/hidden.sh
174 Chapter 14 Manage Differences in Files
4 +++ b/hidden.sh
5 @@ -1,4 +1,5 @@
6 #!/bin/bash
7 #hidden.sh
8
9 +echo "Hidden files:"
10 ls -ld .* $1
The output of this command requires a bit of explaining.1 Ignore the first two lines of output
because they aren't important at this point.
Lines 3 and 4 refer to the two versions of the file. Each version is assigned a letter (a or b) to
distinguish between the two. Line 3 refers to the version that has been committed, whereas line
4 refers to the version in the working directory.
Line 5 gives “directions” on how to make the two files look the same. In this case, it is simply
saying “at line 4 of the 'a' file add line 5 of the 'b' file.” Following these directions would make the
files look the same by making the committed version look like the version in the working directory.
Lines 6–10 visually show what changes would have to take place in the committed version to
make it look like the version in the working directory. A + before a line means "add this" and
a – before a line means "remove this."
Note
The output of the git diff command is referred to as patch output. You can use this
output to patch a file (essentially, upgrade the file to the most current version). Chapter 15,
“Advanced Git Features” covers this process.
1 If you run this on your own system and don't pipe the output to the cat command, you should see
some color highlight that helps you understand the data.
Executing Diffs 175
9 -ls -ld .* $1
10 +echo "Hidden files:"
11 +ls -ldh .* $1
By default, the git diff command compares versions in the following two situations:
■ If the working directory version is different than the committed version, but only if the
working version hasn't been staged
■ If the working directory version is different than the staged version
That means if you stage a file, the git diff command won't compare the staged version
to the committed version, at least not by default. As you can see, there is no output for the
following git diff command:
ocs@ubuntu:~/ocs$ git add hidden.sh
ocs@ubuntu:~/ocs$ git diff | cat -n
To compare a staged version to a committed version, use the --staged option as shown in
Listing 14.2.
5 @@ -1,5 +1,5 @@
6 #!/bin/bash
7 -#hidden.sh
8 +#hidden.sh
9
10 echo "Hidden files:"
11 ls -ldh .* $1
Based on the output of Listing 14.3, lines 7 and 8 are different. However, they look exactly the
same. To see why they are different use the --check option:
ocs@ubuntu:~/ocs$ git diff --staged --check | cat -n
1 hidden.sh:2: trailing whitespace.
2 +#hidden.sh
The message trailing whitespace means some sort of white space characters (spaces, tabs,
and so on) are at the end of the line.2
Comparing Branches
You can also use the git diff command to compare files in different branches. For example,
to see a list of files that are different between two branches, use the following command:
ocs@ubuntu:~/ocs$ git diff --name-status master..test
M hidden.sh
In the previous git diff command, the --name-status option provides a summary of the
files that are different in the two branches. The two branches, master and test, are listed,
separated by .. characters.
To see the differences between the versions in the two branches, use the syntax shown in
Listing 14.4.
If you find the output of the git diff command to be confusing, consider using the git
difftool command:3
ocs@ubuntu:~/ocs$ git difftool hidden.sh
Note how it prompts you for the tool to use to display the differences. It also lists the tools that
could be available.4 If you want to use a different tool than the one it chooses, then execute the
command as shown in the following:
git difftool --tool=<tool> file
The output of git difftool appears in a more readable format. For example, see Figure 14.1
for the output of git difftool when you use the vimdiff command as the display tool.5
3 Note that you need to install the git-all package if you want to use the git difftool command.
4 Most likely not all of these tools are installed on your system.
5 Note that I executed git commit at this point.
178 Chapter 14 Manage Differences in Files
Merging Files
Suppose you create a new branch to add a new feature to a file as demonstrated in Listing 14.5.
After testing out this new feature (look at the last two lines of the output of Listing 14.5 to
see the new feature), you are ready to implement it in the master branch. To do this, you will
need to merge the content from the feature127 branch into the master branch. Start by
committing all changes in the feature127 branch and then switch back to the master branch:
ocs@ubuntu:~/ocs$ git commit -a -m "feature added to showmine.sh"
[feature127 2e5defa] feature added to showmine.sh
1 file changed, 5 insertions(+), 2 deletions(-)
ocs@ubuntu:~/ocs$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 3 commits.
(use "git push" to publish your local commits)
You must be in the branch that you want to merge into in order to correctly run the next
command. The following git merge command merges the changes from the feature127
branch into the master branch:
ocs@ubuntu:~/ocs$ git merge feature127
Updating 4810ca8..2e5defa
Fast-forward
showmine.sh | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
Merging Files 179
After the feature has been implemented, you may decide that the feature127 branch is no
longer necessary. To remove this branch, execute the following command:
ocs@ubuntu:~/ocs$ git branch -d feature127
Deleted branch feature127 (was 2e5defa).
This merge process can be more complex. For example, there was a separate branch named
test that was branched off an earlier version of the master branch. In the test branch, the
most recent showmine.sh script looks like the following:
ocs@ubuntu:~/ocs$ git checkout test
ocs@ubuntu:~/ocs$ more showmine.sh
#!/bin/bash
#showmine.sh
The current version of showmine.sh that has been committed to the master branch looks like
the following:
ocs@ubuntu:~/ocs$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 4 commits.
(use "git push" to publish your local commits)
ocs@ubuntu:~/ocs$ more showmine.sh
#!/bin/bash
#showmine.sh
Should you merge the changes from the master into the test branch? Or should you merge
the changes from the test branch into the master branch? Typically, if you have more
work to do in the test branch, merge the changes from the master into the test branch.
Otherwise, merge the changes from the test branch into the master branch.
The following example merges the changes from the master branch into the test branch:
ocs@ubuntu:~/ocs$ git checkout test
Switched to branch 'test'
Your branch is ahead of 'origin/test' by 1 commit.
(use "git push" to publish your local commits)
180 Chapter 14 Manage Differences in Files
You can see that the merge was not completed because the automated merge process ran into
some conflicts. You can also see these conflicts by executing the git status command:
ocs@ubuntu:~/ocs$ git status
On branch test
Your branch is ahead of 'origin/test' by 1 commit.
(use "git push" to publish your local commits)
Unmerged paths:
(use "git add <file>..." to mark resolution)
no changes added to commit (use "git add" and/or "git commit -a")
This makes it clearer that two files have conflicts, not just one. If you look at the new
showmine.sh file in the working directory, it will look something like Listing 14.6.
Essentially, the file contains the contents of each file. Rather than try to edit this file directly,
one way to handle these conflicts is to use the git mergetool command:6
ocs@ubuntu:~/ocs$ git mergetool showmine.sh
The git mergetool command displays the files using one of the diff tools. For example, using
the vimdiff tool displays as shown in Figure 14.2.7
The first time you see this output, you might be a bit overwhelmed. It isn't as bad as you might
think. To see how this works, look at Figure 14.3.
6 Note that you need to install the git-all package if you want to use the git mergetool command.
7 The vimdiff utility highlights differences using colors that are sure to give you a headache if you
look at them too long. I highly suggest executing the :diffoff! command immediately to avoid
visual problems and dizziness. However, when you want to make changes to the file, you need to turn
this feature back on by executing the :window diffthis command.
182 Chapter 14 Manage Differences in Files
Base
Local Remote
BASE is what the file looked like when the two branches were last in sync. LOCAL represents
how the file looks in the current branch (the test branch in this example). REMOTE represents
how the file looks like in the branch that is being merged into this branch (the master branch
in this example). The file at the bottom is the file that you are creating/merging.
As you can see from Figure 14.2, the first three lines of all versions of the file are identical.
If you go to the first line that differs between the LOCAL and REMOTE, you can execute the
:diffget RE command to grab the code from the REMOTE file. This would grab the echo,
read, echo, and ps commands in this example.
Suppose you want to input specific lines from one of the three files? For example, you want to
copy the last four lines of the LOCAL version into the merged area. In this case you essentially
do a copy and paste operation.
To switch to the LOCAL window, hold down the Ctrl button and then press the W key twice
(Ctrl+W+W). Then copy the four lines (go to the first line that you want to copy then type
4yy). Use Ctrl+W+W to move forward until the cursor returns to the merged copy. Then move
to where you want to make the change and press the P key.
After making all of your changes, you need to save and quit all four versions. The easiest way to
do this is the :wqa vim command.
Merge all files and then stage/commit them with the git commit -a command.8
Git Humor
"Git knows what you did last summer!"
—Anonymous
Summary
At this point you should now know how to create branches, see the difference in versions of
files, and merge files from one branch to another.
8 If you are following along, be aware that at the end of this chapter I completed the merge of all files
(including the hidden.sh file), committed all changes to the test branch, and pushed all changes
for both the test and master branch to the central repository server.
15
Advanced Git Features
At the heart of Git are the repositories. Chapters 13 and 14 introduced you to tools that
enabled you to work with the local repository. In this chapter you learn how to interact with
the central repository server.
Managing Repositories
From your perspective, the central repository server is also considered the remote repository as
opposed to the repository that is on your system (the local repository).
To see the location of your remote repository, execute the git remote -v command:
ocs@ubuntu:~/ocs$ git remote -v
origin https://gitlab.com/borothwell/ocs.git (fetch)
origin https://gitlab.com/borothwell/ocs.git (push)
Both lines point to the same location. The first line refers to the process of downloading
content from the remote repository and the second line refers to the process of uploading
content to the remote repository.
Very likely you will be working on separate projects, each with its own remote repository.
To access another project, execute the git remote add command:1
ocs@ubuntu:~/ocs$ git remote add docs
➥ https://gitlab.com/borothwell/docs.git
ocs@ubuntu:~/ocs$ git remote -v
docs https://gitlab.com/borothwell/docs.git (fetch)
docs https://gitlab.com/borothwell/docs.git (push)
origin https://gitlab.com/borothwell/ocs.git (fetch)
origin https://gitlab.com/borothwell/ocs.git (push)
The docs argument is how you want to refer to this remote repository locally. The last argu-
ment is the URL path to the remote repository.
1 I created this new project by using the web interface provided by gitlab.com.
184 Chapter 15 Advanced Git Features
Of course, after you have added the remote repository, you should also clone it using the git
clone command:
ocs@ubuntu:~/ocs$ cd ..
ocs@ubuntu:~$ git clone https://gitlab.com/borothwell/docs.git
Cloning into 'docs'...
Username for 'https://gitlab.com': borothwell
Password for 'https://[email protected]':
warning: You appear to have cloned an empty repository.
Checking connectivity... done.
ocs@ubuntu:~$ ls
docs ocs
ocs@ubuntu:~$ ls -a docs
. .. .git
Even though this is an empty repository, you can see that it has been cloned by the fact it
created a ~/docs directory and a docs/.git directory. To perform work in this project,
simply create files in the ~/docs directory and execute the git commands while in this
directory.
However, this process can become much more complex later in the development cycle when
you want to include changes from the remote server (likely from other developers) to your local
repository and working directory. You can use several different methods, each with a different
intended result.
Before getting into the process of getting content from the remote server, visualizing how
content is sent from the working directory to other locations might be helpful. Look at
Figure 15.1 for a demonstration.
Working
Add Staged Commit Local Push Remote
Directory
commit-a
Figure 15.1 Git commands to send changes from the working directory
Managing Repositories 185
In Figure 15.1 you can see the flow of version changes. The git add command sends the
working version to the staged area. The git commit command sends the staged version to the
local repository. The git commit -a command can send a version from the working directory
to the staged area and then to the local repository. Lastly, the git push command sends the
changed versions of the files to the remote repository.2
File versions cannot only be sent from the working directory up to the remote repository, but
they can also be propagated from the remote repository to the local repository and the working
directory. See Figure 15.2 for a visual description of the commands that can perform these
actions.3
Pull or Rebase
Working
Staged Local Fetch Remote
Directory
Checkout
Figure 15.2 Git commands to retrieve changes from the remote repository
■ The git fetch command downloads the latest version history of files from the
remote repository to the local repository. This command does not change your working
directory, but you can use the git checkout command to make the working directory
contain the latest versions of the files of the branch.
2 None of these commands are new because they were covered in previous chapters. However,
visualizing this process can help you understand the next topic better.
3 Note that the git clone command is not included in Figure 15.2. This is because typically you only
run this command once when you first download the remote repository.
186 Chapter 15 Advanced Git Features
Important
The git fetch command only downloads the file versions. It does not perform any merging.
■ The git pull command downloads the latest version history of files from the remote
repository to the local repository, but this command also performs a merge operation
and updates the content of your working directory. The merging process is the same as
that described in Chapter 14.
■ The git rebase command takes all the changes from a branch and applies them to
the current branch. This is a process called patching, which is described in more detail
later in this chapter.
This doesn’t mean you shouldn’t use SSH, just that the developers of Git recommend HTTPS.
If you do want to use SSH, then you first need to execute the following command:
ocs@ubuntu:~/ocs$ ssh-keygen -t rsa
This creates an SSH key in the ~/.ssh/id_rsa.pub file. You must upload this file to the SSH
server, which you normally do via the web interface. See Figure 15.3 for an example of this
interface on gitlab.com.
Patching 187
After uploading the SSH keys to the remote repository server, you can have the git command
use SSH instead of HTTP by using the following syntax:
git clone ssh://user@server/project.git
Patching
The idea of patching is that you will discover situations in which it won’t be easy to perform
a simple merge between two different branches. Several reasons exist as to why this might be,
including the following:
■ When you want to implement changes from a branch that hasn’t been made available
on the central repository
■ When you want to implement changes from a specific version of a file
Actually several different techniques can be utilized to perform patching. The most basic
(and common) method is to use the git diff command that was discussed in Chapter 14
to generate a diff file. You do this by executing the git diff command and redirecting the
output to a file. For example:
git diff A B > file.patch
This patch file will be used to modify an existing checked-out file to include the differences.
This is performed by using the git apply command. For example:
git apply file.patch
Often the patch file is generated on one system and then copied to another system before
applying. It is also typically a good idea to use the --check option to test the patch before
actually applying it:
git apply --check file.patch
git apply file.patch
188 Chapter 15 Advanced Git Features
Git Humor
“Nurture your git-twigs and they will grow into a full branch.”
—Anonymous
Summary
In this chapter you learned how to manage repositories. You also learned how to change the
method of connecting to a remote repository from HTTPS to SSH. Last, you were introduced to
the concept of patching in Git.
Index
Symbols
“ (double quotes), 124
‘ (single quotes), 124
- option (su command), 84–85
/ (forward slash)
command, 75
in paths, 29
/bin directory, 30
/home directory, 30
/media directory, 30
/root directory, 30
/sbin directory, 30
/tmp directory, 30
/usr/bin directory, 30
/usr/sbin directory, 30
/usr/share/doc directory, 27
: (colon) command, 76
; (semicolon) in Perl statements, 119
| (pipe) in redirection, 44–45
#! (sha-bang)
in bash shell scripting, 111
in Perl, 120
in Python, 132
$ (dollar sign) command, 71
( (left parenthesis) command, 72
) (right parenthesis) command, 71
* (asterisk) as wildcard, 38
190 ? (question mark)
A packages, 142–145
system libraries, 139–142
A command, 69
capitalize method, 134
a command, 69
case statements
absolute paths, 31–33
in bash shell scripting, 115, 117
adding user accounts, 91–92
in Perl, 126
aliases, 56
cat command, 49–50
append method, 135
cd command, 32–33
apt-get command, 88
change directory process, 31
apt-get install command, 91
changing permissions, 58–59
arguments (in command line), 22
chmod command, 58–59
arrays, 122–124
choosing
asterisk (*) as wildcard, 38
Linux distribution, 14–15
auto indentation in vim, 132
repository host, 156–157
awk utility, 105–107
cloning, 155
closed source, 4–5
B
cmp command, 54
B command, 71 colon (:) command, 76
b command, 71 command line
bash shell. See shell aliases, 56
/bin directory, 30 benefits of, 47–48
connecting to repositories 191
directories
creating, 36 E
-d option (ls command), 40 E command, 71
deleting, 36–37 e command, 71
listing files in, 33–35 echo command, 55, 112
managing, 36–37 ed editor, 67–68
most used, 30 editors
naming conventions, 30–31 bluefish, 82
permissions, 58 ed, 67–68
root, 29 Emacs, 79–80
filesystem. See also directories; files 193
H command, 72
h command, 71
J
hashes, 122, 124. See also dictionaries j command, 71
head command, 51 Java, 108
help command, 22–23 installing, 145–146
help documentation. See documentation packages, 142–145
hidden files, listing, 34 system libraries, 139–142
history command, 56–57 JavaScript, 103–104
/home directory, 30 joe editor, 81
HTTPS, connecting to repositories, 186–187
K
I k command, 71
I command, 69 kernel, 13
i command, 69 keys command, 124
id command, 84 kwrite editor, 81
IDEs (Integrated Development
Environments), 108–109
196 L command
M nonreusable licenses, 8
numeric comparisons in Perl,
M command, 72
126–127
man 5 passwd command, 91
numeric variables, 133–134
man command, 23–26
man pages, 23–26
O
managing
O command, 69
directories, 36–37
o command, 69
files, 37–45
octal method (changing permissions),
filesystem, 33–35
58–59
groups, 93–94
open source
software, 88
defined, 5
/media directory, 30
free software, 5–7
merge process, 150–151
licensing
merging files, 178–182
benefits of, 7
mkdir command, 36
categories of, 8
modifiers (vi editor), 72
examples, 8–9
modifying user accounts, 92 resources for information, 9
modules terminology, 8
in Perl, 129–130
open statement, 137
in Python, 138
options (in command line), 22
more command, 50–51
movement commands (vi editor), 71–72 P
multiple file locations in Git, 165–166
P command, 74
mv command, 38
p command, 74
my statement, 129
packages, 142–145
Debian, 145
N
RPM, 142–145
N command, 75 paging, 44
n command, 75 passwd command, 92
naming conventions for files and directories, passwords, complexity of, 92
30–31
pasting in vi editor, 74
nano editor, 81
patch output, 174
navigating filesystem, 31–33
patching, 186, 187
network, logging in via, 17–18
paths, 29
newline characters, 119
for bash shell scripts, 112
next statement, 126
types of, 31–33
198 Perl
T /usr/sbin directory, 30
/usr/share/doc directory, 27
tail command, 51
tar command, 61–62
Tcl/Tk, 104–105
V
terminal windows, 21 variables
in Perl, 125
patching, 187
removing files, 168–169
user accounts, 91
resources for information, 162
adding, 91–92
retrieving content from remote
deleting, 93
repository, 184–186
modifying, 92
stages, 155–156
user interaction in bash shell scripting,
second generation software, 149–151
117–118
third generation software, 151–154
useradd command, 91
vi editor
userdel command, 93
benefits of, 68
usermod command, 92, 93
copying in, 73
/usr/bin directory, 30
zypper install command 203
W
Z
W command, 71
zero (0) command, 71
w command, 71
zypper command, 88
Wall, Larry, 130
zypper install command, 91
wc command, 51–52
This page intentionally left blank
REGISTER YOUR PRODUCT at informit.com/register
%GGIWW%HHMXMSREP&IRI½XWERH7%:) SR=SYV2I\X4YVGLEWI
• Download available product updates.
• Access bonus material when applicable.
• Receive exclusive offers on new editions and related products.
(Just check the box to hear from us when setting up your account.)
• Get a coupon for 35% for your next purchase, valid for 30 days. Your code will
be available in your InformIT cart. (You will also find it in the Manage Codes
section of your account page.)
Registration benefits vary by product. Benefits will be listed on your account page
under Registered Products.
-RJSVQ-8GSQ¯8LI8VYWXIH8IGLRSPSK]0IEVRMRK7SYVGI
InformIT is the online home of information technology brands at Pearson, the world’s foremost
education company. At InformIT.com you can
• Shop our books, eBooks, software, and video training.
• Take advantage of our special offers and promotions (informit.com/promotions).
• Sign up for special offers and content newsletters (informit.com/newsletters).
• Read free articles and blogs by information technology experts.
• Access thousands of free chapters and video lessons.
'SRRIGX[MXL-RJSVQ-8¯:MWMXMRJSVQMXGSQGSQQYRMX]
Learn about InformIT community events and programs.
Addison-Wesley • Cisco Press • IBM Press • Microsoft Press • Pearson IT Certification • Prentice Hall • Que • Sams • VMware Press
Developer’s Library
ESSENTIAL REFERENCES FOR
PROGRAMMING PROFESSIONALS