LPI Linux Certification in a Nutshell (12 page)

Read LPI Linux Certification in a Nutshell Online

Authors: Adam Haeder; Stephen Addison Schneiter; Bruno Gomes Pessanha; James Stanger

Tags: #Reference:Computers

BOOK: LPI Linux Certification in a Nutshell
4.5Mb size Format: txt, pdf, ePub
Entering commands not in the PATH

Occasionally, you will need to execute a command that is not in
your path and not built into your shell. If this need arises often, it
may be best to simply add the directory that contains the command to
your path. However, there’s nothing wrong with explicitly specifying a
command’s location and name completely. For example, the
ls
command is located in
/bin
. This directory is most certainly in your
PATH
vari
able (if not, it should be!), which
allows you to enter the
ls
command by itself on
the command line:

$
ls

The shell looks for an executable file named
ls
in each successive directory listed in your
PATH
variable and will execute the
first one it finds. Specifying the literal pathname for the command
eliminates the directory search and yields identical results:

$
/bin/ls

Any executable file on your system may be started in this way.
However, it is important to remember that some programs may have
requirements during execution about what is listed in your
PATH
. A program can be launched normally but
may fail if it is unable to find a required resource due to an
incomplete
PATH
.

Entering multiple-line commands interactively

In addition to its interactive capabilities, the shell
also has a complete programming language of its own. Many programming
features can be very handy at the interactive command line as well.
Looping constructs, including
for
,
until
, and
while
, are often used this way. (Shell
syntax is covered in more detail in
Chapter 13
.) When you begin
a command such as these, which normally spans multiple lines,
bash
prompts you for the subsequent lines until a
valid command has been completed. The prompt you receive in this case
is stored in shell variable PS2, which by default is
>
. For example, if you wanted to
repetitively execute a series of commands each time with a different
argument from a known series, you could enter the following:

$
var1=1
$
var2=2
$
var3=3
$
echo $var1
1
$
echo $var2
2
$
echo $var2
3

Rather than entering each command manually, you can
interactively use
bash
’s
for
loop construct to do the work for you.
Note that indented style, such as what you might use in traditional
programming, isn’t necessary when working interactively with the
shell:

$
for var in $var1 $var2 $var3
>
do
>
echo $var
>
done
1
2
3

You can also write this command on one line:

$
for var in $var1 $var2 $var3; do echo $var; done
1
2
3

The semicolons are necessary to separate the variables from the
built-in bash
functions
.

Entering command sequences

There may be times when it is convenient to place
multiple commands on a single line. Normally,
bash
assumes you have reached the end of a
command (or the end of the first line of a multiple-line command) when
you press Enter. To add more than one command to a single line,
separate the commands and enter them sequentially with the
command separator
, a semicolon.
Using this syntax, the following commands:

$
ls
$
ps

are, in essence, identical to and will yield the same result as
the following single-line command that employs the command
separator:

$
ls ; ps

On the Exam

Command syntax and the use of the command line are very
important topics. Pay special attention to the use of options and
arguments and how they are differentiated. Also be aware that some
commands expect options to be preceded by a
dash, whereas other commands do not. The LPI exams do
not concentrate on command options, so don’t feel like you need to
memorize every obscure option for every command before taking the
exams.

Command History and Editing

If you consider interaction with the shell as a kind of
conversation, it’s a natural extension to refer back to things
“mentioned” previously. You may type a long and complex command that you
want to repeat, or perhaps you need to execute a command multiple times
with slight variation.

If you work interactively with the original Bourne shell,
maintaining such a “conversation” can be a bit difficult. Each
repetitive command must be entered explicitly, each mistake must be
retyped, and if your commands scroll off the top of your screen, you
have to recall them from memory. Modern shells such as
bash
include a significant feature set called
command history
,
expansion
,
and
editing
. Using these capabilities, referring
back to previous commands is painless, and your interactive shell
session becomes much simpler and more effective.

The first part of this feature set is command history. When
bash
is run interactively, it provides access to a
list of commands previously typed. The commands are stored in the
history list
prior
to any interpretation by the
shell. That is, they are stored before wildcards are expanded or command
substitutions are made. The history list is controlled by the
HISTSIZE
shell variable. By default,
HISTSIZE
is set to 1,000 lines, but you can
control that number by simply adjusting
HISTSIZE
’s value. In addition to commands
entered in your current
bash
session, commands from
previous
bash
sessions are stored by default in a
file called
~/.bash_history
(or the file named in
the shell variable
HISTFILE
).

Note

If you use multiple shells in a windowed environment (as just
about everyone does), the last shell to exit will write its history to
~/.bash_history
. For this reason you may wish to
use one shell invocation for most of your work.

To view your command history, use the
bash
built-in
history
command. A line number will
precede each command. This line number may be used in subsequent
history expansion
. History expansion
uses either a line number from the history or a portion of a previous
command to re-execute that command. History expansion also allows a fair
degree of command editing using syntax you’ll find in the
bash
documentation.
Table 6-1
lists the basic
history expansion designators. In each case, using the designator as a
command causes a command from the history to be executed again.

Table 6-1. Command history expansion designators

Designator

Description

!!

Spoken as
bang-bang
, this command refers to the most
recent command. The exclamation point is often called
bang
on Linux and Unix
systems.

!
n

Refer to command
n
from the history. Use the
history
command to display these
numbers.

!-
n

Refer to the current command minus
n
from the history.

!
string

Refer to the most recent command
starting with
string
.

!?
string

Refer to the most recent command
containing
string
.

^
string1
^
string2

Quick substitution. Repeat the last
command, replacing the first occurrence of
string1
with
string2
.

While using history
substitution can be useful for executing repetitive
commands, command history editing is much more interactive. To envision
the concept of command history editing, think of your entire
bash
history (including that obtained from your
~/.bash_history
file) as the contents of an
editor’s buffer. In this scenario, the current command prompt is the
last line in an editing buffer, and all of the previous commands in your
history lie above it. All of the typical editing features are available
with command history editing, including movement within the “buffer,”
searching, cutting, pasting, and so on. Once you’re used to using the
command history in an editing style, everything you’ve done on the
command line becomes available as retrievable, reusable text for
subsequent commands. The more familiar you become with this concept, the
more useful it can be.

By default,
bash
uses
key bindings
like those found in the
Emacs editor for command history editing. (An editing style similar to
the
vi
editor is also available.) If you’re
familiar with Emacs, moving around in the command history will be
familiar and very similar to working in an Emacs buffer. For example,
the key command Ctrl-p (depicted as
C-p
) will move up one line in your command
history, displaying your previous command and placing the cursor at the
end of it. This same function is also bound to the up-arrow key. The
opposite function is bound to
C-n
(and the down arrow). Together, these two key bindings allow you to
examine your history line by line. You may re-execute any of the
commands shown simply by pressing Enter when it is displayed. For the
purposes of Exam 101, you’ll need to be familiar with this editing
capability, but detailed knowledge is not required.
Table 6-2
lists some of the
common Emacs key bindings you may find useful in
bash
. Note that
C-
indicates the Ctrl key, and
M-
indicates the
Meta key, which is usually Alt on PC keyboards (since PC
keyboards do not actually have a Meta key).

Note

In circumstances where the Alt key is not available, such as on
a terminal, using the Meta key means pressing the Escape (Esc) key,
releasing it, and then pressing the defined key. The Esc key is not a
modifier, but applications will accept the Esc key sequence as
equivalent to the Meta key.

Table 6-2. Basic command history editing Emacs key bindings

Key

Description

C-p

Previous line (also up
arrow)

C-n

Next line (also down
arrow)

C-b

Back one character (also left
arrow)

C-f

Forward one character (also right
arrow)

C-a

Beginning of line

C-e

End of line

C-l

Clear the screen, leaving the current
line at the top of the screen

M-<

Top of history

M->

Bottom of history

C-d

Delete character from
right

C-k

Delete (kill) text from cursor to end
of line

C-y

Paste (yank) text previously cut
(killed)

M-d

Delete (kill) word

C-r
text

Reverse search for
text

C-s
text

Forward search for
text

Command substitution

bash
offers a handy ability to do
command substitution
. This feature allows you to
replace the result of a command with a script. For example, wherever
$(
command
)
is found, its output will be substituted.
This output could be assigned to a variable, as in the system
information returned by the command
uname
–a
:

$
SYSTEMSTRING=$(uname -a)
$
echo $SYSTEMSTRING
Linux linuxpc.oreilly.com 2.6.24.7-92.fc8 #1 SMP Wed May 7 16:50:09 \
EDT 2008 i686 athlon i386 GNU/Linux

Another form of command substitution is
`
command
`
. The result is the same, except that the
back quote
(or
backtick
)
syntax has some special rules regarding
metacharacters
that the
$(
command
)
syntax avoids. Refer to the
bash
manual at
http://www.gnu.org/software/bash/manual/
for more
information.

Applying commands recursively through a directory tree

There are many times when it is necessary to execute commands
recursively
. That is, you may need
to repeat a command throughout all the branches of a directory tree.
Recursive execution is very useful but also can be dangerous. It gives
a single interactive command the power to operate over a much broader
range of your system than your current directory, and the appropriate
caution is necessary. Think twice before using these capabilities,
particularly when operating as the superuser.

Some of the GNU commands on Linux systems have built-in
recursive capabilities as an option. For example,
chmod
modifies permissions on files
in the current
directory
:

$
chmod g+w *.c

In this example, all files with the
.c
extension in the current directory are given the group-write
permission. However, there may be a number of directories and files in
hierarchies that require this change.
chmod
contains the
-R
option (note the uppercase option
letter; you may also use
--recursive
), which
instructs the command to operate not only on files and directories
specified on the command line, but also on all files and directories
contained
beneath
the specified directories. For
example, this command gives the group-write permission to all files in
a source-code tree named
/home/adam/src
:

$
chmod -R g+w /home/adam/src

Provided you have the correct privileges, this command will
descend into each subdirectory in the
src
directory and add the requested permission to each file and directory
it finds. Other example commands with this ability include
cp
(copy),
ls
(list files), and
rm
(remove files).

A more general approach to recursive execution through a
directory is available by using the
find
command.
find
is inherently recursive and is intended to
descend through directories executing commands or looking for files
with certain attributes. At its simplest,
find
displays an entire directory hierarchy when you simply enter the
command and provide a single argument of the target directory. If no
options are given to
find
, it prints each file it
finds, as if the option
-print
were
specified:

$
find /home/adam/src
...files and directories are listed recursively...

As an example of a more specific use, add the
-name
option to search the same directories for C
files (this can be done recursively with the
ls
command as well):

$
find /home/adam/src -name "*.c"
....c files are listed recursively...

find
also can be used to execute commands
against specific files by using the
-exec
option.
The arguments following
-exec
are taken as a
command to run on each
find
match. They must be
terminated with a semicolon (
;
),
which needs to be
escaped
(
\;
, for example) because it is a
shell metacharacter. The string
{}
is replaced with the filename of the current match anywhere it is
found in the command.

To take the previous example a little further, rather than
execute
chmod
recursively against all files in
the
src
directory,
find
can
execute it against the C files only, like this:

$
find /home/adam/src -name "*.c" -exec chmod g+w {} \;

The
find
command is capable of much more
than this simple example and can locate files with particular
attributes such as dates, protections, file types, access times, and
others. Although the syntax can be confusing, the results are worth
some study of
find
.

Other books

Memoirs of an Emergency Nurse by Nicholl, Elizabeth
Werewolf in Denver by Vicki Lewis Thompson
Billingsgate Shoal by Rick Boyer
Dying Is My Business by Kaufmann, Nicholas
Rexanne Becnel by The Bride of Rosecliffe
Tanked: TANKED by Lewis, Cheri
Stained by Cheryl Rainfield