Part 3: Basic Operations FAQ

ver. 0.194 2003-06-04 by Stan, Peter and Marie Klimas
The latest version of this guide is available at
Copyright (c) <1999-2003> by Peter and Stan Klimas. Your feedback, comments, corrections, and improvements are appreciated. Send them to This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.0, 8 or later with the modification noted in lnag_licence.html.

Contents of this section:
3.1 Basics
   3.1.1 Filenames
   3.1.2 What are the different directories for?
   3.1.3 How do I run a program?
   3.1.4 How can I change the PATH?
   3.1.5 How can I shutdown my computer?
   3.1.6 How do I deal with a hanged program?
   3.1.7 Command options
3.2  Users, passwords, file permissions, and security
   3.2.1 Home directories, root, adding user
   3.2.2 About password security
   3.2.3 I forgot the root password
   3.2.4 I forgot my user password
   3.2.5 Disabling or removing a user account
   3.2.6 I have file permission problems. How do file ownership and permissions work?
   3.2.7 My mp3 player chokes. The sound is kind of interrupted (how to set suid)
3.3 Job scheduling with "at", "batch", and cron
   3.3.1 How do I execute a command in the "background"?
   3.3.2 How do I execute a command at a specified time ( using "at"or "batch")?
   3.3.3 How do I set up cron?
3.4  Shell
   3.4.1 What's a shell and do I want to use a different one?
   3.4.2 How do I customize my shell prompt?
   3.4.3 Colour in text terminal
   3.4.4 How do I print symbols on the console,  in a text mode application, or in X?
   3.4.5 How do I write a simple shell script?
   3.4.6 Meaning of quotes
   3.4.7 Input/output redirection
   3.4.8 Shell special characters (metacharacters)
3.5  Package installation and rpm package manager
   3.5.1 How do I install a program I downloaded from the Internet?

3.1 Basics

3.1.1 Filenames

Linux is case-sensitive. For example: myfile, Myfile, and myFILE are three different files. Your password and login name are also case-sensitive. (This follows tradition since both UNIX and the "c" programming language are case-sensitive.)  Naming conventions for files and directories are identical. All the files and directories which I create (for myself, as a user) are lower-case, unless there is a very special reason to make it different. Most of Linux commands are also all lower case.
Filenames under Linux can be up to 256 characters long and they normally contain letters, numbers, "." (dots), "_" (underscores) and  "-" (dashes).  Other characters are possible but not recommended.  In particular, it is not recommended to use special metacharacters: "*" (asterisk), "?" (question mark), " " (space),  "$" (dollar sign),  "&" (ampersand), any brackets, etc. This is because metacharacters have special meaning to the Linux shell (shell is something like COMMAND.COM, the command processor under DOS).  It is possible to have a space in the filename, but we don't recommend it either--we use underscore "_" instead.
It is not possible at all to have '/' (slash) as a part of the filename because  '/' is used to represent the top of the directory tree, and as a separator in the pathnames (the same as '\' is in DOS).

Like in DOS, I cannot have a file called . or a file called.. (dot or two dots)--they mean "current" and "parent to the current" directory respectively, exactly like in DOS.

Here is the meaning of some metacharacters:
*  = Matches any sequence of zero or more characters, except for  "." (a dot) at the beginning of a filename.
?  = Matches any single character.
[abC1]  = Matches a single character in the enumerated set. In this example the set contains: 'a',  'b',  'C', and '1'.
[a-z] = Matches any lower-case letter.
[A-F] = Matches any upper-case letter from A to F.
[0-9] = Matches any single digit.
[a-zA-Z0-9] = Matches any letter (lower or upper case) or any digit.

The character \ (backslash) is also special. It makes the subsequent special character aquire literal meaning (read on).

Examples. This command will list any filename in the current directory, with the exception of filenames starting with "." (dot):

ls *

An equivalent to this command is to type just ls  or  dir (without the "*").  Files with names starting with "." are not shown because "."  as the first character of a filename is not matched by "*". Think of files with names starting with "." as an equivalent of DOS hidden files.  Use ls -a (list with the option "all") or ls .* to see these  "dot" files.  The "dot-files" are common in the user home directories and they typically contain user-level configurations.
This command will list any file (in the current directory) that contains a dot (except files starting with a dot):

ls *.*

This command will list any filename that contains two dots (except those starting with a dot):

ls *.*.*

Please note that Linux does not have "filename extensions" the way DOS does, but you can still use them. For example, I can have a file Some other DOS-kind file-naming features are completely absent ("Micros~1.doc" comes to mind).
This command will find (on the whole filesystem) any file with the extension "htm" optionally followed by any one more character:

locate *.htm?

This command will show all filenames in the current directory that start with "a" or "b", or any capital letter:

ls [abA-Z]*

This command will list any file starting with "a" and ending with "n"

ls a*n

Command line autocompletion.  This is a great command line feature--I use the [Tab] key a lot to save on typing. It makes it brisk to deal with long and complicated filenames. For example using such a filename on the command line is really not a problems, if I use autocompletion:

dir Eurosong\ 2000\ Olson\ Brothers\ -\ Fly\ on\ the\ wings\ of\ love\ \(denmark\).mp3

I just type

dir Eu<Tab>

and if there are no other files starting with "Eu", the rest of the filename is automatically typed for me. Otherwise, I would have to look at my choices (which are printed for me) and type one or two more characters to make the filename unambiguous. The backslashes in the name of the example song above show that the spaces are "literal", i.e., they spaces are part of the filename.

Problems with weird filenames.  Most of these problems can be solved using autocompletion. Additionally, to manipulate files with names that do contain metacharacters, I may use a pair of ' ' (two apostrophes), so that the metacharacters are quoted and therefore the shell does not interpret their meaning. For example, to rename a file my file* (contains space and asterisk), I would issue:

mv 'my file*' filename_without_weird_characters.txt

Please note that I use a pair of ' (apostrophes) for quoting. Quoting with a pair of "  " (quotation marks) is generally weaker than quoting with '  ' . If you use " (quotation marks)  some metacharacters may get interpreted by the shell (altering their meaning).

Following UNIX tradition, on Linux, one may create files with names contaning almost any character, including non-printable (control) characters. Those are very infrequent, but if you encounter such a file, it can make you feel really weird. I would rename such a file using a carefully positioned metacharacter. I would use ls first to try if my action indeed targets the desired file, and then rename the file (using the move "mv" command):

ls -l myfile*y.html
mv myfile*y.html myfile.html

(I assume that the non-standard character(s) are between the letters e and y.)

As an example of the perhaps weirdest problems that you might face when using non-recommended characters in a filename, try creating a file with a name starting with a dash and then remove it--there seems to be no way to do it (because a dash normally introduces command options).  E.g., the command

dir > -junk

will create such a funny file (like in DOS, the symbol ">" redirects the output from the dir command to a file named "-junk").  Since the regular way of removing the file -junk does not work, I use:

rm ./-junk

The "dot slash" at the beginning  means "the current directory" and here serves just the purpose of hiding the leading dash so it is not interpreted as introducing an option to the rm command.  The point here is that I would rather stick to traditional naming conventions than face the occasional complications.

Besides using autocompletion, apostrophes and quotes, I can manipulate files with weird names using \ (backslash). Backslash hides the special meaning of the subsequent character. For example, i can create a weird file with the name  *?[ using the following command:

touch \*\?\[

(The touch command creates an empty file or, if the file exists, updates its date/time of last modification.)

3.1.2 What are the different directories for?

Linux filesystem tree is large and complicated. It will vastly improve your skills if you familiarize yourself with it.

Briefly, typical Linux contains five filesystems. These filesystems can reside on a single or different physical hard drives and/or hard drive partitions, depending on the size and need of your system. (A single filesystem can also be distributed between different physical devices, if needed.)
The root "/" filesystem contains basic operating system and maintenance tools. The content of this filesystem should be sufficient to start  up the system and perform emergency maintenance and repairs if they were necessary.
/usr filesystem contains all commands, libraries, documentation, and other files that do not change during normal operation. This will also contain major applications that come with your Linux distribution, for example Netscape.
/var filesystem contains files that change:  spool directories, log files, lock files, temporary files, and formatted (on use) manual pages.
/home filesystem contains user files (users' own settings, customization files, documents, data, mail, caches, etc). The contents of this directory should be preserved on an operating system upgrade.
/proc filesystem contains entirely illusionary files. They don't really exist on the disk and don't take up any space there (although ls -l will show their size). When viewing them, you really access information stored in the memory. It is used to access information about the system.

The parts of the root filesystem are:
/bin--executables (binaries) needed during bootup that might be used by normal users.
/sbin--executables (system binaries) not intended for use by general users (users may still use them, but this directory is not on their PATH).
/etc--system-wide configuration files for your operating system.
/root--the home directory of the system administrator (called super-user or root).
/dev--device files. Devices appear on Linux as files so that hardware is abstracted and it is easy to write to them or read from them.
/mnt--mount points for removable media (floppy, cdrom, zipdrive), partitions of other operating systems (e.g. MS Windows), network shares, and anything else that is mounted on the file system temporarily. It normally contains a separate subdirectory for each mounting share. The contents of these drives/shares appear in these subdirectories--there are no drive letters on Linux.
/lib--shared libraries for programs that reside on the root filesystem and kernel modules.
/boot--files used by the bootstrap loader (LILO or GRUB), the thing that loads first when the computer is booted and perhaps gives you the option of which operating system to boot, if you have more than one OS on your computer). It typically also contains the Linux kernel (compressed, file vmlinuz), but this can be stored somewhere else, if only LILO is configured to know where it is.
/opt--optional large applications, for example kde under RedHat 5.2 (under RedHat 6.0, kde is distributed as any other X-windows distribution, main executables are in the /usr/bin directory).
/tmp--temporary files.  This directory may clean up automatically.
/lost+found--files recovered during the filesystem repair.

The most interesting parts of the /usr filesystem are:
/usr/X11R6--X-windows system (version 11, release 6).
/usr/X11--the same as /usr/X11R6 (it is a symbolic link to /usr/X11R6).
/usr/X11R6/bin --lots of small X-windows apps, and perhaps symbolic links to the executables of some larger X-windows applications that reside in their own subdirectories somewhere else).
/usr/doc--Linux documentation (on newer systems, this moved to /usr/share/doc).
/usr/share --Data independent from your computer architecture, e.g., dictionary words.
/usr/bin and /usr/sbin--similar to their equivalents on the root filesystem (/bin and /sbin), but not needed for basic bootup (e.g. during emergency maintenance). Most commands will reside here.
/usr/local--the applications installed by the local administrator (perhaps each application in a separate subdirectory). After the "main" installation, this directory is empty. The contents of this directory should survive normal re-installation or upgrade of the operating system.
/usr/local/bin--perhaps smaller "user"-installed executables, plus symbolic links to the larger executables contained in separate subdirectories under /usr/local .

It is important to understand that all directories appear in a single directory tree, even if the directories are contained on different partitions, physical drives (including floppies, etc), or even if they are distributed over the network. Therefore, there are no DOS-type "drive letters" under Linux. What would be a "drive" under DOS or MS Windows, appears on Linux as a subdirectory in a special "mounting" location.

The directory system is well-established and standard on most Linux distributions (the small differences are being currently addressed by the Linux Standard Base). It is also quite similar to that found on typical commercial UNIX systems.

To summarize:
More about the /proc filesystem (only for really curious).
The /proc "pseudo" file system is a real-time, memory-resident file system that tracks the state of the operating system kernel and the processes running on your computer.  The /proc file system is totally virtual, i.e., it is not written on any particular disk or other persistent media, it exists only in the computer memory, and it is constantly updated to reflect any changes to your system. The size of the /proc directory is always zero and the last modification time is the current date. In some cases, it is possible to change your system settings by manually changing the contents of files in the /proc filesystem. Many Linux utilities use the /proc filesystem as the source of their information, e.g., dmesg, ps, top.

Contents of the /proc filesystem.

Directories with numerical names like "1" "170" "4908" are IDs of the processes running on your computer. Each directory contains several files, e.g.,: cmdline (contains the entire command line that was used to envoke the process), cwd (symbolic link to the cwd of the process), environ (the environment variables defined for this particular process in the form VARIABLE=value), exe  (a symbolic link to the executable file that the current process is linked to), fd  (a list of the file descriptors opened by the process),maps (a named pipe that can be used to access the process memory), root (a symbolic link to the directory which is the root file system for the particular process), stat (info on the status of the process).

Other files in the /proc filesystem:
/proc/cpuinfo --information about the processor, such as its type, make, model, and performance.
/proc/devices --list of device drivers configured into the currently running kernel.
/proc/dma --DMA channels being used at the moment.
/proc/filesystems --filesystem types configured into the kernel.
/proc/interrupts --interrupts in use, and how many of each there have been.
/proc/ioports --I/O ports in use at the moment.

For example, I can read the cpu info on my system using the following command:
cat /proc/cpuinfo

3.1.3 How do I run a program?

Typing the name of the executable on the command line doesn't help? There are three possibilities.

The first possibility: I did not type the name of the executable correctly. Check the case--Linux is case sensitive!  For example, typing "Pico" or "PICO" will not start the pico editor.

The second possibility: maybe the program is not on my PATH?  Under Linux (or any UNIX), an executable must be on your PATH to run it, and the current directory is not on my PATH. Type the full path to the executable in front of the executable name, or do:

cd the_program_directory

I must put the dot and slash in front of the program name or the program will not execute.  (This is a security feature not to put one's current directory on the path.  It makes "trojan horses" more difficult. A "trojan horse" is a malicious program that pretends to be something different than it really is.)  The dot means "the current directory", and the slash "/" is a separator between the directory name and the filename (exactly as "\" in DOS).
I may check my path using:

echo $PATH

To learn how to change your PATH, or add your current directory to it, see the next answer.
If my executable is lost somewhere in the directory tree,  I may want to find it using (for example):
find / -name "netscape"

to find a file named "netscape", starting the search from the root directory "/". You may be able to achieve the same result faster using:

locate netscape

(Locate runs faster because it relies on a pre-built database of files on your system.  This database is updated by a background "cron" process that normally runs at night, so don't count on locate to find a file if you regularly switch off your computer for the night, or you are searching for a file that you have just installed.)
Please note that the PATH is normally different for root than for the regular users (root's PATH includes /sbin and /usr/sbin whereas users' don't). Therefore users cannot execute commands located in the  "sbin" directories unless they specify the full path to the command. Also, if you become a superuser by executing the su command, you inherit the user's PATH, and to execute the command located in sbin, you need to specify the full path.
Conversely, if I need to learn where an executable which is on my PATH is located on your system (i.e., the executable runs by typing its name anywhere in the system, but I would like to know where it is located), I may use something like this:

which netscape

which will show the full PATH to the executable program called "netscape" (if one exists).

The third possibility:
  maybe the file is not executable.  If it should be, change the permissions to make it executable. E.g. (as root or the user who owns the file):

chmod a+x my_file

will make the file "my_file" executable for all users. Check if it worked using:

ls -l  my_file

Read here if you don't understand the output of this command or the whole "third possibility".

Please note that under Linux (or UNIX),  the file extension (for example .exe or .com or .bat) does not make the file executable.  The file needs an "executable file access mode" which is not unlike a "file attribute" under DOS.

3.1.4 How can I change the PATH?

Typically, you don't have to change your PATH, but it very useful to understand what PATH is.

The PATH is the list of directories which are searched when you request the execution of a program. You can check your PATH using this command:

echo $PATH

which, on my system , shows the PATH for the user "yogin" to be:


The ":" is a separator, therefore the above PATH represents a list of directories as follows:


Here is the output from the command "echo $PATH" run on my system on the account "root":


You can change the PATH for all users on the system by editing the file /etc/profile and adjusting (as root) the line starting with "PATH=".  I do it using the pico editor (as root):

pico -w /etc/profile

(The option -w turns off the wrap of long lines.)
Re-login for the change to take effect.  To set up the PATH for an individual user only, edit the file /home/user_login_name/.bash_profile (please note the dot in front of the filename--files starting with a dot are normally invisible, you have to use ls -a  to see them).
If you really want to have the current directory on your PATH, add "." (dot) to your PATH.  When used in the place when directory name is expected, a dot means "the current directory". The specification for the path in /etc/.bash_profile may then look like this:

export PATH

This command takes the contents of the environmental variable called PATH (as set for all users in /etc/profile), and appends to it the name of your home directory as set by the variable HOME with an attached "/bin"  and then a dot. Finally, the command assigns the resulting string back to the variable called PATH.  It is necessary to use the command "export" after modifying PATH or any other user-environment variable, so that the variable is visible outside of the script that sets it.

3.1.5 How can I shutdown my computer?

Close all your programs saving the data as desired. From your GUI main menu (e.g., "K"), select "Logout". Then, from the logon screen, select: "System"-"Shutdown".

Alternatively, from a text terminal, press <Ctrl><Alt><Del> (the "three-finger salute", you press the three keys simultaneously), wait for the shutdown process to complete, and turn off your machine only after it starts rebooting again.  If you are in X-windows, first switch to a text terminal by pressing <Ctr><Alt><F1>  (three keys simultaneously).

Never turn off your machine without the proper shutdown or else you may have disk error messages next time you boot. (Typically, the errors resulting from improper shutdown will be repaired automatically during the next boot, but occasionally more serious problem may result, and then you may need to repair the files manually or re-install!)

If you prefer your computer to go to a halt after you press <Ctrl><Alt><Del> (instead of the default reboot), you can set this up by editing the file /etc/inittab. This file specifies something like this:

ca::ctrlaltdel:/sbin/shutdown -t3 -r now

As root, replace the option "-r" to "-h" so that the same fragment reads:

ca::ctrlaltdel:/sbin/shutdown -t3 -h now

The line starting with "#" is just a comment (it is for humans, it does not have any effect on the computer). The option "-t3" tells the shutdown command to wait 3 seconds before it starts killing processes. The options "-r" and "-h" stand for "reboot" and "halt" respectively, so they perform a shutdown to reboot or a shutdown to a system halt.

Root can also use the shutdown command directly. This command can be used for either local or remote shutdown of your computer, but is used mostly for remote shutdown when the local keyboard is not available so you cannot use <Ctrl><Alt><Del>. It can also be very useful if a program hangs so that the keyboard is no longer functional.  For example:

telnet name_of_machine_with_no_operable_keyboard
[login as a user]
[give password]
Now either execute ps axu |more, find the process id of the offending command in the ps output and do

kill pid_of_offending_process

or reboot your machine with:

/sbin/shutdown -rn now

This command will shutdown really fast, bypassing standard (longer) shutdown procedure--useful when the system becomes really buggy (the option -n will make "shutdown" kill all the processes before rebooting).
Please note that for security reasons, you cannot login to a remote machine as root (e.g., over the telnet).  You have to login as a user and then execute su and give a password to become a super user (root).

The shutdown command may also be used to execute a shutdown later. E.g. (as root):

/sbin/shutdown -r 23:59

will reboot the system 1 minute before midnight. I could also use:
/sbin/shutdown -r +1

to shutdown 1 minute from now. I can cancel a scheduled shutdown with:

/sbin/shutdown -c

If the shutdown command is too long for you, you may want to try these two commands, which do exactly what their names suggest (as root):


A fancy way to shut down your computer is to switch your system to the runlevel 0 (for halt) or runlevel 6 (for reboot). Try it using (as root):

init 0

The meaning of the different runlevels is explained in the file /etc/inittab and  here.

3.1.6  How do I deal with a hanged program?

Buggy programs do hang under Linux. A crash of an application should not, however, affect the operating system itself so it should not be too often that you have to reboot your computer.  Linux servers are known to run for more than a year without a reboot. In our experience, a misbehaving operating system may be a sign of hardware or configuration problems:  we repeatedly encountered problems with the Pentium processor overheating (the fan on the Pentium did not turn as fast as it should or it stopped altogether, the heat sink on the Pentium was plugged with dirt), bad memory chips, different timing of different memory chips (you may try re-arranging the order of the chips, it might help), wrong BIOS setup (you should probably turn off all the "advanced" options, Linux takes care of things by itself).  The "signal 11" error message is typically (99%) associated with hardware problems and is most likely to manifest itself when you perform computing-intensive tasks: Linux setup, kernel compilation, etc.  If your Pentium has the tendency to overheat (very common for early Pentiums), here are some tips to keep it cool, particulary during hot weather: clean the processor heat sink, replace the processor fan, operate the computer with the cover off and aim an extra fan inside, increase the processor "wait-state" in the computer BIOS, don't overclock, decrease useless load, e.g., replace this super-fancy screen saver with a blank screen.
Not really hanged. Some programs might give the uninitiated impression of hanging, although in reality they just wait for user input. Typically, this happens if a program expects an input filename as a command line argument and no input filename is given by the user, so the program defaults to the standard input (which is console). For example, this command


may look like it's hanged but it waits for keyboard input.  Try pressing <Ctrl>d  (which means  "end-of-file") to see that this will satisfy the cat command.  Another example:  I have seen many questions on the newsgroups about the "buggy" tar command that "hangs" when trying to uncompress a downloaded file, for example:

tar -zxv my_tar_file [wrong!]

This waits for user input too, since no option "-f filename" was specified so "my_tar_file" was not recognized as a filename. The correct command is:

tar -zxvf my_tar_filename

Please note that the filename must follow immediately after the option "f" (which stands for "filename). This WILL NOT work (very common mistake):
tar -zxfv my_tar_file  [wrong!]

Any program (hanged or not) can be killed.

A text-mode program in the foreground can often be killed by pressing <Ctrl>c. This will not work for larger applications which block the <Ctrl>c, so it is not used on them accidentally.  Still you can get back in control either by sending the program to the background by pressing <Ctrl>z  (no guarantee this will work)  or switching to a different terminal, for example using <Ctrl><Alt><F2> and login as the same user that hanged the program (this should always work).  Once you are back in control, find the program you want to terminate, for example:


This command stands for "print status" and shows the list of programs that are currently being run by the current user. In the ps output, I find the process id (PID) of the program that hanged, and now I can kill it. For example:

kill 123

will kill the program with the process id (PID) of "123".
As user, I can only kill the processes I own (this is, the ones which I started).  The root can kill any process. To see the complete list of all processes running on the system issue:

ps axu | more

This lists all the processes currently running (option "a"), even those without the controlling terminal (option "x"), and together with the login name of the user that owns each process ("u"). Since the display is likely to be longer than one screen, I used the "more" pipe so that the display stops after each screenful.

The kill command has a shortcut killall to kill programs by name, for example:

killall netscape

will kill any program with "netscape" in its name, while

killall pppd

will surely disconnect any dial-up connection by killing the ppp daemon.

X-windows-based programs have no control terminals and may be easiest to kill using this (typed in an X-terminal):


to which the cursor changes into something looking like a death sentence; you point onto the window of the program to kill and press the left mouse button; the window disappears for good, and the associated program is terminated.

A shortcut to the last command is to press <Ctrl><Alt><Esc>, to which the cursor changes into something looking like a death sentence--you point at the window of the offending program, click your mouse, and the window closes and the program is gone.

If your X-windows system crashes so that it cannot recover, or you just get stuck, it may be the easiest to kill the X-server by pressing <Ctrl><Alt><BkSpace>. After that, it might be a good idea to run ps axu, find any possible X-programs that might still be running, and kill them. If you don't do this, and there really is a misbehaving program that caused your X-windows to crash, it might cause trouble again.
If you have programs in the background, the operating systems will object your logging out, and issue a message like "There are stopped jobs".  To override and logout anyway, just repeat the logout (or exit) command --the background program(s) will be automatically terminated and you will be logged out.
Core files. When a program crashes, it often dumps a "core" into your home directory. This is accompanied by an appropriate message. A core is a memory image (plus debugging info) and is meant to be a debugging tool.  If you are a user who does not intend to debug the program,  you may simply delete the core:
rm core

or do nothing (the core will be overwritten when another core is ever dumped). You can also disable dumping the core using the command:

ulimit -c 0

Checked if it worked using:

ulimit -a

(This shows "user limits", the option "-a" stands for "all".) To make the option of disabling core dumps permanent for all users, edit the file /etc/profile (as root), where ulimit is set, and adjust the setting. Re-login for the changes to /etc/profile to take effect.
If you would like to see how a core file can be used, try (in the directory where you have a core file):

gdb -c core

This launches GNU debugger (gdb) on the core file "core" and displays the name of the program that created the core, signal on which the program was terminated, etc. Type "quit" to exit the debugger.  To learn the meaning of different signals, try:

cat /usr/include/bits/signum.h |more

3.1.7 Command options

Most commands accept numerous "options". An option can be introduced with an "-" (dash). For example:

dir -l

shows me the listing of the current directory but in a long format (the default format is "short").  Multiple options can be introduced in two, equivalent ways:

dir -l -a


dir -la

Either of the above commands will show me the listing of the current directory in the long file format (option -l), and include all files in the listing, i.e., also the hidden files (option -a).

Most popular options are marked with one letter. This follows the traditional UNIX way of invoking options. There is also a new style, which looks like this:

dir --help

Here, a single option is more than one character long, and it must be introduced with two dashes. The above command displays a brief help for the dir command, including the listing of all options. Because there are so many of those (more than a screenful), I would probably do:

dir --help | more

3.2 Users, passwords, file permissions, and security

3.2.1 Home directories, root, adding users

The (almost) only place on the harddrive that normal users (non-root) can write to is their home directory, which is /home/user_login_name.

This "home" directory is for all user files: settings, program configuration files, documents, data, netscape cache, mail, etc.  As a user, you can create subdirectories under your home directory to keep yourself organized.  Other users cannot read your files or write to your home directory unless you give them permission to do so.
Normal users can also see, read and execute many other files on the system (besides their home directory), but normally they cannot modify or remove (delete) them.

The "root" (also called "super user") is a special administrative account that has the power to modify any file on the system.  It is not a good idea to habitually work on your system as root--if you do so, your mistakes can cost you dearly. Set up and use a normal user account for everyday work for yourself, another user account for your son, and yet another for your wife. The root account is typically the only account that exists on Linux after the initial installation. Thus you have to explicitly create "user" accounts for normal work for you Linux system.

A user account can be created by "root" using, for example:

adduser joe
passwd joe
[type the password for the user joe]
[retype the password for the user joe so as to avoid mistakes]

In the example above, first I logged in as root. Then, on the command line, I issued the command "adduser" with the parameter (argument) "joe". This created the account "joe" on my Linux computer. Then, I issued the command "passwd joe" to change the password for the user "joe" to something fairly secure. Now, I can tell "joe" what her initial password is, and she can login and change the password to her liking. Please note that the account name (user login name, "joe") and the password are case-sensitive.

Root can change any user's password, although s/he cannot read it.  [Passwords are encrypted using a one-way encryption algorithm and only this encrypted version is stored on the system, in the file /etc/passwd (older systems) or /etc/shadow (newer systems), and the "open" version of the password is never stored.  When you login, the password you type is encrypted again using the same one-way algorithm and compared with the already encrypted version stored in /etc/passwd or /etc/shadow.]

The separation of the administrator and user makes Linux systems secure and robust--it even makes viruses under Linux difficult (the programs that a user runs can write only to his/her own directories, and therefore cannot affect the vital parts of the operating system).
It is customary that the user changes his/her password immediately after the first login, for example:

(current) UNIX password:  pass_OLD
New UNIX password:  pass_NEW
Retype New UNIX password:  pass_NEW

In reality, the password will not appear on the screen as you type it (for security reasons). Take your time if you are changing the password for the very first time--it can be difficult to type "blind".

On the Linux system, the same password is used to:

3.2.2 About password security

Weak passwords are probably the most common source of security problems. Even at home, you may expose yourself to serious trouble because somebody may be able to hack your computer when you browse the Internet and read/delete your files, or use your computer to do something really nasty to the local police computer network. Therefore, keep all your login names/passwords secure, even at home. Once somebody logs into your computer (even as an ordinary user), he may find it quite easy to gain root access (depending on how well-maintained/up-to-date your system is vs. how good a hacker s/he is).

Here are some examples of hazardous passwords:
- No password (possible!).
- The word "password" (wow, this one is really weak!).
- Your login name (The login and the password the same? Hmm.).
- Your first name or the first name of your daughter, son, husband, wife, girlfriend, or any other first name. The number of first names in use is quite limited--just check the paperback book "what to name your baby". Don't assume that a first name you think of is secure because you are from India--Canada is really a multinational society and the typical namelist seems to cover all kinds of first names.
- Your last name or any other last name. The number of last names is surprisingly limited! Just check the US census data to see that your "rare" last name from the abamamahaba island is very well represented in the US 89,000 of the most frequent last names (e.g., Or just check the Toronto telephone book. Another proof that we are all one family :))
- The nickname of your dog, wife, canary or computer. (Very few nick names humans use, much fewer than last names!)
- Name of your favourite sports team, celebrity, toothpaste, or detergent. Avoid names of popular soccer teams like fire. Same with rock bands (music).
- Date of your birth, social security number, etc; Sequences of digits can be easily probed.
- Name of your company, department, workgroup, etc.
- Password written in the calendar on your desk or on the side of your computer.
- A password which you also use in an insecure public place, for example an Internet store or a mailing list. In general, you should use different passwords for places controlled by different organizations.
- Any word which is in the English dictionary. The English dictionary does not contain as many words as it might seem. A not-so-skillful hacker can easily set a program to encrypt all dictionary words (100,000? that's under 1 MB!) and then compare all the encrypted strings to your encrypted password. As a matter of fact, tools for the "dictionary attack" are readily available on the Internet. Try the program crack yourself to find how easy it is. Swear words or "cool" (colloquial) expressions make the password particularly vulnerable for cracking.
- Any other word, last name, first name, pet or swear word, no matter in what language. For a cracker, to cover most languages is only a small overhead if he already covered one. How many significant languages are out there? 40?  The cracker just grabs a few more files and appends it to his cracking list. The point here is that the subset of words that humans normally use if far far below the theoretical limit of the random combination of characters.
- Any of the above with an addition of a number/letter at the beginning or the end. "yuoping1" is really a very weak password.

A good password is relatively long (minimum 6 characters, some experts even recommend minimum 10 characters),  contains a mixture of letters (upper and lower case, if possible), numbers and special characters, and is changed quite regularly (8-16 weeks?).

Unfortunately, the better the password, the harder it is to remember. I solved this problem for myself by taking 10 minutes to invent my personal password "scheme". Say, I always start and end with the monkey (@) sign, and use two words connected with an exclamation mark, the last letter of each word is capitalized, e.g., "@whitE!housE@".  Seems like an adequate password, and it is easy to remember once I know what my password rule is.  If you are a memory genius, you may consider truly excellent passwords generated with mkpasswd  :))

The system administrator can set the password policy (minimum length, requirement of special characters, password expiry) through the utility included in this configuration program (run as root):


under the menu "user account"-"policies"-"password & account policies".  Normal users won't be able to set a password which is too short,  is a dictionary word, or does not contain the prescribed number of non-alphanumeric characters (but root can change any password to anything s/he likes, s/he will only be given a warning).
Also make sure that any file that contains any password of yours (e.g., /root/.kde/share/config/kppprc) has proper, secure permissions so that it cannot be read by anybody. For example, most likely you want:

chmod 600 kppprc

If you use an "over the phone" Internet connection for just a couple of hours a week, you may be fine even with a relatively weak password on your system. But please really reconsider your system security if you use a cable modem, or are otherwise connected to the Internet for a significant amount of time.

Most computer semi-literate use amazingly weak passwords.  "Around 50 percent of computer users base passwords on the name of a family member, partner or a pet. Thirty percent look to a pop idol or sporting hero," reports CNN (  Please note the underlined base. Appending a digit to an obvious word hardly makes the password more secure.

3.2.3 I forgot the root password

Even if I never forget any passwords, I would still study this issue in detail because it can give me a hint on how my mother might be reading my ICQ chats history :-)
First method. The easiest way to solve your "forgotten root password" problem is to boot your Linux in the single-user mode, namely at the "lilo"prompt (during bootup) type:

linux single

This will make you "root" without asking for a password. Now, being root, you may change the root password  using this command (no knowledge of the old password required):


If it strikes you as insecure, that's because no computer system is secure if other people have physical access to your hardware.  Nevertheless, I did not like the "linux single" hole on my home computer and plugged it by adding the following lines to my /etc/lilo.conf file (at the end of the "image=" section):


[This "lilo" password is required when, at the LILO prompt during bootup, somebody enters the word "linux" with any parameter (normal bootup without any parameters will still be possible without a password).]  For the changes to /etc/lilo.conf to take effect, I must re-run the command lilo .  Since my lilo password is not encrypted, I must make /etc/lilo.conf readable only for root:

chmod 600 /etc/lilo.conf

Second Method.
  Another way to solve the "lost-root-password" problem is to boot your computer from the Linux boot diskette or the CD.   Then find your Linux root partition on the hard drive, mount it, and edit the file /etc/shadow.  (I can do it because after booting from the floppy, I become root without being asked for a password.)  In the password file, I erase the encrypted password for root (for example, using the pico editor), so it is empty.
Information about a user account is kept in plain-text files: /etc/passwd and /etc/shadow.

The file /etc/passwd contains the "world-readable" information about all accounts on my computer  Each line in this file contains information about one account. Each line has 7 colon-delimited fields (this means 8 entries separated by colons): login name, the letter "x", the numerical user ID, the numerical primary group ID for the user, a comment field (for example, the full name of the user), the user's $HOME directory, the name of the shell (meaning the program that is run at login).

The balance of information about accounts on my computer is stored in the file /etc/shadow. This file is more secure because normally only root can read it. In this file, each line describes "shadow" information about one account, and has 9 colon-delimited fields: login name, encrypted password, days since Jan 1 1970 that password was last changed, days before password may be changed, number of days after which the password must be changed, number of days before  password expiration to warn the user, number of days after password expiry that account is disabled, number of days since Jan 1 1970 that account is disabled, and a reserved field.

Some (older) UNIX or Linux systems do not contain the file /etc/shadow and store the encrypted user password in the second field of each line of the file /etc/passwd (the field which on newer systems contains just the letter x).

For example, my /etc/shadow entry for "root" account may look like this:


and after the password is erased, it looks like this:


Now, the root account has no password, so I can reboot the computer and, at the login prompt, type "root" and for password just press ENTER (empty, no password). After a successful login, I immediately set the password for root using the command:


Apparently,  despite deleting the password from /etc/shadow , the Debian  distribution will not let you log in "passwordless" (enhanced security?).  In such a case, what needs to be done is to replace the password in /etc/shadow with an encrypted password from another account, where you know the password. After that, you can login since you know the password.

E-mailing an encrypted password may be also a secure way to set up an account for somebody remote: "I am setting up an ftp account for you on my server. Email me your encrypted password."  After you receive the encrypted password, you insert it into the appropriate field in /etc/shadow. Now, the user can log in, since she knows the password, but nobody else can.

To make the "floppy access" to my system a little bit more difficult, I considered running a computer without a floppy drive :-) Unfortunately, Linux CDs are bootable these days. I set up my boot sequence (in the BIOS setup) so that the system boots from the hard drive before floppy and CDROM are tried, and added an "administrative" password on changes to the BIOS settings. Still, I worry that these BIOS passwords are very easily crackable, or that one could remove the small battery that sustains the BIOS setting. One could also remove my harddrive and connect it to another computer for reading :-) . I am thinking about installing an "encrypted file system" which is now available on Linux, but considering all the trouble associated with it, perhaps I will settle on locking my room :-) .  If all this sounds paranoid to you, it probably is--it just illustrates the point there is little computer security, even under Linux, if the potential cracker has a physical access to your hardware.

3.2.4 I forgot my user password

If a regular (non-root) user forgets his/her password, this is not a problem since root can change any password. For example (as root):

passwd barbara

will prompt for a new password for the user "barbara" (no knowledge of the old password required by root). If a regular user (non-root) wants to change his/her password, s/he will be asked for the old password first. (This is a security feature so nobody changes your password if you have left your terminal unattended.)

3.2.5 Disabling or removing a user account

A user account can be temporarly disabled or permanently removed.

To temporarily disable (lock) a user account, there is no need to change his/her password. Just put an asterisk "*" at the beginning of the second field (before the encrypted password) in the file /etc/shadow .  The "*" means that no login is permitted for this account. When you want to restore the account, you just erase the asterisk and the user account is back in operation, with its old password.

Here is an example entry from the file /etc/shadow with the password disabled for user "peter":


I could also lock a user account with the following command:

passwd peter -l

and unlock it with 

passwd peter -u

To irreversibly remove a user account from my home computer, I do the following:
- login as root
- change my identity to the user to be removed, to check if there is any new important mail:

su doomed_user_login_name

- delete the user account and group

userdel doomed_user_login_name
groupdel doomed_user_login_name

Remove the user affiliation to any supplementary groups:

usermod -G doomed_user_login_name doomed_user_login_name

- force-delete the user home directory with all its contents including any subdirectories:

rm -fr /home/doomed_user_login_name

3.2.6  I have file permission problems. How do file ownership and permissions work?

Linux (the same as any UNIX) is a secure, multiuser operating system, and this creates a level a complexity with "files permissions".  Trouble with file permissions can lead to unexpected and nasty problems.  Understanding file permissions is of uttermost importance to be able to administer any multiuser operating system (be it UNIX, WinNT, or Linux). My advice would be: learn the system of Linux (or any UNIX) file permission conventions; you will not regret it.

File owners.  Each file (or directory) belongs to an owner (normally a login name) and to a group. The owner is typically the person who created (or copied) the file.  The group often consists of one person--the owner, and has a name identical to that of the owner, but it does not need to be so.  A file can be removed (erased) only by the owner of the file, or a member of the group that owns the file, or the root. Other users, however, may be able to modify or erase the contents of the file if they are given permission to do so--read on. The owner and group that owns the file will be shown in the output from the ls -l command (="list in the long format"). For example, the command:

ls -l junk

produced this output on my screen:
-rwx------   1 yogin    inca           27 Apr 24 14:12 junk

This shows the file "junk", belonging to the owner "yogin" and to the group "inca".

The ownership of a file can be changed using the commands chown (change owner) and chgrp (change group), which are normally executed by root:

chown peter junk
chgrp peter junk
ls -l junk

After executing the above 3 lines, the command ls-l junk produces this output on my screen:

-rwx------   1 peter    peter           27 Apr 25 20:27 junk

Changing file ownership comes handy if you move/copy files around as root for use by other users. At the end of your housekeeping you typically want to hand the file ownership over to the proper user.

File permissions.  Now, an owner of a file can make the file accessible in three modes: read (r), write (w) and execute (x) to three classes of users: owner (u), members of a group (g), others on the system (o). You can check the current access permissions using:

ls -l filename
If the file is accessible to all users (owner, group, others) in all three modes (read, write, execute) it will show:


Skip the first "-" (it shows the type of file, and is "-" for normal files, "d" for directories, "l" for links,  "c" for character devices, "b" for block devices, "p" for named pipes i.e. FIFO files, "f" for stacks i.e. LIFO files). After the initial "-" character, the first triplet shows the file permission for the owner of the file, the second triplet shows the permissions for the group that owns the file, the third triplet shows the permissions for other users. A "no" permission is shown as "-".  Here is an output from the ls -l command on a file that is owned by root, for which the owner (root) has all permissions, but the group and others can only read and execute:

drwxr-xr-x   2 root     root        21504 Apr 24 19:27 dev

The first letter "d" shows that the file is actually a directory.

You can change the permissions on a file which you own using the command chmod (="change mode"). For example, this command will add the permission to read the file "junk" to all (=user+group+others):

chmod a+r junk

In the command above, instead of "a" (="all"), I could have used "u", "g" or "o" (="user", "group" or "others").  Instead of "+" (="add the permission"), I could have used "-" or "=" ("remove the permission" or "set the permission").  Instead of "r" (="read permission"), I could have used "w" or "x" ("write permission" or "execute permission").
Second example. This command will remove the permission to execute the file "junk" from others:

chmod o-x junk

Instead of letters, one can also use numbers to specify the permissions. To understand how it works, look at this:


The total permission for a class of users is the sum of the three. Thus:

0 = no permissions at all(neither to write, nor to read nor to execute)(common)
1 = execute only (seems unusual)
2 = write only  (seems unusual)
3 = write and execute (seems unusual)
4 = read only (common)
5 = read and execute (common)
6 = read and write (common)
7 = read, write and execute (common).

The permission for all three classes of users (owner, group, others) is obtained by gluing the three digits together one by one. For example, the command:

chmod 770 junk

will give the owner and the group the completto of permissions, but no permissions to others. The command:

chmod 666 junk

gives all three classes of users (owner, group, others) the permissions to read and write (but not execute) the example file named "junk".  Please note the "666". It is quite often used and, for at least one person I know, it is proof that Linux (any UNIX for that matter) is the work of the devil >:-0.
This command:
chmod 411 junk

would give the owner the permission to read only, and the group and others to execute only.  This one does not seem useful, but might be funny, at least for those North American Linux users who dial 411 (telephone number) for directory assistance.  Mail me if you can think of any other funny permissions (perhaps 007?).
The numerical way of representing file permissions is called "octal" because the numbers have the base 8 (the decimal system's base is 10).  The highest digit in the octal system is 7 (the octal system has eight digits: 0 to 7, analogous to the decimal system having ten digits: 0 to 9).  The octal representation is really a convenient notation for the binary representation of file permissions, where each permission is flagged as "set" or  "denied" with a one or zero and the total is represented as a string of zeroes and ones, as in this diagram:

user class:                                    owner  group others
example permissions:                            rwx    rw-    r--
absent permissions:                             ---    --x    -wx
binary representation of the permissions:       111    110    100
octal representation  of the binary:             7      6      4
Permissions for directories.
The meaning of the permissions is different for directories than it is for "normal" files. For normal files: r=permission to read the contents of the  file, w=permission to modify the contents of the file, and x=permission to execute the file.
For directories: r=permission to list the filenames in the directory, w=permission to create or delete files in the directory, and x=permission to access the directory.  Otherwise, the permissions are set the same way for directories as they are for normal files.

Default file permissions with umask.  When a new file is created, it is given default permissions. On my system, these are:


This means that files created by a user can be read and written by this user; the group and the others can only read the file. Still, on my default RedHat system, users cannot read the files in the other users' home directories because the permissions on the home directories are:


I can check the default file permissions given to my newly created files using:

umask -S

(The option "-S" stands for "symbolic" and tells umask to display the permissions in an easy-to-read form, instead of the default numeric mode.)
I can change the default file permissions for newly created files using a command like:

umask u=rw,g=,o=

which will give the owner the read and write permissions on newly created files (r+w), and no permission to the group and others.
Using numbers to set default permissions with umask is more tricky. The number shows the permissions that you take away for users (opposite to chmod).  Thus:

umask 000

will give full permissions to everybody on newly created files.  The next example gives read and write permissions to the owner, and zero permissions for everybody else (seems that's what one might want):

umask 177

To make the settings permanent for all users on the system, adjust the appropriate line(s) in the file /etc/profile .

3.2.7 My mp3 player chokes. The sound is kind of interrupted (how to set suid).

The MP3 player might not be given enough processor power (it requires a lot of it). It could be that your computer is lousy. Or you might be running too many cpu-intensive programs at the same time. Or, most likely, you may need to run the player with a higher priority. (The priority of a program can be set with the command nice -- see man nice or info nice). Try to run the player as root--programs run by root are given higher priority than those run by normal users. If this solves the "interrupted music" problem, set the "suid" on the executable so all users are given the "effective user id" of the file ower (normally root) when running it, for example:

chmod a+s /usr/bin/xmms

will do the trick for the xmms program. The output from

ls -l /usr/bin/xmms

on my computer is now:

-rwsr-sr-x  1 root  root  908k Feb 22  2000 /usr/bin/xmms

The first "s" indicates that the substitute-user-id (suid) bit is set. The second "s" indicates that the substitute-group-id (sgid) is also set.  Thus anybody who executes xmms is given the effective user id of the program owner and effective group id of the owner group, which in the example above is the user "root" and the  group "root".

Setting the suid for a program could possibly become a security hole in your system. This is unlikely the case on a closed home network and when setting suid for a program of which the origin is well traceable.  However, even at home, I wouldn't suid a piece of code of which the origin is uncertain, even if the setup instructions urged me to do so.  Also, it is definitely a very bad idea to suid too many executables on your system--it defies the whole idea of UNIX security.
Some programs do, however, require suid for proper functioning, for example kppp (the popular modem "ppp" connection utility under the KDE graphical-user-interface desktop). This is because they require direct access to the hardware--something only root is allowed to.

If you have constant problems with a smooth performance of your system, or some "real time hardware" (e.g., CD writer) tends to crash, try to reduce the number of daemons on your Linux system. Run (as root) setup (RH specific command) and disable all the "services" that you don't really require.  Ultimately, you can switch to the command line, shut down the GUI (command init 3 as root), and then the performance should surely be better even.

For those who need (like) their Linux to be a "universal" operating system (workstation, server, office computer, game box, mulimedia, etc, everything at the same time), there are dedicated Linux kernel patches: "low latancy patch" and "pre-emptive kernel patch" which aggresively atack the "latency" problem that overloaded systems exhibit.

3.3 Job scheduling with "&", "at", "batch", and cron

3.3.1 How do I execute a command in the "background"?

Using the "&" at the end of the command. For example, this will start licq (an icq client) in the x-terminal in the background, so that after issuing the command, my x-terminal is not blocked:

licq &

The process identification number, job_number, is printed on the screen, so you can use it with related commands. The related commands are fg job_number (="foreground", bring the background process back to my immediate view/control, restart it if it was stopped), bg job_number (="background", send the process to the background, restart if it was stopped, exactly as if it was started using &), <Ctrl>z (send the current foreground process to the background and stop it), jobs (list the active jobs), kill process_ID (terminate the process, use the conmmand ps to find the process_ID of the process to kill).

To make a background process keep running after you disconnect, you may use the nohup (="no hungup"), for example:

nohup make &

that maybe compiling a large program.

3.3.2 How do I execute a command at specified time (using "at" or "batch")?

The at command will execute the command(s) you specify at the date and time of your choice. For example, I could start playing music from my CDROM at 7 o'clock in the morning:

at 7:00

In the example above,  I entered the first line "at 7:00" on the command line and then pressed ENTER. To this, the at command displayed a prompt "at>". At this prompt, I entered my command "cdplay" and then pressed the control key and "d" simultaneously to finish the input. If instead of  pressing  <Ctrl>d ,  I pressed  "ENTER", the next "at>" prompt would appear, at which I would be able to enter the next command to be executed right after "cdplay", also at 7:00. And so on, I could have had many commands scheduled for execution one by one starting at 7:00.  After typing the last command, I would finish the input with <Ctrl>d.  Think of the <Ctrl>d as sending "end-of-file" to the current input.  Don't press <Ctrl>d twice because this will log you out--that's what <Ctrl>d does when entered straight on the Linux command line.

You can list the job you scheduled for execution using:

at -l

which will give you the numbered list of the jobs waiting.

If you changed your mind, you can remove a job from this list. For example:

atrm 8

will remove the job with the number eight on the list.
I could also schedule a job for execution much later, for example:

at 23:55 12/31/00

would start my X-windowing system right on time for the new millennium (5 minutes before midnight on 31 of December 2000).
If you cannot execute the at command, check if the at daemon ("atd") is loaded (as root, use ntsysv). If you cannot execute the at command as a regular user although it works for root, check if the empty file /etc/at.deny exists and there is no file /etc/at.allow. This should be the default setup and it permits all the users to execute at.  If you want only certain users to use at, create a file /etc/at.allow and list these users there.
For other options,  check:

man at

If you wish to perform a processor-intensive job in the background when the system load is low, you may choose to use the batch command.  For example, I could run setiathome (a program crunching data to help in search of extraterrestrial intelligence, SETI) using:


In this example, I entered the command batch and then, at the "at>" prompt, I entered the command which I wanted to be executed in the background. The job tries to start immediately, but goes ahead only when the system load is under 0.8  You can check the system load by inspecting the contents of the (virtual) file /proc/loadavg . For example:

cat /proc/loadavg

When a batch job finishes, the output is sent to me via e-mail.

3.3.3 How do I set up cron?

Cron (a Linux process that performs background work, often at night) is set up by default on your RedHat system. So you don't have to do anything about it unless you would like to add some tasks to be performed on your system on a regular basis or change the time at which cron performs its duties.

Please note that some of the cron work might be essential for your system functioning properly over a long period of time.  Among other things cron may:
- rebuild the database of files which is used when you search for files with the locate command,
- clean the /tmp directory,
- rebuild the manual pages,
- "rotate" the log files, i.e. discard the oldest log files, rename the intermediate logs, and create new logs,
- perform some other checkups, e.g. adding fonts that you recently copied to your system.

Therefore, it may not be the best idea to always switch your Linux machine off for the night--in such a case cron will never have a chance to do its job.  If you do like switching off your computer for the night, you may want to adjust cron so it performs its duties at some other time.

To find out when cron wakes up to perform its duties, have a look at the file /etc/crontab, for example:

cat /etc/crontab

It may contain something like this:

# run-parts
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly

You can see that there are four categories of cron jobs: performed hourly, daily, weekly and monthly. You can modify those or add your own category. Here is how it works.

The columns in the entries show: minute (0-59), hour (0-23), day of month (1-31), month of year (1-12), day of week (0-6--Sunday to Saturday).  The "*" means "any valid value".

Thus, in the example quoted, the hourly jobs are performed every time the computer clock shows "and one minute", which happens every hour,  at one minute past the hour. The daily jobs are performed every time the clock shows 2 minutes past 4 o'clock, which happens once a day.  The weekly jobs are performed at 22 minutes past four o'clock in the morning on Sundays. The monthly jobs are performed 42 minutes past four o'clock on the first day of every month.  The directory with the script file that contain the command(s) to be executed is shown as the last entry on each line.

If you wanted your jobs to be performed at noon instead of 4 in the morning, just change the 4s to 12s. Cron wakes up every minute and examines if the /etc/crontab has changed so there is no need to re-start anything after you make your changes.
If you wanted to add a job to your cron, place a script which runs your job (or a link to your script) in the directory /etc/cron.hourly or cron.daily or /etc/cron.weekly, or /etc/cron.monthly .

Here is an example of an entry in /etc/crontab which causes a job to be performed three times a week (Mon, Wed, Fri):

02 4 * * 1,3,5 root run-parts/etc/cron.weekly

An example seen on usenet showing how to automatically email a log file (edited for space):

Re: help in crontab
From: Dean Thompson <> Date: 2001-03-03 16:35
Newsgroups: comp.os.linux.admin,comp.os.linux.networking,
> How can I set the job mail < /var/log
> every day in the /etc/crontab -e file ?
You could try the following entry and see if you meet with any success:
0 0 * * * (/bin/mail < /var/log/messages) > /dev/null 2>&1

3.4  Shell

3.4.1 What is a shell and do I want to use a different one?

A shell is the program that interprets what you type on the command line and decides what to do with it.  A shell can also be invoked in a non-interactive way, for example to execute a pre-typed list of commands contained in a text file (a "shell script").  Think of a shell as the equivalent of the DOS "" (command-line interpreter) and the shell script files as the equivalent of the DOS batch files (*.bat). In comparison with their DOS cousins, the Linux shell and scripting are on steroids.

There are several shells available on the Linux system (if you installed them):  bash ("Bourne Again" shell), sh (Bourne shell, standard on many UNIX systems), csh (C shell, with a syntax akin to the "c" programming language, available on most UNIX systems), pdksh (public domain Korn shell), tcsh (tiny C shell, often used on small systems), sash (stand-alone shell, could be used when libraries are not available), ash, zsh, and perhaps a couple more.

The default shell on my system (and most probably on yours too) is bash , which is an excellent and standard shell, and I really cannot see a reason why a newbie like myself would want to change it.  bash is fully backwards-compatible with the Bourne shell (the most popular shell on UNIX) and incorporates many enhancements and best features from other shells.  From a newbie perspective, the different shells are included with Linux for historical reasons and backwards-compatibility of shell scripts that may require a particular shell to run. [Some shells may be useful if you write programs targeted for specialized "embedded" devices, that might run a "tiny" shell.]

You  can determine the shell you are running using:

echo $SHELL

If you wanted to try another shell, type, for example:
which will start the tiny c shell.  When done, type
which will return you to the previous shell (using exit on your first shell will log you out). You can find out how many shells you stacked on each other by displaying the "shell level" environmental variable:

echo $SHLVL

In the above command, the "$" means "expand the value of a shell environment variable", "SHLVL" is the variable name, and "echo" is a command that prints things.

The shell for each user is specified as the last field in the password file /etc/passwd .  If you really wanted to change it, edit (as root) this file and replace the "/bin/bash" with the shell of your choice.

3.4.2 How do I customize my shell prompt?

On my machine, the prompt may look like this:

[stan@marie stan]$ _

Here "stan" is my login name, "marie" is the name of the computer, the second "stan" is the name of my current working directory, and "_" represents the cursor.

The prompt is set by the environmental variable called PS1.  To display the current setting, I can use:

echo $PS1

The system-wide setting of the prompt (for all users on the system) is in the file /etc/bashrc which on my system contains such a line:

PS1="[\u@\h \W]\$ "

To customize the prompt, I can edit the file /etc/bashrc (as root) and insert almost any text inside the quotation marks. Here is the meaning of some special codes I may also choose to use:

\u   -    username of the current user (= $LOGNAME),
\h   -    the name of the computer running the shell (hostname),
\H   -    entire hostname,
\W   -    the base of the name of the current working directory,
\w   -    the full name of the current working directory,
\$   -    display "$" for normal users and "#" for the root,
\!   -    history number of the current command,
\#   -    number of the current command (as executed in the current shell),
\d   -    current date,
\t   -    current time (24-hr),
\T   -    current time (12-hr) - bash 2.0 only,
\@   -    current time (AM/PM format) - bash 2.0 only,
\s   -    name of the shell,
\a   -    sound alarm (beep),
\j   -    number of jobs the user has,
\n   -    new line,
\\   -    backslash,
\[   -    begin a sequence of non-printable characters,
\]   -    end a sequence of non-printable characters,
\nnn -    the ASCII character corresponding to the octal number nnn.
$(date) - output from the date command (or any other command for that matter),

Here is an example on how to add colour. See the next chapter for details about colour:

PS1="\[\033[1;32m\][\u@\h \W]\$\[\033[0m\] "

There is also the second-level prompt, set by a variable called PS2. The shell uses the second level prompt when it expects additional input, and on my system the secondary prompt is "> ". I don't worry too much about PS2, but if I did I could set it the same way as PS1. There are even PS3 and PS4, but these are rarely seen.

3.4.3  Colour on text terminal

Colour on the text terminal can be produced using the "ANSI escape sequences". For example:

echo -e "\033[44;37;5m ME \033[0m COOL"

The above sets the background to blue, foreground white, blinking video, and prints " ME ", then resets the terminal back to defaults and prints " COOL".  The "-e" is an option specific to the echo command--it enables the interpretations of the special characters. The "\033[" introduces the escape sequence. The "m" means "set attribute" and thus finishes the sequence. The actual codes in the example above are "44;37;5" and "0".

Change the "44;37;5" to produce different colour combinations--the number/order of codes do not matter.  The codes to choose from are listed below:

Code  Action/Color
 0    reset all attributes to their defaults
 1    set bold
 2    set half-bright (simulated with color on a color display)
 4    set underscore (simulated with color on a color display)
 5    set blink
 7    set reverse video
22    set normal intensity
24    underline off
25    blink off
27    reverse video off
30    set black foreground
31    set red foreground
32    set green foreground
33    set brown foreground
34    set blue foreground
35    set magenta foreground
36    set cyan foreground
37    set white foreground
38    set underscore on, set default foreground color
39    set underscore off, set default foreground color
40    set black background
41    set red background
42    set green background
43    set brown background
44    set blue background
45    set magenta background
46    set cyan background
47    set white background
49    set default background color

Other interesting codes:

\033[2J      clear screen
\033[0q      clear all keyboard LEDs (won't work from Xterm)
\033[1q      set "Scroll Lock" LED
\033[2q      set "Num Lock" LED
\033[3q      set Caps Lock LED
\033[15;40H  move the cursor to line 15, column 40
\007         bell (beep)

LEDs (="Light Emitting Diods) are the lights on the keyboard which indicate if <CapsLock>, <NumLock> and <ScrollLock> are engaged.

See man console_codes for more.

3.4.4 How do I print symbols on the console, in a text mode application, and in X?

The procedure described here may give me fast access to the PC extended character set (codes 128-255) and is quite portable in the PC world:  it works in MS Windows, DOS (if you have an ANSI driver installed), and inside any text mode Linux application (including right on the shell command line).  I found it was worth my time to memorize the codes for the few characters I tend to use the most.
It works like this. Make sure that <NumLock> is on. Then press <Alt> and hold it. While <Alt> is pressed, key in on the numeric keypad these four digits: 0181. Now release <Alt> and the Greek letter mu "µ" appears.   I find quite useful the following characters from the PC character set encoding: 176 ° (degree), 177 ± (plus minus), 178 ² (square), 179 ³ (power 3), 181 µ (Greek mu), 0183 · (multiplication sign), 232 è  (French accent agrave), 233 é (French accent aigu) 228  ä (German a-umlaut), 243 ó (Polish u-zamkniete), 248 ø (Scandinavian o-bar) 252 ü (German u-umlaut). Some other characters are also possible, here is the full listing:

128 ? 147 ? 166 ¦ 185 ¹ 204 Ì 223 ß 242 ò
129 ? 148 ? 167 § 186 º 205 Í 224 à 243 ó
130 , 149 * 168 ¨ 187 » 206 Î 225 á 244 ô
131 f 150 - 169 © 188 ¼ 207 Ï 226 â 245 õ
132 ? 151 - 170 ª 189 ½ 208 Ð 227 ã 246 ö
133 ? 152 ~ 171 « 190 ¾ 209 Ñ 228 ä 247 ÷
134 ? 153 ? 172 ¬ 191 ¿ 210 Ò 229 å 248 ø
135 ? 154 s 173 ­ 192 À 211 Ó 230 æ 249 ù
136 ^ 155 > 174 ® 193 Á 212 Ô 231 ç 250 ú
137 ? 156 ? 175 ¯ 194 Â 213 Õ 232 è 251 û
138 S 157 ? 176 ° 195 Ã 214 Ö 233 é 252 ü
139 < 158 ? 177 ± 196 Ä 215 × 234 ê 253 ý
140 ? 159 Y 178 ² 197 Å 216 Ø 235 ë 254 þ
141 ? 160   179 ³ 198 Æ 217 Ù 236 ì 255 ÿ
142 ? 161 ¡ 180 ´ 199 Ç 218 Ú 237 í
143 ? 162 ¢ 181 µ 200 È 219 Û 238 î
144 ? 163 £ 182 ¶ 201 É 220 Ü 239 ï
145 ? 164 ¤ 183 · 202 Ê 221 Ý 240 ð
146 ? 165 ¥ 184 ¸ 203 Ë 222 Þ 241 ñ

Now, if I really want to, I can  have a file with a name µm·°C±b³. MS Windows, DOS ANSI, and Unicode differ slightly in some of the above characters, but the useful "core" remains the same.  See if you want to know the details of the differences. Linux uses the Unicode standard.

Under X, the above key combinations will not work. But I may use:




to select a Unicode character and copy it into my application. Not all unicode characters are available yet, but many are.  From Unicode pages other than page 0, the characters may display or not, depending on your application and the availability of the glyph in your font. For example, I can surely use the following characters in most KDE applications (if they display on your browser, depends on your browser AND the availability of a suitable Unicode font):

Greek (Unicode page 3, char 913 to 969): ???????????? ????????????????? ????????????????? ???????????
Russian: (Unicode page 4, chars 1040 to 1103): ????????? ????????????? ????????????? ????????????? ?????????????? ??
and many others. You can find common Unicode codes (numerical) and their html symbolic ("character entity") references at

3.4.5 How do I write a simple shell script?

Create a text (ASCII) file which will contain the shell script. For example, I would use the pico editor to write a script that runs the program tar with all the parameters usually necessary to uncompress tarballs downloaded from the Internet (I never seem to remember the tar options). I decided to call my script "untar":

pico untar

Since the file "untar" did not exist in my current directory, it was created by the pico text editor.  Now, I type in the content of my script:

echo this is the script file $0
echo untarring the file $1
# this calls tar with options -xvzf (extract,
#    verbose, filter through gzip, input filename)
tar -xvzf $1

I save the file with <Ctrl>o and exit with <Ctrl>x

The first line of the script, starting with "#!" (called pound-bang), is special--it tells the shell what program should be used to interpret my script. In this example, the script is to be interpreted by the bash shell /bin/bash .  The first line must start with #!  or the script will never run (the file will be interpreted as just a text file).  Other lines starting with # are comments for the author (readers, users) of the shell and are totally ignored by the computer.

The $0, $1, $2 ... in my script are the parameters passed to my script.  For example, if I ran a script called "myscript" with seven parameters like this:

myscript a b c d e f g

then $0 would be seen inside "myscript" as having the value "myscript", $1 would have the value "a",  $2 would be "b",  $3 would be "c", etc.
On the second and third line of my example script, the command echo prints on the screen everything that follows on the same line, expanding $0 and $1 to the values of the parameters passed to the script.  The fourth and fifth line contains a comment I wrote to myself to remind myself what I was trying to achieve, just in case I ever had to modify my script. The last line performs the actual work.
Once the script is written, I make the file executable to the file owner ("u"=user):

chmod u+x untar

and my script is ready to run like this:
./untar my_tar.tar.gz

Linux scripting is definitely rich, flexible, powerful and can be complex. However, it does not require special knowledge to write simple scripts for automation of common tasks. You just put together a group of often used commands, one by one, into a file.  I use scripting because I am too lazy to type the same groups of commands over and over again.

A really simple sequence of commands can also be typed into a text file and passed to shell for straight execution using:

source my_file

[No need for the initial "pound bang" or executable permission.]

3.4.6 Meaning of quotes

Normally, these characters are special to the shell:

\ ' " ` < > [ ] ? | ; #  $  ^ & * ( ) = <Space> <Tab> <Newline>

There are four different types of quotes: backslash (\), single quotes (apostrophes, '), double quotes (quotation marks, "),  and backquotes (`).

The backslash \ means: disable the special meaning of the subsequent character.

Quoting with '' (two apostrophes) means:  quote exactly, disabling any special characters inside the quotes.

Quoting with "" means:  disable the special characters inside the quotes except for $ ` \

The pair `` (two backquotes) means:  do a command substitution inside the backquotes first. So what is inside the backquotes is executed by the shell first, and then the output is passed to the command outside the quotes.  The same can also be acomplished with $(command) which nests better than backquotes.

Examples. I can create a funny directory called "*" by either \ quoting or '' quoting:

mkdir \*
mkdir '*'

This hides the special meaning of the "*" from the shell (without the quote it would mean "all files in the current directory").

3.4.7 Input/output redirection

There are three important  input-output streams: standard input ("stdin"), standard output ("stdout"), and standard error output ("stderr"). They all default to the console ("console" means the keyboard for the input and the screen for the output), but they can be redirected.

To redirect the standard output I use ">". For example:

dir my_dir > filelisting.txt

will redirect the standard output of the dir command into the textfile filelisting.txt and nothing should appear on my screen. The file can be subsequently edited (e.g. with pico filelisting.txt) or embedded into a document.

To redirect the standard error, I need to use the construct "2>". For example:

dir my_dir 2> errorlisting.txt

The above will send the normal output onto the screen and nothing to the file unless  dir produces an error. On error, nothing may go to my screen, and the file errorlisting.txt will contain the error message, which might be something like:

dir: my_dir: Permission denied

Finally, I can redirect both standard output and standard error to a file using:

dir my_dir > file_and_error_listing.txt 2>&1

which first redirects the standard output to a textfile, and then redirects the standard error to the same location as the standard output.  A bit twisted, how it works, but it works.

In the examples above,  if the file (to which to redirect) already existed, it will be overwritten. To append to an existing file, I use ">>" as in these examples:

dir my_dir >> filelisting.txt
dir my_dir 2>> errorlisting.txt
dir my_file >>file_and_error_listing.txt 2>&1

If you are puzzled by the "2>" symbol, here, briefly, is how to rationalize it. The standard streams have standard descriptors. "0" is standard input, "1" standard output and "2" is standard error.

dir my_dir > file.txt

is short for 

dir my_dir 1> file.txt

and therefore the example below redirects the standard error: 

dir my_dir 2> file.txt

One can also use the symbol "|" to send ("pipe") the output from one command as input for another command. In this popular example, the output from dir is piped to more (more pauses the display after each screenful):

dir | more

One can also split the output so it goes both to a file and the screen using "tee":

dir | tee filelisting.txt

It is called "tee" by the analogy to the "T"-letter-shape fitting that pipefitters use, and which divides flow.

This section so far dealt with redirecting standard output. Redirecting standard input is not nearly as useful as redirecting the output, but it can be done using a construct like this:

cat < my_file

There is also something called in-line redirection of the standard output, realized with "<<". Forget about it, seems of no use to me. Yet, here is an example if you really ever needed it  (here, the ">" stands for the secondary prompt): 

cat << my_marker
> my_line_from_the_keyboard
> another line_from_the_keyboard
> my_marker  [the marker of my choice ends the in-line redirection].

Apart from redirection to regular files and "filters" (as shown in the examples above), one can redirect to/from devices and other special files. Some examples follow.

An example of redirection to a device file. The following command displays the listing of files on the fourth text terminal:

dir > /dev/tty4

An example of redirection to a special "FIFO" file. This command sends the message "you are lucky" to the lucky ICQ user UIN 77777777 (assuming you are connected to the icq server with your licq program):

echo message 77777777 "you are lucky" > ~/.licq/licq_fifo

The above works because the file "licq_fifo" in your licq directory is a special "fifo" (first-in-first-out) queue file.  How could the above ever be more useful than sending a message using the pretty licq GUI front-end? For example, you could write a short script to impress fellow icq users with multiple (identitcal) messages:

echo Messaging UIN:  $1  Message:  $2   Times: $3
# The next command puts puts your licq in the status "on-line, invisible".
echo 'status *online' > ~/.licq/licq_fifo
while  [ $c -le $3]
echo message $1 $2 > ~/.licq/licq_fifo
c=`expr $c + 1`
echo $c " "
echo 'status offline' > ~/.licq/licq_fifo
echo "all done"

The above example may give you an idea how one can use licq for automation, owing to the smart licq communication model (the fifo file) and simple file redirection.

3.4.8 Shell special characters (metacharacters)

Normally, these characters have special meaning to the shell:

\ ' " ` < > | ; <Space> <Tab> <Newline> ( ) [ ] ? # $ ^ & * =

Here is the meaning of some of them:

\  ' "  and are used for quoting and were described before.

<  and  >   are used for input/output redirection and were described before.

| pipes the output of the command to the left of the pipe symbol "|" to the input of the command on the right of the pipe symbol.

separates multiple commands written on a single line.

<Space> and <Tab>  separate the command words.

<Newline>  completes a command or set of commands.

( )  enclose command(s) to be launched in a separate shell (subshell). E.g. ( dir ).

{ } enclose a group of commands to be launched by the current shell. E.g. { dir }. It needs the spaces.

&  causes the preceding command to execute in the background (i.e., asynchronously, as its own separate process) so that the next command does not wait for its completion.

*   when a filename is expected, it matches any filename except those starting with a dot (or any part of a filename, except the initial dot).

when a filename is expected, it matches any single character.

[ ]  when a filename is expected, it maches any single character enclosed inside the pair of [ ].

&&  is an "AND" connecting two commands.

command1 && command2 will execute command2 only if command1 exits with the exit status 0 (no error).  For example: cat file1 && cat file2 will display file2 only if displaying file1 succeeded.
||   is an "OR" connecting two commands.
command1 || command2 will execute command2 only if command1 exits with the exit status of non-zero (with an error).  For example: cat file1 || cat file2 will display file2 only if displaying file1 didn't succeed.
=  assigns a value to a variable.
Example. This command:
assigns the value "blahblah" to the variable called "me". I can print the name of the variable using:
echo $me
$    preceeds the name of a variable to be expanded.
The variables are either assigned using  "="  or are one of the pre-defined variables (which cannot be assigned to):
$0  name of the shell or the shell script being executed.
$# number of the positional parameters to the command
$1  the value of the first positional parameter passed to the command. $2 is the second positional parameter passed to the command. etc. up to $9.
$*    expands to all positional parameters passed to the command
$@   expands to all positional parameters passed to the command, but individually quoted when "$@" is used.
See man bash if you really need more.

3.5  Package installation and rpm package manager

3.5.1 How do I install a program I downloaded from the Internet?

The answer depends on what kind of package you downloaded. You can avoid many installation headaches if you download programs in the form of Red Hat binary packages *.rpm (that's the format I select if given a choice).


If the program I want to install is a RedHat binary package (*.rpm),  I can use either a command line, or a GUI utility. I like to use the command-line utility because it is fast and trouble-free.  The RedHat package manager installation utility is called rpm . First I read the info on the package content (optional):

rpm -qpi my_new_file.rpm

This queries (mode "q", must be the first letter after the dash) the yet uninstalled package (option "p") so that it displays the info (option "i") which the package contains.  If I want to install the program, I run (as root):

rpm -ihv my_new_file.rpm

The above command does the installation job. It runs rpm telling it to install the package (mode "i", must be the first letter after the dash) while printing to the screen more information than usual (option "h"=display "hashes" to show the unpacking progress, option "v"  = be verbose).  The contents of the package are distributed to the directories where they belong (rpm knows where they belong).  After this installation, the program is ready to run, I just have to know the executable name and its location.  If I have trouble finding the executable, this lists all the files that the package contains together with their destination directories:

rpm -qpl my_new_file.rpm

This queries (option "q") the yet uninstalled package (option"p") so that it displays the listing (option "l") of all the files the package contains.

The GUI front-ends to rpm are: gnopro (the old version, that comes with RH6.0 is confusing, but newer versions are much improved), kpackage (available only with the more recent distributions), and the old glint (very slow, comes with RH5.2).

Troubleshooting. rpm is supposed to be an intelligent software package manager. If the installation fails I read the error message and may be able to figure what to do:
(1) Installation failed because I have an earlier version of the same package and the versions confilict. Solution: don't install, but "upgrade" the package. 

rpm -Uvh my_new_file.rpm

(2) Installation failed because another package is needed first. I have to find the missing package and install it first, and then retry the installation. In extreme cases, I may choose to ignore the missing dependencies (I really should know what I am doing here else the software may malfunction): 

rpm -ivh --nodeps my_new_file.rpm

or perhaps even: 

rmp -ivh --nodeps --force my_new_file.rpm


If what I downloaded from the net is a Linux source code in the form of a compressed tarball (*.tar.gz or *.tgz), the installation procedure is longer and more troublesome than with the binary-only rpm. I typically install the program as root.

First, I change my current working directory to /usr/local  :

cd /usr/local

, I decompress the tarball that I downloaded from the net:

tar -xvzf /home/the_dir_where_the_tarball_is/my_tarball.tar.gz

This extracts (option "x") the contents of the *.tar.gz (or *.tgz) tarball, unzips it (option "z"), while talking to me more than usual (option "v" = verbose).  Please note that the option "f" means "file", so the filename must immediately follow the letter "f".  The contents of the tarball are extracted into a subdirectory which tar creates under my current working directory, which in the typical case is /usr/local/ .  The tarball knows what the new subdirectory should be called.

If the tarball is not compressed (e.g., *.tar), I may use:

tar -xvf /home/the_dir_where_the_tarball_is/my_tarball.tar

Third, I have to figure how the new directory is called, then I cd into it:

cd the_new_program_subdir

Since some of the directories have long names, I use the great autocompletion option to save on typing--I just type the first few letters and then press <TAB> .

Fourth, most programs are compiled by executing these three commands:

make install

The above commands can take some time to complete (1 min? 0.5 h?). If any of them fail, it might be an idea to read the README or INSTALL or whatever info is provided with the new program. Some programs may require customization of the environment (e.g. definition of their path) or installation of an additional library, or yet something else. It can sometimes be a pain. Very simple programs might not need the "./configure" or/and "make install" step, in which case "make" alone will do.

Fifth, if everything goes well, I find the new executable which I just compiled. The names of executables display in green when running this command:

ls --color

Now, I can run the executable, for example:


Some programs automatically install the executable to /usr/local/bin, so I may want to try:


Sixth, if I plan to run the program more often, I create a symbolic link to the executable from the directory /usr/local/bin :

cd /usr/local/bin
ln -s /usr/local/the_new_program_subdir/the_executable .

This way, the executable (actually, a symbolic link to it) is on my PATH and it can be run by simply typing its name (no need to type the full path to the executable any more). Some programs will install the executable (or a link to it) in a "bin" directory in which case you skip the last step.


o There are also programs distributed as "source code rpm" packages. They require installation of the *.rpm package with the "rpm" utility as described in the first part of this chapter. But since the "rpm" installs the source code (typically in the C language source code), I then have to compile the source code by executing the same: "./configure ;  make ; make install" sequence as for the sourcecode distributed as tarballs (see the previous answer).

Go to Part 4.1:  Startup Issues (LILO and GRUB)
Back to the Main Index