To access the Linux system you have to have an account. The account will have a login
name and a password, use these to login. Once the login is accepted Linux will set
your environment and execute any commands it finds your .bashrc file (assuming your
shell is bash . If the shell is sh or ksh .profile will execute, if it's csh .cshrc
will be executed). When all is ready Linux will present you with a prompt, usually the
dollar sign ($). - The prompt tells you that you can enter commands.
To see the environment:
env
Or
set
The system will show you a list of variables that affect the way your commands will be
executed. Since they are variables, you can change them to any value you like,
although some settings may not work the way you expect.
The first file Linux executes after all of this is the .bashrc (notice that there is a
dot at the beginning of the file name. The rc at the end means, run commands and is
appended to all manner of files to designate them as start up commands run before
anything else). You can put any shell command in this file. Normally Linux will
execute the commands in the system setup file to provide a basic environment. This
file is called, /etc/bashrc . This file is going to run regardless of anything yes"> -
else but you can change whatever that file does by adding commands to your personal
.bashrc file. Some of the things you might want to change are:
PS1 This is the prompt ($ by default)
HOME This can be any directory but is usually your HOME directory
PATH This is where Linux looks to find executable files
Notice that these are variables and they set the environment. They are, therefore,
called environment variables. All environment variables are written as all caps
(upper-case only). These variables are always available and can used in shell
programs. When any variable (environment or otherwise) is used it will be prefixed by
the dollar sign ($) so the environment variable PS1, for instance, - is referred to as
$PS1.
To give a variable a value, the dollar sign is not used, instead you just use its
name:
PS1=$HOSTNAME ${PWD#*}> '
Notice that there are no space between the variable name and whatever is being
assigned to it. The quotes are required to make sure everything you are assigning is
properly included in the variable.
You can also add or change aliases . An alias is a command that executes other
commands. An alias is useful if you want to modify that way a standard command works.
An alias looks like this:
An alias is handy since you can quickly create your own - commands. An alias is also
executed before any command in your PATH so it takes precedence over existing commands
of the same name (so be careful with alias names!).
You can also create a shell function. A shell function is a complete shell
program within another shell program (a shell program is called a script ). A shell
function can be used as a sub-routine which means that it can be called within a
script based on whatever condition you specify. This gives a shell script the power
and flexibility of a real programming language. A function looks like this:
checkname()
{
while [ $ans = ]
do
echo Enter your name ...
read ans
done
}
checkname
Here the function is the function name followed by empty parentheses. On the next line
is the left curly brace. This starts the function definition. Then there's some
regular shell commands and then the right curly brace that ends the function
definition. Now its a sub-routine can be called from anywhere within the main
script.
Using these features you can create a very sophisticated program that executes every
time you login. You should experiment with the .bashrc shell script to see how you can
change your environment and tailor it to your needs.
After making a change to the .bashrc you will want to execute it to see if everything
works:
. .bashrc
That's a dot (.) followed by a space and then .bashrc. The first dot causes the shell
to execute .bashrc file as if you had just logged in.
If you have used Windows or DOS you will notice some differences in the way things are
done. A directory uses the forward slash character (/) to separate directory elements
under Linux instead of the backslash (\). The cd command by itself will return you to
your HOE directory.
There are no drive letters like C: or D:. Linux sees everything as a directory beneath
the root (/) directory regardless of where it is on a disk or even which disk it may
be on if you have more than one physical disk. Every part of a command must be
separated from every other part by a space or tab. Linux uses the minus sign character
(-) to include a command option while Windows and DOS use the slash character (/).
Linux is case-sensitive. A command like LS is different than ls. Windows and DOS
change everything to upper-case and cant tell the difference between upper and
lower case. Linux has an on-line manual that explains every command in detail.
There are many other differences, large and small, between Window/DOS and Linux so
much of what you may have understood from Windows and DOS may not be that helpful when
using Linux. Past experience is helpful of course, but there's still much to learn.
A Linux command (actually a shell command since the shell is the mechanism used to
parse and process commands) sees a command as a collection of pieces. The first piece
is the command itself. Following the command there can be arguments. A command can be
something like:
ls
an argument to ls might be an option that changes they way it works:
ls -lA
An option is always prefixed by the minus sign character (-) and is used to modify the
command. There can be other arguments like a file or directory:
ls -lA /etc
In the example above there are three arguments: the command itself, the options and
the directory (the object of the command). The command is an argument because we are
actually asking the shell to process the command (the shell is the subject). Because
the entire command line has a subject, a verb (the command and its options) and
an object, it has a syntax or grammar and the shell is very picky about how
you talk to it.
Since the usual way to number things when speaking to a computer is to begin with
zero, the first argument is zero (0), the next is one (1) and then two (2) and so on.
Whats particularly useful about this is that these arguments are also variables.
This makes it possible to refer to each part of a command as a series of variables
beginning with zero:
$0 $1 $2 ... $n
So in the example above, ls is variable $0, the option lA is $1 and the directory,
/etc , is $2. These kinds of variables are called positional parameters and are
defined by their position on the command line. The shell knows many kinds of variables
and any of them can be used in a shell script. This capability makes it possible to
write shell scripts that can know just about anything about the world they live
in. Because of this flexibility, almost all of the Linux configuration is constructed
using shell scripts.
The System Configuration Environment
Since the Linux system is configured almost entirely by shell scripts, it's fairly
easy to examine and even change the system by modifying these scripts. most of the
major Linux system configuration files are located in the / etc directory. Within this
directory are lots of configuration scripts and sub-directories containing still more
scripts. any of these scripts depend on still other scripts and, often, various
non-script configuration files (usually named with a .conf - extension). There are
several directories that contain information Linux needs to start and run most of the
network and system services . A service in this case is one or more programs that
provide some feature required to make the system useful. A service will often refer to
some other service so that configuring one can affect another.
The location of system files will vary depending on the distribution and version of
the UNIX or Linux you're using. /etc/init.d
is common but so is
/etc/rc.d/init.d
and the
xinetd.d
directory can be is other places than what I'm describing
here (in a Redhat Linux system). Some systems also use an
/etc/inetd.conf
file to manage network services.
The log file locations can also vary as well as the location of the sendmail files and
directories.
You may have to poke around to find everything but regardless of the actual locations,
their purpose is the same.
Text Box: The location of system files will vary depending on the distribution and
version of the UNIX or Linux you're using. /etc/init.d is common but so is
/etc/rc.d/init.d and the xinetd.d directory can be is other places than what I
describing here (in a Redhat Linux system). Some systems also use an /etc/inetd.conf
file to manage network services. The log file locations can also vary as well as the
location of the sendmail files and directories. You may have to poke around to find
everything but regardless of the actual locations, their purpose is the same. Two
directories in particular are essential. The /etc/xinetd.d directory contains files
that instruct some service on how it should operate. These are not scripts but rather
lists of options a service uses to operate. The
/etc/init.d directory contains a collection of shell scripts that are used to start
and stop various services (typically, servers like apache or DNS). These are scripts
that test the current environment for some odds and ends and then start a program
based on that environment. In both of these directories the programs that the files
and scripts refer to are called, daemons.
A daemon is a program that is started (usually by a script) and continues running
until you explicitly stop it or re-boot the machine. They will sit quietly in the
background waiting for another program to request it to perform its service. Once
the daemon has done its thing, it goes back into the background and waits for another
request.
A somewhat complex example is the email daemon. This daemon is called sendmail - and
is used to process all the email services. When the system boots it will start all the
daemons you have activated. If sendmail is configured to run, the boot process will
run the script /etc/init.d/sendmail and pass it the option to start:
/etc/init.d/sendmail start
The sendmail script will first perform - a bunch of checks to see how it should
behave. If these checks pass, the script will start the sendmail daemon using whatever
options you have configured.
During all of this, the script or sendmail itself will refer to configuration files
located in the /etc/mail directory. This directory contains the files that actually
determine how sendmail will work. most of this information will be in the
etc/mail/sendmail.cf file. Sendmail reads this file
every time it starts so if you change something in this file you have to re-start
sendmail. most likely you will never even look at any of these files, but its good
to know where the are and what they do.
To see what daemons are configured to start when the machine boots:
chkconfig --list
This will display a listing of all the currently configured daemons. The list has the
daemon on the left-most column and the various run levels in which it is
supposed to run. A run level is a point in the boot process. Unlike Windows or Macs,
Linux doesn't have to boot all the way the before you can begin using it. The boot
can be in stages. These stages, or run levels, provide some capability unique to that
run level. The run levels are:
0 shutdown the machine
1 Single-user mode. Only someone at the system console can use the
system.
2 multi-user mode. Here many people can log in and execute commands.
3 The is the same as multi-user except networking is now enabled
4 This run level isn't used (possibly reserved)
5 This is the same as run level 3 except that the Graphical User
Interface is enabled. This is the normal windowing environment XWindows).
If you use the chkconfig list command for sendmail, for instance, you will see the
run levels in which it becomes active. It may not be active (on) in any run level if
you aren't running a mail server.
The start up script for sendmail in
/etc/init.d/sendmail will check to
see if the daemon is enabled. If so the script will continue starting sendmail. If not
it will just quit and do nothing.
To see which daemons get started and if there were start up problems, you can view the
system log file located in
/var/log/messages or /var/log/maillog (for
sendmail). - The Linux system logs just about everything that happens so you can check
these logs if there is a problem or you suspect something is amiss.
- There are several ways to view a file. Since most of the files you want to examine
are plain text almost any configuration file can be viewed. The viewers are:
more - displays one screen-full of the file at a
time. Hit the question mark at any time to get help on how to continue.
less - like more only less (some would say it was
the other way around)
pr - - this is mostly for display file for printing
and rarely used.
cat - - this will just dump the entire file without
stopping This command is useful if you suspect a file has special characters
These characters are supposed to be non-printing but they can interfere with the
display. Use the v option if you suspect these characters are in the file.
You can also use an editor to view files. The best all purpose editor is
New"'>
vi . Other editors
are ed, emacs , sed and even
awk . Theses editors
let you view a file and also change if you want.
To view the system log file, then, try:
more /var/log/messages
You can just view the last few lines of a file:
tail /var/log/maillog
Or maybe view only the first few lines:
head /var/log/lastlog
Since you will probably want to view some of these files fairly often, you might
benefit
from creating an alias in you . bashrc file:
alias syslog=tail -200 /var/log/messages
alias maillog=tail 00 /var/log/maillog
Now you just have to type the alias name to view the file.
The vi Editor
So how do you change a file anyway? The best all-purpose editor for creating and
editing
programs and scripts is vi . This editor has lots of very useful features for working
with shell scripts and is by far the most convenient way - manage editing tasks.
Unfortunately, it is also kind of tricky to master. The best way to master vi is by
simply using it. A good place to start is with the . bashrc file. As mentioned above,
this file is used to set up the environment for you after you've logged in. Like
most shell commands, vi needs an argument, something to work on. This will be a file
of course and, since .bashrc is the file we want to edit:
vi .bashrc
This will open the file and display the first line of the file. If its a new
file there won be a first line so
vi will display the tilde
character (~). - There are several ways to enter new text depending on where the
cursor is located. Normally the cursor will be positioned on the first character of
the first line.
The vi editor is a screen editor meaning that it displays one screen full of the
file at a time and also that that can move around within that screen to edit stuff. To
do all this it uses commands, usually of one letter. There are several way to access
these commands. The simplest commands are those having the simplest function.
To quit vi
:q
To write the changes to disk
:w
To both write and quit vi
:wq
To force and action use the bang first
:!
To move the cursor to the bottom of the file
:$
To move to the top of the file
:^
To delete a range of lines
:1-4d
to substitute one string with another
:s/old_string/new_string/
To search for a string of characters
/some string of characters/
Notice that these commands use another character at the beginning of the command. The
colon character (:) is used to tell vi that the action applies to the entire file in
most cases. The slash character is used to specify some string of characters
(words. This hints at the most basic functions of vi, but to actually edit the
file you have to use another kind of command. These commands don't use the colon
(:), you just enter the command:
a
add (append) text to the right of the cursor
Hit the Esc key to exit
i
insert text to the left of the cursor
Hit the Esc key to exit
o
create an empty line below the current line and enter editing mode
Hit the Esc key to exit
O
create an empty above the current line and enter editing mode
Hit the Esc key to exit
D
delete everything to the end of the current line
dd
deleted the entire line
yy
copy the current line
p
paste deleted or copied text below the current line
P
paste deleted or copied test above the current line
w
skip to the beginning of the next word
W
skip to the beginning of the next including any punctuation
e
skip to the end of the current word
E
skip to the end of the current word including any punctuation
These commands are used when you are actually editing - a file. When in the text entry
mode (a,i,o,O) you have to hit the Esc key to exit the editing mode. There's lots of
other commands but these are enough to get you started.
Now we can edit the .bashrc file (letters that are bold are commands you will enter:
vi .bashrc
:$
a
alias syslog=tail 00 /var/log/messages
alias maillog=tail 100 /var/log/maillog
alias vi=/bin/vi
alias dir=ls lA|grep
Hit the Esc Key here ...
At this point you've added some text to the bottom of the file. If you write this
file to disk and then quit,
:!wq
this file will now be permanently stored on the disk.
Now lets add something else:
vi .bashrc
o
export PS1=$HOSTNAME ${PWD#*}>
export PATH=$PATH:/usr/sbin:/usr/local/bin
-
Hit the Esc Key here and then write and quit:
:wq!
You can edit, save and edit again as often as you want. Since this is your startup
file that will execute every time you login, lets execute it now to see what it
does:
. .bashrc
Notice the dots (.). They're important, they tell the shell to execute this file and
preserve the settings it may have changed. This technique is necessary because the
shell will usually execute a copy of itself to run the script. This copy will execute
and then disappear returning control back the original shell. Whatever that copy
(sub-shell) does is forgotten as soon as it finishes so any settings it may have used
are also forgotten. The dot (.) command tells the original shell to not use a
sub-shell but to run the script itself. Doing it this way means that the environment
settings wont be forgotten but will instead become part of the original shell.
Sounds complicated but it makes sense once you've used it a few times.
So the dot command above will replace the existing environment with the settings added
to the .bashrc file. Now you can see the effect of the changes. If you don't like
the changes, edit the .bashrc file again, change stuff, write and quit vi and then run
the dot command again.
Any changes to the shells environment while in a sub-shell will be lost when the
sub-shell finishes. To preserve changes to the environment use the export directive to
force the change to exist in all subsequent sub-shells. If export is used in the
.bashrc file then that environment change will persist in all the sub-shells.
Text Box: Any changes to the shells environment while in a sub-shell will be lost
when the sub-shell finishes. To preserve changes to the environment use the export
directive to force the change to exist in all subsequent sub-shells. If export is used
in the .bashrc file then that environment change will persist in all the sub-shells.
If you enter the .bashrc entries above and run the dot command on .bashrc, you will
immediately see the difference. The prompt (the PS1 variable) will be different, you
can just type, syslog to see the last 100 lines of the system log file
/var/log/messages or maillog to see the /var/log/maillog file. Type dir to see only
the directories in the current directory.
Sub-shell runs a command and then goes away
class=shape>
Login shell starts a sub-shell to run a command
Its important to understand that UNIX (and, later, Linux) has always been a
multi-user and multi-tasking operating system. This means that many users can be
executing many commands at the same time. To keep everything straight, each user is
given a copy of the shell at login. This copy belongs to that user and that user can
modify the environment using the .bashrc startup file. The shell that belongs to a
user can spawn(start) sub-shells and each sub-shell will belong to the original
login shell for that user. This makes the multi-user, multi-tasking capability
possible. Understanding this design is necessary to effectively manage your
environment.
"Times New Roman"'>
"Times New Roman"'>
Creating Shell Scripts
A shell script is a plain text file that contains commands that can be executed as a
group rather than one at a time from the command line. Not only is a script
convenient, its extremely powerful since you can construct some very complex
commands specific to your needs. The .bashrc file discussed earlier is a shell script
but it doesn't really do much until you makes some changes to it. Once you have a
working script, all you have to do to execute it is change its permissions and then
just type the file name of the script to execute its commands.
A file or directory will always have some permissions that determine what kind of file
it is and who can use it. These permissions assume three classes of possible users:
the owner of the file, the group of users to which the owner belongs, and everyone
else. Each of these classes of users will have three possible kinds of access: Read,
Write and Execute. Read permission means that the file can viewed, write permission
means that the file can be modified and execute permission means that the file is a
program or script that can be run as a command.
Type
Owner
Group
Others
device
read
write
execute
read
write
execute
read
write
execute
1/0
1/0
1/0
1/0
1/0
1/0
1/0
1/0
1/0
binary
1
1
1
1
0
1
1
0
1
octal
7
5
5
Decimal Value
0
0
0
0
0
1
1
0
0
1
2
2
0
1
0
3
3
0
1
1
4
4
1
0
0
5
5
1
0
1
6
6
1
1
0
7
7
1
1
1
To provide read, write and execute permissions to the owner, use an octal 7. For read
and execute permission use octal 5. A shell script will usually have at least access
level 5.
To modify a files permissions, use the chmod command:
chmod 755 file_name
Each class of user is identified using a 1 (one) for the kind of permission being
granted. If that permission is one then access is granted, if it is empty (zero) then
permission is denied.
Since there are three possible binary states for each permissions class, the
permission for a class of user can be represented as an octal number. To see a
files permissions use the ls command with the l option:
ls l file_name
-rwxr-xr-x
- - 1 - - 0
- - 0 - -
1203
Jul 3 - - 2004
file_name
The first column of information shows that this file has the permissions set to binary
111101101 which is octal 755 and this gives the owner read, write and execute
permissions, the users group has read and execute permissions and everyone else
read and execute permissions. This is the normal permissions setting for a shell
script file.
Pretty boring stuff but you really do need to understand how it works. There's a
setting that usually gives all new files a default permissions setting. This is umask
command:
umask
022
What this means is that all new files will be set to the mask of the this
number. A mask in this sense means that every zero will create a one in the
permissions and every 1 will create a zero in the permissions. Confusing? Of course
but here's what happening:
All Ones
111
111
111
ask
000
010
010
Permissions
111
101
101
This uses binary addition which I wont go into here but it works (trust me) and
Linux assumes a umask of 022 for all new files you create. This is usually what you
want. All new files you create will also automatically belong to you and the group you
belong to is also determined by Linux so you don't have to think about that at
least.
So now you know all about file permissions and file ownership. You now need to create
a shell script. This is the most interesting and challenging use of the Linux
operating system since you can create all manner of useful programs for yourself. As a
Systems Administrator you absolutely have to know how to create shell scripts,
there's no more effective way to manage the system. While the Graphical User
Interface (GUI) can do most of the systems management chores, there's far more
possible when you work from the command line. Enough said, lets do it.
vi get_name
a
echo e enter your name ... \c
read name
if [ $name= T ]
then
echo You aren't serious are you.
exit 0
fi
f1=`echo $namecut c1|tr [a-z] [A-Z]`
f2=`echo $namecut c2-`
name=${f1}${f2}
echo Hello $name
Simple script really but its doing quite a lot. The echo command will display the
following word or string. If the string contains spaces or tabs use the double quotes
(). It usually best to always use the double quotes whether you need them or
not. The e option tells the echo command to interpret the \c notation at the end of
the string. (this is a special character that affects how echo displays the string,
see man echo ). The string is a prompt asking for user input.
Next is the read command. This will take everything you type up to hitting the Enter
key and store it in a variable. The variable here is named, name. It is quoted because
we want to catch the possibility that user enters nothing (just hits Enter). - By
using the quotes we can tell if the variable, name, is null or unset. The difference
is that null means the variable exists but has no value. An unset variable doesn't
even exist.
The if statement will compare (test, see man test ) the variable name with null. By
using the quotes around the variable, we can see if its null or unset. The null
value is just the two double quotes within nothing in between. Without these quotes,
the if statement will fail if the variable is empty because the variable is unset and
therefore cant be tested. With the quotes we can see that the variable exists but
is empty. If the shell tries to test an unset variable its going to fail so use the
quotes.
If it turns out that the variable is null (you didn't enter anything), the script
will echo a string of text and then exit. A shell script - always have an exit value
to let you know if the script completed without errors. An exit value of zero means
that the script has no errors. There's no benefit to returning a failure exit code
because the script worked correctly even though the user misused it. In other words
the script is ok.
If the user entered something the script will assume that its his (or her) name and
pass the value of the name variable to the next step. When the shell sees the fi it
knows that the if statement has completed and move to the next line. - The next line
in this case will create another variable named,
f1
.
Since the name variable has a usable value (presumably a name), we can use that value
to define the f1 variable. Here we use a variable type called, command substitution .
This type of variable will have the value of a command we execute. The command will
output something and that is what will become the value of the variable we want to
define.
We use the echo command again to display the value of the name variable we acquired
earlier from the read command. This time though we don't display it to the screen,
we send it to a pipe instead. A pipe (|) is a mechanism to take the output of a
command and dump it into the input of another command. Think of it as an actual pipe
with one end connected to one command and the other end to some other command. A
simple concept that is hard to explain, just use it to see how it works.
The cut command that follows the pipe will take the value of the name variable and
process it using the c option. The cut command is used to cut up a string and
display the results. The c option means to cut some number of characters. Here we
just care about the first character of the
name
variable. We take this character and pass it to another pipe and from there to the tr
command. the tr command will translate the character passed to it to something
else. We use it here to convert any lower case letter to upper case. We capitalize it.
On the next line we do pretty much the same thing except we take all the characters of
the name variable except the first and we don't care about capitalization.
Next we combine the two variables we just created to create a new value for the name
variable. Now we take this new name variable and echo it back to the user. He (or she)
will see their name displayed and properly capitalized in case they neglected to do
it.
Not terribly exciting but it demonstrates some of the cool things you can do with a
shell script. With just the few commands we used above, you can device some pretty
sophisticated scripts that can give the appearance of intelligence and choice.
For more detail on these commands use the on-line manual for the commands. Type man
and then one of:
read
exit
cut
tr
echo
test
To find about more about variables, man bash . The manual entry for bash has all
manner of detail about creating scripts. While the prose is difficult and terse,
there's most of what you need to know about creating scripts hidden in its pages.
Read it and then read again and then go back and read it some more. It is the
authoritative source of almost everything you need to know.
You can create little shell scripts to view log files and collect other information
that can make maintaining a Linux system easier. These kinds of scripts don't have
to be very elaborate and, in some cases, can be replaced with an alias or shell
function. Just for practice though well create some scripts to show some of the
techniques available.
vi chklogs
a
if [ $1= T]
then
log=/var/log/messages
else
if [ -f - /var/log/$1 ]
then
log=/var/log/$1
fi
more $log
Hit the Esc key to get out of the editing mode and then:
: wq!
chmod 755 chklogs
This script will expect you to enter the log file you want to view. The $1
variable means the first argument after the command (the shell script name). if you
don't provide a log file to view, the script will assume that you want to view the
system log at /var/log/messages . If you do provide a log file on the command line,
the script will use that file name if it really exists. In both cases the script will
use the log file name you provide or the default to create the variable "Courier
New"'>
log .
All of this was done using an if statement. The if statement will first check (test)
to see if there is an argument to the command. There are several ways to indicate a
test condition. I always use the square brackets ([]) since, for me, its easier to
read. The test will compare the positional parameter variable $1 to null. If true ($1
is null, notice the double quotes!), then the variable
log is assigned
a default value
(/var/log/messages ). If false then $1 has a value and
execution drops down to the else part of the if statement. Here we test to see if the
file exists (-f). If so we assign the
log variable
the value of $1 since we know we have a real log file name.
Next we use the log variable as an argument to the more command which will display the
file named by the log variable one screen at a time. The logic of the script is quite
simple but preparing everything is somewhat involved. All we really wanted to do was
view a file but we had to make sure the user entered something we can use. To ensure
that the script will work we have to test the user input before using it. Lots of
scripts have to do this checking to prevent confusing errors.
After writing and quitting vi we use the chmod command to change the permissions of
the script to make it executable. Now we can just type the name of the script and
provide a log file to view (or use the default /var/log/messages file):
chklogs
or
chklogs maillog
Lets create little script to monitor the system login information files for
changes. If someone hacks into the machine and modifies these files by adding a login,
we can devise a test to alert us.
All user accounts are stored in the
/etc/passwd file. This file has
all the information about a user needed to permit him or her to login. In most systems
the password information is stored in another file, /etc/shadow that can only be
viewed by root (the system owner and manager, a very powerful special account). The
/etc/shadow file contains the passwords for every user in encrypted form. While the
encryption is pretty much impossible to crack, keeping even the encrypted form hidden
makes it even more difficult to hack into a user's account.
vi chkpw
a
if [ `sum /etc/passwd|awk {print $1,$2} != `cat
/etc/p.sum ]
then
mail s assword file has changed< - /etc/pw_alert
root
fi
if [ `sum /etc/shadow|awk {print $1,$2} != `cat
/etc/s.sum ]
then
mail s shadow file has changed< - /etc/pw_alert
root
fi
sum /etc/passwd|awk {print $1.$2}> /etc/p.sum
sum /etc/shadow|awk {print $1.$2}> /etc/s.sum
chmod 600 p.sum s.sum
Hit Esc to quit editing mode
:wq!
chmod 755 chkpw
The first time this script is run the root user will get an email saying the password
and shadow files have changed. That's because the stuff were checking for
doesn't exist yet. You can ignore this email.
What this script is doing is testing the output of a command and comparing that to the
output of another command. This is accomplished using command substitution variables.
This kind of variables uses the grave accent character (`) to enclose the
command. This kind of quote character tells the shell to execute the command it
contains.
The first command is sum . This command will do a checksum calculation on a file
(or string). This will output a pair of numbers that will be unique for the file.
Its very difficult to change a file without also changing its check sum so its a
handy way to see if a file has been modified. We are testing the checksum on the
/etc/passwd file.
This is followed by a pipe which passes the output of the sum command to another
command, awk . The awk command is a very powerful command and almost a programming
language in itself. What we want here is to grab just the first two words-
(fields) of the awk output. The sum command will output three fields (words). The last
field is the file name being checked. We don't care about that so we have awk just
display the first two, numeric fields. The awk command understands positional
parameters so you can use them the same way as in a regular script: $1, $2, $3, etc.
Since we only care about the first two fields (positional parameters $1 and $2) we
tell awk to only display those two using the built-in awk print statement.
The test operator != says, is not equal to(the bang (!) means not so we
are comparing the output of the first command substitution to the output of the next
command substitution.
This second command substitution is the output we get with,
cat /etc/p.sum .
The cat command will just dump the contents of a file. When compared we expect both
commands to output exactly the same two numeric fields; the output of both commands
should be identical. If they are not the same we use the mail command to send the root
user an alert message.. The s option to mail lets us create a subject line for the
email. We use the < operator to pass to the mail command the contents of a file. This
< operator is called input re-directionand tells the shell to use this file for
input to the command instead of the keyboard. There is also an output re-direction
operator that sends the output of a file or command to another file.
The very same logic is used to run the very same tests on the /etc/shadow file. If
either test fails, root gets email with an alert message. After all this we use the
sum command to replace the current contents of the two check file with new checksums.
This has the effect of updating these check files for future checks. After these files
are updated, we ensure that they can only be read or written by root and no one else
by using the chmod command.
All we need now is to create the alert file that is mailed to root:
vi pw_alert
a
There have been changes to /etc/passwd or /etc/shadow since the last check
Hit the Esc key
:wq!
Now we have a way to track changes to user account information and any attempt to
create a new account.
About Quoting
The shell uses different kinds of quoting for different purposes. These quotes are:
Grave accent
`
command substitution
single quote
strip any "special" meanings from a string
double quote
shell interprets special characters
backslash
\
strip special meaning from the next character
curly brace
{}
enclose a variable to preserve its name
If you use the wrong quote there will be an error or other strange behavior. When
using quotes in a script make sure to provide both an opening and closing quote of the
same type (except for the backslash). The bash manual entry ( man bash ) has more
detail. In almost every case you should use the double quotes when creating or
referring to a variable, $1is safer than just $1.
If you need to include a special character in a string put the backslash in front
of it like this:
echo e you owe me \$${100}!
The backslash in front of the first dollar sign will cause the shell to display the
dollar sign as just another character. The second dollar sign is not quoted by the
backslash so the shell will assume it is a variable. By enclosing the variable in the
curly braces({}), we can put another character right next to the variable name.
Without the curly braces any character following the variable name will seen by the
shell as part of the variable name and that will most likely not work as expected.
About Words in the shell
The shell chops up the command line into pieces ( arguments ) by using an environment
variable called the Internal Field Separator or IFS. This will be the space , the
tab and the newline (the Enter key). Because of this behavior, every argument on the
command must be separated from every other by a space or tab. While in DOS or Windows
its ok to type a command like,
dir/w
with Linux something like,
ls-l
will be interpreted by the shell as the single command,
New"'>
ls-l . It is seen as one word These words (arguments) are more
correctly called, fields, since many shell commands (like awk ) refer to them as
fields in their documentation. It also makes it easier to visualize a command or
string as having fields since quite often you are creating or modifying files that are
flat-file databases where the notion of records and fields is essential to
understanding their function.
Regular Expressions
One of the handiest features of the Linux shell are - regular expression.
Unfortunately, it also one of the trickiest to master. Its worth the trouble to
learn what they are and how they are used but it takes some time. A regular expression
is a way to create or find a string without specifying it explicitly, or sometimes,
even knowing what it is. This is done by substituting a special notation in the place
of the some number of characters. An example would be to take a string of characters
like, Bill writes excellent documentation for Linux!and replace some parts of
the string with special characters, like this:
grep b]i.*excel*x$ some_file
Believe it or not this will match the string. The grep command is used to locate a
string in a file. I suggest - using the double quotes () around - the regular
expression. If it finds a match it will display the entire line that contains the
match. The regular expression begins with the caret character ( This tells grep to
start looking for a string that begins with the following character. The notation [Bb]
will search for a string having either the upper case or lower case B. So we want a
string that begins with either a B or b. The square brackets ([]) will represent one
character only but that character can be any one of those listed with the brackets. To
represent a range of characters, use this [m-r] or [Aa-Cc].
Following the closing bracket is the letter i with no spaces and then a dot. This
means that the second character in the string will be a lower case i. the dot (.)
represents any character and can be a letter, a number or even punctuation. Next is
the asterisk (*, no space). This will match anything at all, even nothing. Next comes
the letters, excel. Then another asterisk (matching anything, of any length). Now
comes the letter x and, finally, a dollar sign ($). The dollar sign means the end of
the line. Put it all together and you can match the example string exactly.
Of course this formula can match lots of other strings too. To ensure that you only
get the string you really want, construct the regular expression using some unique
combination of characters.
You can use a regular expression almost anywhere. With the ls command, for instance,
you can match files having some unique part of the files name:
ls l *gz
ls lA .*
ls report[0-9].*
You will see lots of regular expressions used in the various system configuration
files so you will definitely need to understand them to manage these files. The best
source of detailed information is in the manual entry for ed ( man ed ) which, alas,
is difficult to read and understand but the authority on regular expressions. While ed
is one of the oldest UNIX editors, and rarely used for interactive editing, it is
extremely handy within a shell script.
vi ed_script
a
while [ $name= T ]
do
echo e enter your login name, fool ... \c
read name
continue
done
if [ `grep c :${name}: /etc/passwd` -ge 1 ]
then
ed /etc/passwd <
/name}: /
s/:\/bin\/sh/\/bin\/bash
fi
w
q
!
chmod 755 ed_script
In this script were going to use the while statement. The while statement will
evaluate the stuff within the square brackets and, if the evaluation (test) is true it
will drop down to line after the do statement. The test is to see if the
$name variable is null. If so (or if its unset)
the script execution will display the echo line. The first time the script its
executed the $name variable wont be set so the echo statement will execute. This
prompts the user to enter something. If this step assigns something to the
$name variable, then the while statement is
satisfied and sends the shell to the line following the done statement. If the user
just hits the Enter key, the
$name variable will still have no value
so the continue statement forces the shell to go back and start over at the while
statement line.
Once we've gotten some user input, we cause the shell to use the if statement to
perform another test. This time we use grep to find a string in the /etc/passwd file.
The -c option to grep means to just return the count of lines that match. If there is
at least one line matching (the ge operator in the test means, greater than or
equal to then we know we have a string to work on.
Now that we have our matching string, we use the ed command to edit the /etc/passwd
file. The notation <
The line:
/name}: /
is the same as in the vi editor. The slash (/) characters enclose a regular
expression. If the regular expression matches a string in the file that ed is editing,
ed jumps to the line having that regular expression. Once at that line, we can give ed
some commands that affects just that line.
The next line:
s/:\/bin\/sh/\/bin\/bash
is again like vi. We are telling the ed editor to substitute a string that begins with
the colon character (:). The notation \/ is how we use the backslash to quote the next
character (quoting with the backslash (\) removes any special meaning from the
following character. This is also known as escaping character special
meaning). So what we are saying is, substitute a string that begins with the colon
(:) followed by the slash character (/), the word bin and then another slash
character, and then the word sh with the string, / bin/bash . Pay attention to
the escaped slash characters. Four of them are escaped with the backslash and two
are not. The two that are not escaped are used to replace the first string with the
second.
Once we've done all that, we send the ed command a w command and then q command.
This will write the changes to the file and then quit. After that is the bang
character (!) that ends the here document. The here document is very handy but its
probably the only time you will use the ed editor.
There's one more script we should try. Suppose we have directory of files that we
want to change the permissions and ownership on. Ordinarily we would have to run the
chmod and chown command on each file and directory and that could take quite while.
Lets use a script:
vi fix_files
a
for i in `ls /var/spool/mail`
do
echo ## Changing permissions and ownership on $i ##
chmod 760 /var/spool/mail/$i
chown ${i}.mail /var/spool/mail/$i
done
Hit the Esc key and then
:wq!
chmod 755 fix_files
This time we will use the for statement to create the script. The for statement will
use a list of things to look at which in this case is the output of the command
substitution for the ls command. The for statement will take each line passed to it by
ls and put it in the variable we've named i . it will then jump to the line
after the do statement and execute the lines it finds there. What were doing this
time is using echo to display a informative string to the user. It will also display
the current value of the $i variable.
After that the script will use the chmod command to change the permissions for the
file named by the current value of $i. Next it executes the chown command to change
the files ownership and group still using the current value of $i. When the shell
sees the done statement it goes back to the top and gets the next line from the list
and performs the same operations on it. When the list has displayed everything, its
next value will be null and the for statement just quits.
These examples are just some ideas on how the shell can used to create some really
useful scripts. Obviously all the techniques Ive demonstrated can be combined into
much more complex and comprehensive scripts. If you're clever, you can make the
machine appear almost intelligent. When you understand the various capabilities of the
shell, you can read and fully comprehend the system configuration files. By modifying
the system shell scripts, you can add features, enable and disable stuff and customize
things to suit yourself.
If you find that you are frequently typing the same commands over and over again,
consider creating a script (or alias) to automate the task. A good candidate might be
something like:
find . /depth print |awk print $3}sed
s/\.tar$/\.tar_file/
This command is a pain to type and prone to typing mistakes. A shell script can
perform the same function plus have lots of extra features making the command even
more powerful. The easiest way to being is to just create very simple scripts and add
features. Test the script,
bash x script_name
This will display each line of the script as it is executed and show the processing of
all tests and the assignment of all variables. You can use the output to find out
where the script failed or why something like a variable wasn't set or had the wrong
value.
Systems Administration
The main function of a Systems Administrator is to make sure that the machine he or
she manages behaves like its supposed to. While it might seem that setting things
up right in the first place would be enough but it rarely is. Once things are working,
the Systems Administrator has to also monitor everything to make sure it keeps
working. It often happens that a configuration will have to change as features are
added or changed or when something begins to fail or behave erratically.
One of the most common causes for a configuration change is that the original purpose
for having the machine in the first place, changes. You may have planned on it having
it perform some set of tasks and then decided to add some functionality. There may
also be a need to enhance its performance or enable additional security. The point is
that the way a computer is used can evolve so you have to know manage the changes.
A second function of a Systems Administrator has to do with the fact that a Linux
machine is meant to be networked to other computers. most of the Linux operating system
assumes it will have a role in a network - To use Linux for a stand-alone home PC is
to waste much of its capability. Linux is a networked operating system by design.
Almost every administration task on Linux can be done using a GUI (Graphical User
Interface). The default login session will start the GUI and setup a standard
windowing display with icons and mouse support. The main system menu will contain
sub-menus you can access to manage almost everything. This makes it pretty easy to
manage the system and its possible that you could do everything using this
interface. Even so, if don't know how to read, modify and create shell scripts, you
will eventually run into some very confusing problems. Use the GUI for simplicity but
be prepared to verify any changes by examining the files and scripts that are created
or modified.
Because you will use Linux in a network, it will help to understand what that means. A
network is supposed to allow computers to exchange resources. A resource can be a file
or printer or information. In a Linux network a resource can also be a server A
server is a program that provides a service to other (client) computers. Linux
supports all the major servers like email, the web, ftp, DNS, DHCP, telnet and a bunch
of others.
The client will connect to the Linux machine (usually called the server because it
provides the service you want to access) and request a service.
The Linux machine will start a server program (usually a daemon ) to handle the
request. The services use a set of standards called protocols to handle requests.
these protocols are very precisely defined and well documented (most often by an RFC ,
R equest F or C omment). The most common protocol for most services is TCP/IP
(Transmission Control Protocol / Internet Protocol). TPC/IP provides the connection
information for networked computers. Within this information will be a request for a
specific application protocol like ftp or httpd . The TCP/IP and application protocol
information is contained in a packet . The packet will also contain the data the
application is supposed to process.
The file /etc/services lists all the most common protocols. The file also specifies
which port the application will use. A port in this case is a location that specifies
how the application protocol will communicate with the application program (daemon).
The combination of the requesting computers IP address and the port number is
called a socket . If a computer wants to telnet to the Linux server, for instance, it
will send a TCP/IP protocol request packet requesting a connection to the telnet port
(23). If the Linux server accepts the request it passes it to the telnet daemon
(usually
/sbin/in.telnetd ) and that program will
process the request according to the telnet protocol (as defined in an RFC).
Most of the common daemons are located in either
/etc/xinetd.d or
/etc/init.d . The xinetd.d files
are actually setup files that provide arguments to the daemon to be started. The files
in init.d are shell scripts that execute to provide the daemons environment. There
are also files in the
/etc directory that provide startup
configuration for various other applications (not necessarily daemons). These files
end with the string, .conf and are arguments to the application.
There are some servers and applications that are installed in other places. The
webserver daemon, httpd , is located at
/etc/httpd/bin/httpd with its configuration file in /etc/httpd/conf . The ftp server
may be located in a directory named after the daemons name like /etc/vsftpd .
Almost all of the configuration files will be somewhere in the /etc directory but they
might also be in /opt or /usr/local . Since they are started by scripts in /etc/init.d
or configuration files in /etc/xinetd.d directories, you can view these files to find
out where the daemon and configuration files are located. Another good reason to
understand shell scripting.
There are also lots of configuration files in the directories named rc*.d The * will
be number from 0 to 6. These numbers represent the run-level to which the system
was booted (run-level 5 is the default). These files are actually links to the files
in
/etc/init.d . These links will execute a script
in /etc/init.d .
most of the system logs will be in the
/var/log
directory although some (like httpd ) will keep their logs elsewhere. You can view
these logs to find out how things are working or why they failed. most log files have
the same format.
The date and time of the entry and which user or which program was running and any
additional information or error messages that the program output, one entry per line.
These logs can provide all the information you will need to get a good start on
locating and correcting any failures. Some handy network commands for managing the
system are:
netstat
reports what the network cards are seeing
ifconfig
shows the configuration for the network cards
chckconfig
shows or enables/disables network services
route
show the routing configuration
traceroute
see how packets get to another computer
ping
see if another computer is up
nslookup
discover a computers name or IP address
There are also quite a few very handy add-on programs for managing and monitoring the
network:
webmin
This provides a great web interface to manage most of the system
nmap
This is part of Linux but it has options you can add. For scanning ports
nessus
a nice graphical port scanner
snort
a packet sniffer to see how your ports are being accessed. Also a good IDS
tripwire
monitors system files to detect changes
mrtg
use to create web based graphs of network traffic usage
When you decide to add a program (package) to Linux you first download it (try
rpmfind.org). You will usually end up with a file having a name that ends: .tar.gz .
The gz part means it's compressed (zipped) and the tar part means that its an
archive. The steps to install the file are usually:
tar zxvf some_file.tar
cd some_file
. ./configure
make
make install
This will unpack the archive and install it. There is also usually a READE file and a
INSTALL file. Read these to see if you need to do anything else. The configure shell
script will also have information that may make the installation easier.
There are also packages that have been configured to install themselves. Redhat Linux
use the rpm (Redhat Package Management) command to install a package:
rpm i some_file.rpm
Debian uses a command called,
apget to do the same thing. Once a
package is installed it becomes part of the system. You should check the log files
after a new installation to make sure it isn't causing problems. An RPM usually
installs itself in the /usr/local/ directory.
The best way to become a competent Systems Administrator is to constantly watch the
logs and install monitoring software like
tripwire
to make sure there are no changes that you haven't authorized. If you are
administering a network server be very careful about what daemons are enabled and who
has access to what. A good place to start is by creating an /etc/hosts.allow file.
This will invoke tcpwrappers to allow or deny access based on hostname or IP address.
make sure that every user account has a valid password and pay attention to how users
are using their accounts by checking the logs.
You'll also have to spend a lot of time digging through the on-line manual. The
entries are difficult to read and even more difficult to comprehend but, once you've
done it a few times it gets easier. Linux also provides a utility for a quick summary
of a command:
info cat
There's also hundreds of very handy web sites where you can refer to case studies and
special or interesting uses. Web searches can also turn up some specific answers
especially for unusual log file entries. Cut and paste a log file error into a Web
search and see what happens (use double quotes to make the whole string one single
search term.
Use vi or more to view the various configuration files and server startup scripts to
see how they are constructed. You will learn how shell scripts are written as well as
discover how the system is set up. Poke around and look at everything. Don't change
anything though, just look and learn. Write simple shell scripts and, once they're
working, add features and try stuff out. If a script fails it will usually display an
error message that you can use to correct problems.
Copy and existing shell script to your HOE directory and play with it. change little
pieces and see what happens. Copy the /etc/passwd file to your HOE directory and
practice finding information using commands like grep and awk, ed, sed and here
documents. The /etc/passwd file is cool because each item of specific information is
separated by a colon (:) from every other item. You can, therefore, - extract stuff by
keying on the colon character. Experiment, play and learn. You will be surprised how
quickly you begin making sense of it all.
Return to the Contents Page