Novell Certified Linux Professional Exam: Preliminary GNU and Unix Commands
The NCLP practicum requires you to have a mastery of SuSE Linux Enterprise Server. Before you can have a mastery of any one specific implementation, however, you must first know and understand the basics of the operating system. This chapter does not focus on any specific testing objectives for the practicum, but provides you with the core set of skills that you must know in order to be able to work effectively with any Linux implementation.
This chapter covers the following course objectives:
-
Accessing the Command Line (3036)
-
Introduction to Command Shells (3036)
-
Understanding Command Syntax and Special Characters (3036)
-
Executing Commands at the Command Line (3036)
-
Common Command Line Tasks (3036)
-
Piping and Redirection (3036)
-
Changing Directories and Listing Directory Contents (3036)
-
Creating, Viewing, and Appending Files (3036)
-
Copying and Moving Files and Directories (3036)
-
Creating Directories (3036)
-
Deleting Files and Directories (3036)
-
Using grep to Search File Content (3036)
-
Understanding Regular Expressions (3036)
-
Introduction to Linux Text Editors (3036)
-
Using Command Line Editors to Edit (3036)
-
Using Desktop Editors to Edit Files in the Linux System (3036)
-
View Processes from the GUI and the Command Line Interface (3036)
-
Multiuser Processes and Multitasking in the Linux System (3036)
-
Monitor Processes (3038)
This chapter contains a great deal of content, and it is imperative that you understand and are comfortable with all of it before moving on. It cannot be stressed enough that the commands, utilities, and skills discussed in this chapter lay the foundation upon which all Linux administration is built.
Working at the Command Line
Course Objectives Covered
-
Accessing the Command Line (3036)
-
Introduction to Command Shells (3036)
-
Understanding Command Syntax and Special Characters (3036)
-
Executing Commands at the Command Line (3036)
-
Common Command Line Tasks (3036)
-
Piping and Redirection (3036)
To understand the command line and work there effectively, you must understand the processes that are taking place. Within Linux, the shell is the command interpreter. It takes commands that a user gives, processes them (or sends them to the appropriate utility/interacts with the kernel), and formats the finished results for the user. Thus, the shell is the mediator between the operating system and the user. Not only can it interpret commands, but it can also handle redirection (input and output), filename generation, some programming, variable substitution, piping, and a host of other services.
A number of different shells (interpreters) are available, and different vendors include different combinations of choices with their operating systems. The simplest of all is the Bourne shell (sh), which is one of the earliest ones created for the Unix platform and offers the smallest number of features. The Korn shell (ksh) was one of the first to expand upon, and deviate from, sh, and it includes a larger number of options. The Bourne Again shell (bash) took many of the features from Korn, and some new ones, and combined them with sh, while trying to reduce deviations. The Z shell (zsh) is the largest shell of all and added a whole new set of features to the Korn shell.
Not to be overlooked are shells created to make the environment more friendly to those familiar with the C programming language. The first of these was the C shell (csh), which added C-like features to the interpreter and deviated greatly from the Bourne shell. It has been expanded upon by Tom's C shell (tcsh) .
As a generalization, every vendor includes more than one shell for the user to choose from, but rarely do they include all the available shells. In many versions, there are three prevalent shells:
-
bash
-
tcsh
-
zsh
Additionally, there are often two links within the operating system so that if a user attempts to use sh, they are really given bash, and if they attempt to use csh, they are really given tcsh.
NOTE
All shells reside in the /bin directory and the default can be specified for the user in the user's /etc/passwd file entry.
There are slight deviations in the way each shell carries out its tasks, but all perform a core set of functions. Throughout this section, we will look at the core functions for all shells and discuss differences as they apply.
Command-Line Interaction
When a command is entered, the shell must determine if the command is for it (internal) or not (external). If the command is an internal one, it does the processing and sends the output back without further interaction being needed. If the command cannot be found within the shell itself, it is assumed to be an external utility (such as ls, cat, cal, and so on). The command syntax for external commands is always assumed to be
{program name} {option(s)} {argument(s)}
Although it is always assumed that there are three components to the command, there need not be. The simplest command to give is simply the name of the utility, for example:
ls
This will return an output similar to
Desktop sample snapshot01.gif snapshot02.gif
In this case, only the program name was given, and no options. This results in a listing of all files within the present directory being shown in the default format. An option can be specified to change the display to include/exclude information and/or change the format of the display. An example would be
ls -l
This changes the output to
total 34 drwx------ 5 root root 1024 Jul 19 16:34 Desktop -rw-r--r-- 1 root root 155 Jul 19 16:48 sample -rw-r--r-- 1 root root 12497 Jul 19 16:39 snapshot01.gif -rw-r--r-- 1 root root 17257 Jul 19 16:50 snapshot02.gif
Here, the program name has been specified (ls), as well as an option to use with it (-l) to change the listing to the "long" format.
NOTE
It is important to understand that whitespace must always be used to separate the parameters from one another. Whitespace can be either a space character or a tab character.
If the command were given as ls-l, an error message would be generated because there is no utility by the name of ls-l, and the interpreter would not be able to distinguish the program name from the option.
The options, as well as the arguments, are optional and never required. To complete the example, an argument can also be used with the command:
ls -l *.gif
This will result in the following display:
-rw-r--r-- 1 root root 12497 Jul 19 16:39 snapshot01.gif -rw-r--r-- 1 root root 17257 Jul 19 16:50 snapshot02.gif
NOTE
Alternatively, the argument can be used without the options, like this:
ls *.gif
The number of arguments that can be given is not limited to one. Although there may be limitations on the number of parameters an individual utility will accept, typically you can string multiple requests together. For example, instead of specifying
ls -l sa*
as one command and then following it with
ls -l *.gif
you can accomplish the same operation with
ls -l sa* *.gif
The result of the operation becomes
-rw-r--r-- 1 root root 155 Jul 19 16:48 sample -rw-r--r-- 1 root root 12497 Jul 19 16:39 snapshot01.gif -rw-r--r-- 1 root root 17257 Jul 19 16:50 snapshot02.gif
If the number of arguments you are giving becomes too long to be easily readable on the command line, or if you simply want to break up the entry a bit, you can use the backstroke character to signify that you are continuing from one line to the next. For example
ls -l sa* \ *.gif
If you were giving hundreds of such arguments, you would use the backstroke following each entry to separate each. This would make entry easier to view and the command would not execute until the Enter key is pressed without being preceded by a backstroke. For example
ls -l sa* \ *.gif \ *.ead \ *.txt \ *.doc
Connecting Commands
In all the examples thus far, the Enter key is used to inform the shell that you have given a command that needs to be processed. You are not, however, limited to giving the shell only one command at a time.
Multiple commands, not connected to one another in any way, can be given on the same line as long as the semicolon (;) is used to connect them. For example, it is possible to see all the files in the current directory and the current date by giving the following two commands in succession:
ls date
These are unrelated commands in that the output of the second has absolutely nothing to do with the output of the first. You can combine them on a single command line with a semicolon between the two and get the same result:
ls ; date
The semicolon is a special character signaling that multiple commands are on the same line. This character allows you to break the whitespace rule on both sides of it (ls;date) while giving you the same result.
If the commands do have something in commonthe output of one is to become the input of the nextthey are connected using a pipe (|). For example, if a list of files within a directory is too long to fit on one screen, you can view a screen at a time by using this command:
ls -l | more
Here the output of the ls -l command becomes the input of the more command. If the first part of the entire command line fails, the second part cannot possibly be executed.
Wildcards
Wildcards are characters used to signify other characters that the shell fills in. The two most common wildcard characters are the asterisk (*) and question mark (?). Although they are often confused, their meanings are different and can lead to completely different results.
The asterisk is used to signify any and all; anything and nothing; alpha and omega. For example
ls s*
will find all entries (files and directories) within the current directory starting with the letter "s" and having any number of characters followingincluding none. Possible results it could generate in the display include
s sa sam samp sampl sample samples samples.gif
Note that it finds "s" alone, and "s" with any number of entries following it. In contrast, the question mark is a placeholder for one character, and only one character. Using the same file possibilities, the following command
ls s?
will only find entries (files and directories) in the current directory starting with the letter "s" and having only one character following. The resulting display generated is
sa
If you want to find only five-letter entries beginning with "s", the command to use would be
ls s????
To recap, the asterisk means all or none, and the question mark always means one. These two wildcards are not mutually exclusive, and can be used in combination with one another as the need arises. For example, to find only files with three-letter extensions, regardless of the filename, the command would be
ls *.???
To muddy the waters a bit, you can also use brackets ([]) to specify possible values. All the possible values must reside within the brackets and are used individually. The following example will find all entries that start with either "d" or "e" and have an unlimited number of characters following:
ls [de]*
To find only three-character entries that start with "d" or "e", the command would become
ls [de]??
The number of characters within the brackets can be virtually unlimited. Therefore, if you wanted to find all entries that start with a lowercase letter instead of a number (or other character), you could use "[abcdefghijklmnopqrstuvwxyz]". However, because this is a range, a much simpler way to signify it would be "[a-z]":
ls [a-z]*
The ranges need not be a complete set (though complete sets are easier to specify), and can jump around if needed. For example, if you only want to look for entries that fall within the range from "d" to "t", you could use either "[defghijklmnopqrst]" or "[d-t]". If the entry could be between the two values upper- and lowercase, you can either use "[DEFGHIJKLMNOPQRSTdefghijklmnopqrst]" or "[D-Td-t]".
Some more examples follow:
-
All letters (upper- and lowercase): [A-z]
-
All numbers [0-9]
-
All letters and numbers [A-z0-9]
-
Not a number [!0-9]
-
Not a letter [!A-z]
NOTE
"[A-z]" is the same as saying "[A-Z]" and "[a-z]".
The Path Statement and Other Variables
When you enter a command at the command prompt and the shell cannot find it internally, it must look for a utility by that name externally. It does this by searching directories specified in the PATH variable, in the order they are listed, until it finds the first match. If no match is found after all listed directories have been searched, the result is an error message ("command not found").
There are several important things to know about the path:
-
You can view your path by using the echo command:
-
The path does not, by default, include the present directory. Thus you can create an executable file in your home directory, see it right before you (with ls), and when you type its name, you will be told that the command cannot be found. To circumvent this, you can give the full path to the file, add your home directory to your PATH variable, move the file to a directory in the path statement, or add the present directory variable (.) to the PATH variable.
-
Entries within the path are separated by colons (:).
-
The order of the PATH search should always include the most common directories where executables can be found first (the bin directories) and the user-specific directories (if any) at the end.
echo $PATH
To add another directory to your path, you can redefine the entire statement, or simply append the new directory with the command
PATH=$PATH:{new directory}
Thus to add the directory /home/edulaney to the path, the command would be
PATH=$PATH:/home/edulaney
Or you can add a variable that signifies you always want the directory you are currently working in to be searched for the utility:
PATH=$PATH:./
NOTE
For security reasons, it is always recommended that you not include the current directory in your path. If you must do so, however, it should be at the end of the PATH statementas shown in the preceding examplenot at the beginning.
For example, if your current PATH is equal to
/sbin:/usr/sbin:/usr/local/sbin:/root/bin:/usr/local/bin:/ usr/bin
then you want the new PATH to look like
/sbin:/usr/sbin:/usr/local/sbin:/root/bin:/usr/local/bin:/ usr/bin:./
and not
./:/sbin:/usr/sbin:/usr/local/sbin:/root/bin:/usr/local/bin:/usr/bin
because the directories are always searched in the order they appear in PATH.
Common Variables
Any variable that exists can display its values using the following syntax:
echo ${variable name}
Thus the command
echo $MAIL
will show the mail directory, $HOME the home directory, and so on. To see a complete list of the environmental variables that are defined, you can use two commandsenv and set. Although the displays can differ slightly (environmental variables only versus local variables), for the most part the output of env is a subset of the output of set. Some of the variables that can display include the following:
-
HOMEThe directory you begin in, and where you end up when typing cd without any other parameters
-
LINESNumber of lines within the display before pausing (more)
-
LOGNAMEThe username under which the current user is logged in
-
PWDThe present working directory, or where you are now
-
SHELLWhich interpreter you are using
-
TERMThe type of terminal, or emulation, in use
-
USERThis rarely differs from LOGNAME but can if the user is switching permission levels with commands such as su
NOTE
As a general rule, predefined system variables are always in uppercase.
You can change the value of variables as needed, or add your own to be referenced in programs or at the command prompt. For example, to create a new variable called TODAY, use the following syntax:
TODAY=Wednesday
You can now see the value of the variable by using the command
echo $TODAY
The result will be Wednesday. If you now use the command
set
the variable will appear there. However, if you use the following command, it will not:
env
The variable has been created locally, and can be referenced locally. In order for it to be accessible in subroutines and child processes, you must move it from local status into the environment, and this is accomplished via the export command:
export TODAY
This moves the variable to where it can be found in the environment, as well as locally, and accessed by subroutines and child processes. The variable, and its value, will be available for the duration of the session, and lost when you log out. To make the value permanent, you must add the entry to a profile.
To change the value of the variable, simply define its new value:
TODAY=Monday
Because it has already been exported, this need not be done again, and the new value will apply locally as well as in the environment. Should it be necessary to remove a variable, you can use the unset command.
Among those variables present and definable are those that present the prompt. The prompt is the visual message from the shell that tells you it is ready for input. The default prompts include
-
$ as the last character for Bourne, BASH, and Korn shells
-
% as the last character for C shell and Z shell
-
> as the last character for tcsh
The primary prompt is either the variable PS1 or prompt, based on which shell you are using. In bash, a typical value for PS1 is
[\u@\h \W]\$
Dissected into its components, PS1 is equal to the following:
-
The left bracket ([)
-
The name of the current user
-
The at symbol (@)
-
The name of the current host
-
A space
-
The present working directory
-
The right bracket (])
-
The dollar sign ($)
An example of this prompt would be
[edulaney@server7 home]$
The backstroke (\) character is used to signify that a special value should be used. Different values that can be used for the prompt include those shown in Table 3.1.
Variables to Define the Prompt
Value |
Result |
\d |
Current date |
\h |
Name of host to first period |
\n |
New line |
\s |
Shell |
\t |
Time |
\u |
Username |
\W |
Current directory |
\! |
History number |
\# |
Command number |
\$ |
Default prompt$ for standard users, and # for root |
\\ |
An actual backstroke (literal) |
ABC |
ABC (the value of that text, or any text given) |
Looking at the variables on the system, you will find that more than PS1 exists. For example, earlier in this chapter, we discussed ending a line with a backstroke to signify that you are not finished entering input yet. If we look at the sequence of events, and include prompts, it would look like this:
[edulaney@server7 home]$ ls -l *.gif \ > *.fig \ > *.bmp
Note that the prompt changed from PS1 to a greater-than sign (>). If it had stayed PS1, you would not know that it was still accepting input, so it changed from the primary prompt to a secondary prompt to signify the change in mode. The prompt represented (by default) by the greater-than sign is PS2. Its value can be changed from the default to any value you want, including all the special values given in the earlier table. Within most shells, there are three to four layers of prompts.
By now you've realized that the dollar sign ($) is used to signify a variable; when you have a variable named EXAMPLE, you view its contents by examining $EXAMPLE. Three other variables exist for a shell that can be useful in determining your environment.
-
The first$$will show the process ID number of the shell now running:
echo $$
The second$?will show the results of the last command that you ran in terms of whether it was successful (0) or not (1). For example, the ls utility accepts an option of -F that will differentiate between directories and files by putting a slash behind the name of directories. The ls utility does not have a -z option. Given this knowledge, the following sequence shows how $? can be utilized, and includes the prompts and output of each operation:
[edulaney@server7 home]$ ls -F Desktop\ sample snapshot01.gif snapshot02.gif [edulaney@server7 home]$ echo $? 0 [edulaney@server7 home]$ ls -z ls: invalid option -- z [edulaney@server7 home]$ echo $? 1
The third variable$!will show the process ID number of the last child process started in the background. If no child processes have been started in the background, the result will be empty. For this discussion it is useful to know that placing an ampersand (&) at the end of the command will execute the command in the background. For example
[edulaney@server7 home]$ echo $! [edulaney@server7 home]$ ls -F & [edulaney@server7 home]$ echo $! 19321 [edulaney@server7 home]$
In the first instance, no job had been sent to the background, so the returned value was empty. A job was then sent to the background, and its process ID number could be found by echoing $!.
Quoting
One of the most difficult components of the shell to understand is often the use of quotes. There are a few rules to remember to make understanding the concept easier:
-
There are three types of quotesdouble quotes ("), single quotes ('), and back quotes (´). Each has a different and distinct meaning. Double quotes are used to disable all characters except ', \, and $. Single quotes disable all characters except the back quote. The back quote substitutes the value for a command.
-
Quotes must always be used in even numbers. If you give an odd number, the shell believes that you have not finished with input yet and waits for more.
-
You can mix and match different types of quotes and embed them within one another.
Let's examine each rule in order. If you have a file named sample of the worlds best cigars, and you give this command:
cat sample of the worlds best cigars
The cat utility will first try to open a file named sample, then one named of, followed by four other files: the, worlds, best, cigars. The whitespace between the words is interpreted as delimiters between different files. In order to be able to see the file, the command must be changed to
cat "sample of the worlds best cigars"
The double quotes cancel the default meaning of the whitespace and allow the value between them to be interpreted as a single entry. The double quotes cancel the meaning of most special characters, but not all. For example, suppose there is a variable named EXAMPLE that is equal to 25:
echo $EXAMPLE
This will return "25". Likewise, the following will also return "25":
echo "$EXAMPLE"
And the following will return "$EXAMPLE":
echo '$EXAMPLE'
The single quotes go above and beyond the double quotes and also cancel out the meaning of the dollar sign.
Going in another direction
echo 'date'
will return "date". Substituting the single quotes for back quotes will have a different result:
echo ´date´
will return the results of the date command. An alternative to the back quotes in the newer shells is to place the command within parentheses and treat it as a variable. Thus the date can be echoed as in the preceding example with the command:
echo $(date)
If you fail to use an even number of any quote set, PS1 is replaced by PS2, and continues to be so until the total number of quotes used (each set) is an even number. This can be useful when you have a lengthy entry you want to break into lines during entry. The following example includes the prompts and also shows the use of one set of quotes (back quotes) within another (double quotes):
[edulaney@server7 home]$ EXAMPLE="Hi, the date > and time now > are ´date´." [edulaney@server7 home]$ echo $EXAMPLE Hi, the date and time now are Thu Aug 10 11:12:37 EDT 2000 [edulaney@server7 home]$
In many instances, the quotes need to be mixed and matched. One of the biggest problems you will encounter, however, is that special characters make it difficult to display them as output. For example, assume the end result of an echo operation to be
Karen says "Hi"
If you use the command
echo Karen says "Hi"
the result will be
Karen says Hi
The shell interprets the quotation marks as meaning that the text within them should be taken as a single entry. The shell performs the operation given it, and loses the quotes in the process. To get around this, you must use the backslash (\) character to override the default meaning of the quotes:
echo Karen says \"Hi\"
Note that the backslashliteralcharacter must precede each incidence of the quotes, and is always only good for the character immediately following it.
Command History
The bash shell keeps a list of commands that you give it and allows you to reuse those commands from the list rather than needing to retype them each time. From the command line, you can use the up and down arrows to scroll through recent commands. You can also enter two bangs (!!) to rerun the very last command you gave.
Typing history shows all the commands that are stored, with an incrementing number on the left. Typing a single bang and one of those command numbers will rerun that command, as in !205.
NOTE
Instead of seeing the entire history list, you can choose to see only the most recent entries by following the history command with the number of lines you want to see, like this:
history 5 history 10
Alternatively, you can type a bang followed by a set of characters and the shell will rerun the most recent command starting with those characters. For example
!ls
will rerun the most recent command that started with ls.
Important variables for history are
-
HISTFILEPoints to the file holding the history of commands. By default, it is .bash_history in each user's home directory.
-
HISTSIZEThe number of entries to keep each session.
-
HISTFILESIZEIdentifies the number of command history entries to be carried over from one session to another (letting you run commands in this session that you ran in the previous one).
NOTE
An internal alias for history, fc, also exists and can be used to recall and rerun commands as well.
Command Aliasing
Although a plethora of commands and utilities are available within the operating system and shell, you can create aliases that make more sense to you, or that shorten the number of characters you have to type. For example, if you are familiar with working with the command line of Windows-based operating systems, you are accustomed to typing dir to see what files are there. A similar operation in Linux is possible with ls -l. It is possible to create an alias so that when you type dir, it is ls -l that runs using the following syntax:
alias dir="ls -l"
The syntax is always the alias followed by the actual command that will run when the alias is entered, separated by the equal sign (=). In rare instances, you can get away with not using the quotation marks around the aliased entry, but as a general rule, they should always be used.
NOTE
For aliases to survive a session, they should be added to the .bashrc file within a user's home directory. If you do not put them within a file that is executed upon login (thus re-creating them), the created aliases are lost when you log out.
Other Features and Notes
The Linux command line has a number of other features that should not be overlooked. Although they are not complicated enough to warrant a section of their own, it is useful to know of their existence:
-
When typing a command, you can press the Tab key after entering a few characters and the shell will attempt to complete the name of the command you were typing.
-
The command-line history can be edited to alter commands before running them again. The default editor in bash is emacs, and in zsh it is vi. Editors are discussed later in this chapter, in the section "Working with vi."
-
When you press the Enter key, the shell first scans the command line and determines what elements it has been given by looking for whitespace. It next replaces wildcards with any relevant filenames. Following that, it strips all quotes and substitutes variables. Lastly, it substitutes any embedded commands and then executes the entry.
-
The test utility can be used in conjunction with $? to test almost anything. For example, to see if a file exists and is readable, use this combination:
test -r snapshot01.gif echo $?
Complete syntax for all the test options can be found by typing man test.
Two less-than signs (<<) are known simply as "here" and signify that processing is to wait until the string following them is given as a PS2 prompt on a line by itself. For example
cat << litter
will accept input at a PS2 prompt until the string "litter" is entered on a line by itself.