52890.fb2
In order to maintain your system effectively, it's necessary to learn some basic system management skills. This chapter covers these essential skills.
With a small investment in time, you'll be able to adjust your system configuration, keep the filesystem under control, disable unused services, and identify and stop rogue processes. I'll cover the basics of performing these operations using both graphical and command-line tools, both locally and remotely.
Many system management tasks can be performed using either of the graphical user interfaces provided with Fedora (i.e., GNOME or KDE). However, most power users prefer the command line for system management work because they find it faster, more consistent between different versions of Linux, and easier to access remotely. The command line is also called a shell prompt , because the commands are processed by a program called a shell; the standard shell on a Fedora system is the Bourne-again shell ( bash ).
If you are logged in to the system through the graphical user interface, access the command line through the terminal program. Select the menu option Applications→Accessories→Terminal (System→Terminal in KDE), or right-click on the desktop background and select Konsole under KDE.
If you find yourself using the terminal frequently, you can make it easier to launch: right-click on the Terminal option in the application menu and select "Add this launcher to panel." A new panel icon will appear that will launch a new terminal when clicked.
If you have logged in to the system through a character-mode login screen or an SSH login, you will automatically be presented with a command line.
The standard shell prompt looks like this:
[chris@concord2 ~]$
This message is an invitation to enter a command. It shows the name of the user ( chris ), the computer being used ( concord2 ), and the current working directory within the filesystem ( ~ , meaning the user's home directory). The last character of the prompt, $ , indicates that this is a normal user's prompt, as opposed to the system administrator's prompt, which ends with # .
To enter a command, simply type it, and then press Enter to execute it. The output from the command will appear after the command (scrolling the screen if necessary), and when the command is done a new prompt will be printed.
To edit a command line, use the left and right arrow keys to position within the line, and the Backspace and Delete keys to delete characters to the left or right of the cursor, respectively. To insert text, simply type it. You can press Enter with the cursor located anywhere on the line to execute the command. Other editing keys are available; Table 4-1 shows the most useful ones.
Table 4-1. Useful editing keys
Key or key sequence | Description |
---|---|
Left arrow | Move left one character. |
Right arrow | Move right one character. |
Backspace | Delete the character to the left of the cursor. |
Delete | Delete the character under/to the right of the cursor. |
Ctrl-U | Delete to the start of the line. |
Ctrl-left arrow | Move one word to the left. |
Ctrl-right arrow | Move one word to the right. |
Esc, DAlt-D | Delete to the end of the current word. |
Esc, BackspaceAlt-Backspace | Delete to the start of the current word. |
HomeCtrl-A | Go to the start of the line. |
EndCtrl-E | Go to the end of the line. |
You can scroll through the history of previously entered commands using the up and down arrow keys. This enables you to easily re-enter a command, either exactly as you previously entered it or after editing.
You can also search for a previous command by pressing Ctrl-R (for reverse search ) and then typing a few characters that appear in the command. For example, if you had at some previous point typed cat /etc/hosts and you pressed Ctrl-R and typed hos , the cat /etc/hosts command would appear (providing that no intervening commands contained the letter sequence hos ).
The superuser account, root , is also called the privileged account, because it is not subject to the security restrictions that are applied to regular user accounts. root access is required for many system administration commands. Although it's tempting to use the root account all the time on a single-user computer, it is unwise because Fedora assumes that you know what you're doing and won't ask for confirmation if you enter a dangerous command; it will just go ahead and execute it. If you're using the root account, an incorrect command can cause a lot more damage than the same command executed in a normal account.
Although you can directly log in as a root user, it's usually much safer to take on root privilege only when necessary, using the su (switch user) command:
$ su
Password:
root-password
#
The shell prompt will change to end in a pound sign ( # ) instead of a dollar sign ( $ ) when you are in root mode. Press Ctrl-D or type exit to drop superuser access and return to your regular shell prompt.
In this book, I'll use $ to indicate any normal user's prompt, user $ to specifically indicate user's prompt, and # to indicate the root prompt. Avoid entering commands as root unnecessarily!
Many Linux commands will output a message only if something goes wrong. For example, if you try to remove a file using the rm command, no message will be displayed if the file is successfully deleted, but an error message will be generated if the file does not exist:
$ rm barbeque
rm: cannot remove \Qbarbeque ': No such file or directory
Most error messages start with the name of the command that produced the message.
You can leave a shell by pressing Ctrl-D or typing exit . If you are using a terminal window and don't have any programs running, you can simply close the window using the X button on the title bar.
The shell prompt is managed by bash , the Bourne-again shell. bash got its name from the fact that it is a successor to the original Unix shell, sh , which is also known as the Bourne shell (after its author, Steve Bourne). bash is a command editor, command interpreter, job controller, and programming language.
When bash receives a command, it splits it into words and uses globbing to expand any ambiguous filenames. bash next checks to see if the first word is a built-in command. If not, it treats it as an external command or program and searches a list of directories to find that program. It executes that program, passing the other words to the program as arguments. Almost all Linux commands are external programs.
Linux commands generally accept three types of arguments:
Options
These start with a hyphen or double-hyphen ( - or -- ) and modify the way the command operates. For example, the ls (list-files) command will include hidden files in its output if the -a argument is given, and will list detailed information about files when the -l option is specified. These options may be used individually, used together in any order, or combined after one hyphen if they all use a single hyphen:
$ ls -l
$ ls -a
$ ls -l -a
$ ls -a -l
$ ls -al
$ ls -la
Positional arguments
These have significance according to the order in which they are specified. For example, the cp (copy) command accepts two or more filenames:
$ cp one two
one is the name of the file being copied, and two is the name that will be given to the new copy. If you swap the position of the two arguments, the meaning of the command is changed. Options may be placed before, between, or after positional arguments; usually, the positions of the options don't matter.
Options with a value
These combine options with positional arguments. An option with a value may be placed before or after other arguments, but the value must be placed directly after the option.
For example, the ls command accepts the -w option (width of output), which is specified along with a number indicating the desired width of output in characters. This can be combined with the -a and -l options in any order, as long as the number immediately follows the -w option:
$ ls -a -l -w 60
$ ls -w 60 -al
$ ls -l -w 60 -a
$ ls -l -w60 -a
$ ls -alw60
Fedora is configured to allow you to log in using a character-mode display even if the graphical user interface is running. In fact, you can log in up to six times, using the same or different user IDs.
The key is Virtual Terminals (VTs). There are 12 virtual terminals that can be accessed easily: VT1 through VT6 are configured for character-mode login, VT7 is used for graphical login, and VT8 through VT12 are not normally used.
To switch to a specific VT, press Ctrl-Alt and the function key that corresponds to the virtual terminal you wish to access (Ctrl-Alt-F1 for VT1, Ctrl-Alt-F7 for VT7, etc.).
There are actually 64 virtual terminals, but virtual terminals above number 12 are not directly accessible from the keyboard and are therefore rarely used.
You can log in on multiple VTs simultaneously and switch back and forth between them. This is particularly useful when you bring up documentation on one VT and enter commands on another.
The type , which , and whereis commands all provide information about the location of programs.
type will tell you where a command is located in a verbose way, along with an indication of whether the command location is hashed (stored in the shell for quick reference because the command has already been used recently). If there is more than one command with the same name, the location shown is the first one found using your $PATH :
$ type cat
cat is hashed (/bin/cat)
which is similar, but shows only the command location:
$ which cat
/bin/cat
whereis will show you all of the locations for the command (and sometimes there are several, if different versions of the same program are installed), along with the location of its manpage documentation:
$ whereis cat
cat: /bin/cat /usr/share/man/man1p/cat.1p.gz /usr/share/man/man1/cat.1.gz
Programs with a graphical user interface are started in exactly the same way as programs with a character-based user interface. GUI-based programs use the DISPLAY environment variable to determine if a graphical display is available and to connect to that display. Some programs, such as system-config-printer , will automatically start up with a graphical or a character-based user interface according to the type of display that is available.
Typing Alt-F2 will open a Run Application dialog (in KDE, it's called Run Command), which enables you to enter a single command and run it. This is most useful for starting graphical programs that aren't on the menu.
You can also add an applet to your panel bar that does the same thing.
There isn't any! Linux does not make any distinction between categories of programs.
Fedora offers four different command shells: csh (a.k.a. tcsh ), bash (a.k.a. sh ), ksh , and zsh . You can temporarily start a different shell just by typing the shell name:
$ csh
Press Ctrl-D or type exit to return to the original shell. You can permanently change your default shell using the chsh (change shell) command:
$ chsh
Password:
bigsecret
New shell [/bin/bash]:
/bin/csh
Shell changed.
The password requested is your normal login password; the change will take effect the next time you log in.
chsh requires that you enter the full pathname of the new shell. To see a list of available shells, use chsh with the -l (list) option:
$ chsh -l
/bin/sh
/bin/bash
/sbin/nologin
/bin/ksh
/bin/tcsh
/bin/csh
/bin/zsh
zsh , ksh , and bash each use a syntax related to the original Bourne shell ( sh ). csh uses a very different syntax, which C programmers often find comfortable.
The bash , chsh , csh , zsh , and ash manpages
A fully loaded Fedora system includes over 4,700 programs, plus programming interfaces, data files, and graphical tools. To help you learn your way around, over 12,000 files of online documentation are available, with additional documentation available through the Web. Knowing how to access and knowledgeably navigate through this documentation is essential to getting the most out of your Fedora system.
The phrase online documentation refers to both local and Internet-based electronic documentation.
There are five main types of documentation available:
Manpages
info pages
The GNOME Guides and KDE Manuals
HOWTOs and guides from the Linux Documentation Project
Text files distributed with applications
Fedora continues the Unix tradition of providing an online version of what were originally loose-leaf printed manuals. These manuals cover the commands, programming interfaces, and data formats used by the system.
The command used to access these online manuals is called man , so these documents have come to be known as manpages . The majority of Fedora documentation is in this format.
The pages are arranged into sections according to the original binders, using the section numbers described in Table 4-2 . The section numbers are used to distinguish different manpages with the same name, such as the manpage for the uname system call (found in section 2) and the uname command (found in section 1). In some cases, a letter or two may be appended to a section number to indicate a subsection (such as 3pm , the manual section containing Perl module library functions).
A system call is a request made of the operating system by an application program.
Table 4-2. Section numbers for manpages
Section | Description |
---|---|
1 | User commands |
2 | System calls |
3 | Library functions |
4 | Special files |
5 | File formats |
6 | Games |
7 | Conventions and miscellany |
8 | Administration and privileged commands |
To view the manpage for a particular command, such as ls :
$ man ls
The output will appear as shown in Figure 4-1 . You can use the up and down arrow keys and the Page Up/Page Down keys to scroll through the text, or q to quit. You can also type / , enter some text, and press Enter to search for that text within the document; type n (lowercase n , for next ) to search again. ? and N (uppercase N ) can be used in the same way to search backwards.
Figure 4-1. Online display of a manpage
To request a manpage from a specific section of the manual, give the section as the first argument and the name of the manpage as the second argument:
$ man 2 uname
If you don't specify the section, the first section containing a page with the requested name is usedand since there is a uname page in section 1, you won't see the page from section 2 unless you specifically ask for it.
The -k argument of man is used to produce a list of all of the pages that contain a specific keyword in their short descriptions. For example, if you wanted to see all of the manpages that contained the word calendar in their summary:
$ man -k calendar
Date::Calc (3pm) - Gregorian calendar date calculations
Date::Calendar (3pm) - Calendar objects for different holiday schemes
Date::Calendar::Profiles (3pm) - Some sample profiles for Date::Calendar and
Date::Calendar::Year
Date::Calendar::Year (3pm) - Implements embedded year objects for Date::Calendar
cal (1) - displays a calendar
Note that the section number is in parentheses. If you were looking for a calendar command, you could ignore the results from section 3 of the manual (library functions), which leaves just one possibility: the cal command. You could then get more information about that command to see if it will do what you need :
$ man cal
apropos is another name for man -k. To my ear, it has more class!
To see all of the manpages with a specific name in all sections of the manual, use the whatis command:
$ whatis uname
uname (1) - print system information
uname (2) - get name and information about current kernel
In this case, you can see that there is a page for uname in section 1 and 2 of the manual.
The GNU project supplies most of its documentation in info documents rather than manpages. info documents are a unique form of hypertext and are read with a reader program named, not surprisingly, info :
$ info ls
info has many features and can be a bit overwhelming. Each document consists of nodes (analogous to web pages) that are linked together using menu options. The keys listed in Table 4-3 are sufficient for basic navigation.
Table 4-3. Basic navigation in info
Key | Description |
---|---|
Page Up/Page Down | Scroll through the text. |
p | Go to the previous node. |
n | Go to the next node. |
Tab | Jump to the next menu option in the current page. |
Enter (when the cursor is on a menu option) | Follow the menu option. |
Space | Go to the next page, or next node if there is no more text in the current node. |
l | Return to the last node accessed. |
To take a guided tour of info , type:
$ info info
GNOME and KDE each provide a general user's guide or manual, with specific chapters (or in some cases, separate manuals) for their various desktop tools.
To access these guides, just press F1 in a GNOME or KDE application. Alternately, select the System→Help (GNOME) or Help (KDE) menu options from the panel bar. The GNOME menu is connected to the GNOME documentation, and the KDE menu is connected to the KDE documentation. You can access the documentation for the other desktop environment from a command prompt; for GNOME documentation, use either of these commands:
$ gnome-help
$ yelp
For KDE documentation:
$ khelpcenter
Each of these tools also provides a graphical user interface for viewing manpages and info documents.
The Linux Documentation Project (TLDP) maintains a very helpful set of documents called HOWTO s, each of which describes the procedure to accomplish a specific task. They also publish some book-length guides . Most of these documents have been translated into multiple languages. However, these documents are generic and do not reflect the default configuration and packaging of Fedora.
The TLDP documentation can be found on the Web at http://www.tldp.org/ . TLDP also publishes FAQs and maintains links to online versions of the manpages and free Linux magazines.
Most open source software packages include a small number of text files written by the programmers, which include licensing information, change histories, errata and bug lists, and release notes. In Fedora these miscellaneous documents are placed in /usr/share/doc and are organized in directories by package name and version. For example, the notes for dia (a diagram-drawing application) are available in /usr/share/doc/dia-0.95 .
I find that the easiest way to view these documents is to use a web browser, which enables you to navigate among directories and view documents by simply clicking on them. To do this, just open the Firefox web browser and enter /usr/share/doc as the location.
To view these files from the shell prompt, change to the directory you wish to view, and then use ls to list names of the files and less to view the contents of any text files that interest you. For example, here are the steps you might take to view the dia text files:
$ cd /usr/share/doc
$ ls -d dia*
dia-0.95 dialog-1.0.20050306
$ cd dia-0.95
$ ls -l
total 724
-rw-r--r-- 1 root root 1578 Aug 16 2004 AUTHORS
-rw-r--r-- 1 root root 574015 Aug 17 2004 ChangeLog
-rw-r--r-- 1 root root 17992 Mar 12 2004 COPYING
-rw-r--r-- 1 root root 11364 Aug 16 2004 custom-shapes
-rw-r--r-- 1 root root 1620 Aug 16 2004 diagram.dtd
-rw-r--r-- 1 root root 3927 Aug 16 2004 INSTALL
-rw-r--r-- 1 root root 4955 Aug 16 2004 KNOWN_BUGS
-rw-r--r-- 1 root root 21535 Aug 17 2004 NEWS
-rw-r--r-- 1 root root 3444 Aug 16 2004 README
drwxr-xr-x 2 root root 4096 Sep 27 01:13 samples
-rw-r--r-- 1 root root 2324 Aug 16 2004 shape.dtd
-rw-r--r-- 1 root root 501 Aug 16 2004 sheet.dtd
-rw-r--r-- 1 root root 1379 Aug 19 2004 THANKS
-rw-r--r-- 1 root root 2545 Aug 16 2004 TODO
$ less KNOWN_BUGS
The less command will enable you to scroll through the specified file ( KNOWN_BUGS ) in the same way that you would move through a manpage, using the arrow keys and Page Up/Page Down keys to scroll and q to quit.
Note that this directory also contains a sample directory, which includes some sample files for use with the dia program.
The man command's -t option will format a page into PostScript; you can then send the PostScript output to your printer with the command lpr using a pipe. This command prints the manpage for ls :
$ man -t ls | lpr
It's easy to convert manpages into PDF or HTML formats.
For PDF, use the -t option with man and then pipe the PostScript output into the ps2pdf program. This command places the manpage for ls into the file ls_man_page.pdf :
$ man -t ls | ps2pdf - ls_man_page.pdf
The commands to convert a manpage to HTML are more complex:
$ zcat $(man --path ls ) | man2html | tail +3 > ls_man_page.html
This uses man --path to find the compressed, unformatted manual page; zcat to decompress the page; man2html to convert the page to HTML; and tail to strip off the unneeded httpd Content-type header.
Other sources of information about Fedora and Linux:
The Fedora Project at RedHat: http://fedora.redhat.com/
The Fedora Project Wiki: http://fedoraproject.org/wiki/
The Fedora Forums: http://www.fedoraforum.org/
Links to Linux-related news at LinuxToday: http://linuxtoday.com/
O'Reilly Network: http://www.oreillynet.com/
A large part of system administration involves dealing with files and directories: creating directories, copying files, moving files and directories around, and deleting them. Fedora provides a powerful set of tools for managing files from the shell prompt as well as graphically.
Linux, like most modern operating systems, uses a tree-like hierarchy to store and organize files. To manage files effectively, extend the hierarchy to organize your data.
Fedora's master directory (or folder , as it would be referred to by other operating systems) is called the root directory ; it may contain files and directories. Each of those directories may in turn contain other files and directories.
For each user, one directory is designated as the home directory , and that is where that user stores her personal files. Additionally, each process (a running copy of a program) has a current working directory on the system, which is the directory that it accesses by default unless another directory is explicitly specified.
The root directory is always the same system-wide; the home directory is consistent for a particular user, but varies from user to user; and the current working directory is unique to each process and can be changed anytime.
A pathname specifies how to find a file in the file hierarchy. There are three different pathname schemes that can be used, based on the three different starting points (root, home, and current working directory); each scheme specifies the path from the selected starting point to the desired file, separating directory names with the forward slash character ( / ). These three schemes are summarized in Table 4-4 .
Table 4-4. Absolute, Relative, and Relative-to-Home pathnames
Scheme | First characters of pathname | Relative to... | Example |
---|---|---|---|
Absolute | / | Root directory | /home/chris/book/chapter/one.odt |
Relative-to-Home | ~ | User's home directory | ~/book/chapter/one.odt |
~ chris | Home directory of chris | ~chris/book/chapter/one.odt | |
Relative | (Anything other than / or ~) | Current working directory | chapter/one.odt (Assuming that /home/chris/book is the current directory) |
The special symbols . (same directory) and .. (parent directory) are useful in pathnames. For example, if your current directory is /home/chris/book , then ../invitation refers to /home/chris/invitation.
Fedora uses a standard set of directories derived from historical conventions, the Linux Standard Base (LSB) project, and the kernel. Table 4-5 outlines the key directories and their purpose.
Table 4-5. Key directories in Fedora Core
Directory | Purpose |
---|---|
/bin | Basic binaries (programs) needed to start the system. |
/boot | Files used during the boot process, including the boot menu and kernel. |
/dev | This directory contains special files that are actually connections to devices, such as keyboards, mice, modems, printers, sound cards, and so forth. When you read data from a special file or write data to it, you're actually communicating with the associated device. |
/etc | System configuration files (sometimes regarded as the "home directory for the computer"). |
/home | Users' home directories, for the storage of personal files. |
/lib | Libraries. |
/lost+found | A directory used to recover files in the event of filesystem damage. Any file that has been disassociated from its name is placed here during filesystem recovery. |
/media | External media (floppy disks, USB drives, digital cameras, optical disks) that have been mounted. |
/mnt | Historical location for mounting storage devices, many of which have now moved to /media. |
/opt | Optional, add-on software. The definition of add-on software is subjective; if you obtain OpenOffice.org directly from the openoffice.org web site, it will be installed here, but if you install the version distributed with Fedora, it will be installed in /usr/bin. |
/proc | Per-process status information plus system information. |
/root | Home directory for the root user (superuser). |
/sbin | Basic system administration binaries. |
/selinux | Files for Security Enhanced Linux. |
/sys | System device information. |
/tmp | Temporary file storage. |
/usr | User data (years ago, home directories were also stored in /usr). |
/usr/bin | The remainder of the standard binaries. |
/usr/lib | User libraries. |
/usr/libexec | Programs that are not directly executed by the user but that are executed by another application (e.g., graphics demos for the xscreensaver program) |
/usr/local | Local files (specific to your system configuration). |
/usr/local/bin | Local binaries and scripts. |
/usr/sbin | The remainder of the system administration binaries. |
/usr/src | Source code for locally built RPM packages and the Linux kernel. |
/var | Files that change frequently (variable), including databases, print requests, and logfiles. |
/var/log | Various system logfiles. |
/var/spool | Files for various queues (spools), such as print queues and file-transfer queues. |
Local files refers to filesbinaries, scripts, and datafilesthat you have developed and that are not part of Fedora. Separating these files from the rest of the operating system makes it easier to move them to a new system in the future.
The wildcard characters ? and * can be used for pattern matching , which is useful for dealing with several files at a time without individually specifying each filename. ? will match any one character in a filename, and * will match any number of any characters (including none).
Square brackets [] can be used to contain a list of characters [123] , a range of characters [aj] , or a combined list and range [123aj] ; this pattern will match any one character from the list or range. Using an exclamation mark or carat symbol as the first character inside the square brackets will invert the meaning, causing a match with any one character which is not in the list or range.
Table 4-6 lists some examples of ambiguous filenames.
Table 4-6. Ambiguous filenames
Filename | Description | Matches | Does not match |
---|---|---|---|
a* | Any filename starting with a | absolutely.txt | Albert |
a.out | backup | ||
albert | _abc_ | ||
*x* | Any filename containing an x | xylophone.gif | constantinople |
nexus | ALEX | ||
old.x | |||
*[09] | Any filename ending in a digit | file3 | file |
menu.backup60 | file3a | ||
file3.txt | |||
416-555-1212.phone | |||
[Aa]???.txt | Any eight-character filename starting with a or A and ending in .txt | appl.txt | application.txt |
ax42.txt | a.txt | ||
Any1.txt | allow.txt | ||
[azAZ][09] | Any two-character filename starting with a letter and ending with a digit | a9 | No |
G7 | 7G | ||
N3 | XX | ||
Fortran77 | |||
[!azAZ]* | Any filename that does not start with a letter | 9lives.odt | abc.txt |
[^azAZ]* | _whatever | Nevermore |
Linux filenames can be up to 254 characters long and contain letters, spaces, digits, and most punctuation marks. However, names that contain certain punctuation marks or spaces cannot be used as command arguments unless you place quote marks around the name (and even then there may be problems). Linux filenames are also case-sensitive, so it's productive to adopt a consistent naming convention and stick to it.
Here are my recommendations for Linux filenames:
Build the names from lowercase letters, digits, dots, hyphens, and underscores. Avoid all other punctuation. Start the filename with a letter or digit (unless you want to specify a hidden file), and do not include spaces.
Although it makes command-line file manipulation more awkward, more and more users are adding spaces to photo and music filenames.
Use the single form of words instead of the plural ( font instead of fonts ); it's less typing, and you won't have to keep track of whether you chose the singular or plural form.
Filename extensions (such as .gif , .txt , or .odt ) are not recognized by the Linux kernel; instead, the file contents and security permissions determine how a file is treated. However, some applications do use extensions as an indication of file type, so it's a good idea to employ traditional extensions such as .mp3 for MP3 audio files and .png for portable network graphics files.
The ls (list-directory-contents) command will display a list of the files in the current working directory:
$ ls
4Suite crontab hosts libuser.conf nxserver
a2ps.cfg cron.weekly hosts.allow lisarc oaf
...(Lines snipped)...
You can specify an alternate directory or file pattern as an argument:
$ ls /
bin etc lost+found mnt proc sbin sys usr
boot home media net ptal selinux tftpboot var
dev lib misc opt root srv tmp
$ ls -d a*
a2ps.cfg alsa ant.conf audit.rules
a2ps-site.cfg alternatives ant.d auto.master
acpi amanda asound.state auto.misc
adjtime amandates atalk auto.net
alchemist amd.conf at.deny auto.smb
aliases amd.net atmsigd.conf
aliases.db anacrontab auditd.conf
By default, filenames starting with a dot ( . ) are not shown. This provides a convenient way to store information such as a program configuration in a file without constantly seeing the filename in directory listings; you'll encounter many dot files and directories in your home directory. If you wish to see these "hidden" files, add the -a (all) option:
$ ls -a
ls can display more than just the name of each file. The -l (long) option will change the output to include the security permissions, number of names, user and group name, file size in bytes, and the date and time of last modification:
$ ls -l
-rw------- 1 chris chris 3962 Aug 29 02:57 a2script
-rwx------ 1 chris chris 17001 Aug 29 02:57 ab1
-rw------- 1 chris chris 2094 Aug 29 02:57 ab1.c
-rwx------ 1 chris chris 884 Aug 29 02:57 perl1
-rw------- 1 chris chris 884 Aug 29 02:57 perl1.bck
-rwx------ 1 chris chris 55 Aug 29 02:57 perl2
-rw------- 1 chris chris 55 Aug 29 02:57 perl2.bck
-rwx------ 1 chris chris 11704 Aug 29 02:57 pointer1
-rw------- 1 chris chris 228 Aug 29 02:57 pointer1.c
-rwx------ 1 chris chris 12974 Aug 29 02:57 pp1
-rw------- 1 chris chris 2294 Aug 29 02:57 pp1.c
ls -l is so frequently used that Fedora has a predefined alias (shorthand) for it: ll.
You can also sort by file size (from largest to smallest) using -S :
$ ls -S -l
-rwx------ 1 chris chris 17001 Aug 29 02:57 ab1
-rwx------ 1 chris chris 12974 Aug 29 02:57 pp1
-rwx------ 1 chris chris 11704 Aug 29 02:57 pointer1
-rw------- 1 chris chris 3962 Aug 29 02:57 a2script
-rw------- 1 chris chris 2294 Aug 29 02:57 pp1.c
-rw------- 1 chris chris 2094 Aug 29 02:57 ab1.c
-rwx------ 1 chris chris 884 Aug 29 02:57 perl1
-rw------- 1 chris chris 884 Aug 29 02:57 perl1.bck
-rw------- 1 chris chris 228 Aug 29 02:57 pointer1.c
-rwx------ 1 chris chris 55 Aug 29 02:57 perl2
-rw------- 1 chris chris 55 Aug 29 02:57 perl2.bck
The first character on each line is the file type: - for plain files, d for directories, and l for symbolic links.
There are dozens of options to the ls command; see its manpage for details.
To print the name of the current working directory, use the pwd (print-working-directory) command:
$ pwd
/home/chris
To change the directory, use the cd (change-directory) command.
To change to the /tmp directory:
$ cd /tmp
To change to the foo directory within the current directory:
$ cd foo
To change back to the directory you were in before the last cd command:
$ cd -
To change to your home directory:
$ cd
To change to the book directory within your home directory, regardless of the current working directory:
$ cd ~/book
To change to jason 's home directory:
$ cd ~ jason/
To create a directory from the command line, use the mkdir command:
$ mkdir newdirectory
This will create newdirectory in the current working directory. You could also specify the directory name using an absolute or relative-to-home pathname.
To create a chain of directories, or a directory when one or more of the parent directories might not exist, use the -p (path) option:
$ mkdir -p foo/bar/baz/qux
This has the side effect of turning off any warning messages if the directory already exists.
To delete a directory that is empty, use rmdir :
$ rmdir newdirectory
This will fail if the directory is not empty. To delete a directory as well as all of the directories and files within that directory, use the rm (remove) command with the -r (recursive) option:
$ rm -r newdirectory
rm -r can delete hundreds or thousands of files without further confirmation. Use it carefully!
To copy a file, use the cp command with the source and destination filenames as positional arguments:
$ cp /etc/passwd /tmp/passwd-copy
This will make a copy of /etc/passwd named /tmp/passwd-copy . You can copy multiple files with a single cp command as long as the destination is a directory; for example, to copy /etc/passwd to /tmp/passwd and /etc/hosts to /tmp/hosts :
$ cp /etc/passwd /etc/hosts /tmp
In Linux, renaming and moving files are considered the same operation and are performed with the mv command. In either cases, you're changing the pathname under which the file is stored without changing the contents of the file.
To change a file named yellow to be named purple in the current directory:
$ mv yellow purple
To move the file orange from jason 's home directory to your own:
$ mv ~jason/orange ~
The rm command will remove (delete) a file:
$ rm badfile
You will not be prompted for confirmation as long as you are the owner of the file. To disable confirmation in all cases, use -f (force):
$ rm -f badfile
Or to enable confirmation in all cases, use -i (interactive):
$ rm -i badfile
rm: remove regular empty file \Q
badfile
' ?
y
-f and -i can also be used with cp and mv .
The graphical desktop tools don't directly delete files; they relocate them to a hidden directory named ~/.Trash, which corresponds to the desktop Trash icon, where they stay until the Empty Trash option is chosen. You can do the same thing from the command line:
$ mv badfile ~/.Trash
Linux systems store files by number (the inode number ). You can view the inode number of a file by using the -i option to ls :
$ ls -i /etc/hosts
3410634 /etc/hosts
A filename is cross-referenced to the corresponding inode number by a link and there's no reason why several links can't point to the same inode number, resulting in a file with multiple names.
This is useful in several situations. For example, the links can appear in different directories, giving convenient access to one file from two parts of the filesystem, or a file can be given a long and detailed name as well as a short name to reduce typing.
Links are created using the ln command. The first argument is an existing filename (source), and the last argument is the filename to be created (destination), just like the cp and mv commands. If multiple source filenames are given, the destination must be a directory.
For example, to create a link to /etc/passwd named ~/passwords , type:
$ ln /etc/passwd ~/passwords
The second column in the output from ls -l displays the number of links on a file:
$ ls -l electric.mp3
-rw-rw-r-- 1 chris chris 23871 Oct 13 01:00 electric.mp3
$ rm zap.mp3
$ ln electric.mp3 zap.mp3
$ ls -l electric.mp3
-rw-rw-r-- 2 chris chris 23871 Oct 13 01:00 electric.mp3
Although these types of links, called hard links , are very useful, they suffer from three main limitations:
The target (file being linked to) must exist before the link is created.
The link must be on the same storage device as the target.
You cannot link to directories.
The alternative to a hard link is a symbolic link , which links one filename to another filename instead of linking a filename to an inode number. This provides a work-around for all three of the limitations of hard links.
The ln command creates symbolic links when the -s argument is specified:
$ ls -l ants.avi
-rw-rw-r-- 1 chris chris 1539071 Oct 13 01:06 ants.avi
$ ln -s ants.avi ants_in_ant_farm.avi
$ ls -l *ants*
-rw-rw-r-- 1 chris chris 1539071 Oct 13 01:06 ants.avi
lrwxrwxrwx 1 chris chris 8 Oct 13 01:06 ants_in_ant_farm.avi -> ants.avi
Notice that the the link count on the the target does not increase when a symbolic link is created, and that the ls -l output clearly shows the target of the link.
The file command will read the first part of a file, analyze it, and display information about the type of data in the file. Supply one or more filenames as the argument:
$ file *
fable: ASCII text
newicon.png: empty
passwd: ASCII text
README: ASCII English text
xpdf.png: PNG image data, 48 x 48, 8-bit/color RGBA, non-interlaced
You can display the contents of a text file using the cat command:
$ cat README
Dia is a program for drawing structured diagrams.
...(more)...
If you accidentally cat a non-text file, your terminal display can get really messed up. The reset command will clear up the situation:
,l*l<lL\xe2 ,,<lFL<<<G\\l<lGRL<l\xe2 \xf5 <L,l<lLl\LLLl<*]US]$$][]UWVS[ j)Eue[^_1PuuuG;re[^_UUSR@t@CuX[USP[n X[xG hG6QGListxG!GN9Akregator11ApplicationE <L\L 2hLl\xe2 \xf5 [&&*CS@&*_^-&@$#D]$ reset[chris@concord2 ~]$
To display only the top or bottom 10 lines of a text file, use the head or tail command instead of cat .
If the text file is too big to fit on the screen, the less command is used to scroll through it.
$ less README
You can use the up and down arrow keys and the Page Up/Page Down keys to scroll, and the q key to quit. Press the h key for help on other options, such as searching.
GNOME's file manager is named Nautilus and it permits simple drag-and-drop file management.
When you are logged in to GNOME, Nautilus is already running as part of the desktop environment. To open a Nautilus window, double-click on the Home icon on your desktop or select a folder from the Places menu. A window will appear, such as the one shown in Figure 4-2 , showing each file as an icon. Emblems overlaid on the icons are used to indicate the file status, such as read-only .
Figure 4-2. Nautilus file management window
By default, Nautilus uses a spatial mode, which means that each directory will open in a separate window, and those windows will retain their position when closed, re-opening at the same location when you access them later.
You can open child directories by double-clicking on them, or you can open a parent directory using the pull-down menu in the bottom-lefthand corner of the window. To deal with more than one directory (for example, for a copy or move operation), open windows for each of the directories and arrange them on the screen so that they are not overlapping.
To manage files, start by selecting one or more files:
To select a single file, click on it.
To select several files that are located close together, click on a point to the left or right of the files (which will start drawing a rectangle) and then drag the mouse pointer so that the rectangle touches all of the files you wish to select.
To select several files that are not adjacent, click on the first one, and then hold Ctrl and click on additional ones.
To select a consecutive range of files, click on the first file, and then hold Shift and click on the last file.
Once you have selected a file (or files):
Move the file by dragging it between windows.
Copy a file by dragging it between windows while holding the Ctrl key.
Link a file (symbolically) by dragging it between windows while holding the Ctrl and Shift keys.
Delete a file by dragging it and dropping it on the Trash icon on the desktop, by pressing the Delete key, or by right-clicking and selecting "Move to Trash."
To rename a file, right-click, select Rename, and then edit the name below the file icon.
You can also use traditional cut, copy, and paste operations on the files:
To cut a file, press Ctrl-X, or right-click and select Cut. Note that the file will not disappear from the original location until it is pasted into a new location; this effectively performs a move operation.
To copy a file, press Ctrl-C, or right-click and select Copy.
To paste a file that has been cut or copied, click on the window of the directory you with to paste into, and then press Ctrl-V or right-click on the window background and select Paste.
You can also perform cut, copy, and paste operations from the Edit menu at the top of the Nautilus window.
KDE's Konqueror is both a file manager and a web browser. Figure 4-3 shows the file manager view. Although at first glance this looks similar to Nautilus, Konqueror offers a larger set of features, most of which are accessed through the toolbar and menus.
Figure 4-3. Konqueror in file management mode
To start Konqueror, select Home from the K menu. Unlike Nautilus, Konqueror does not use spatial windows; as you move around the file hierarchy, the same window is reused. To create a second window for drag-and-drop, press Ctrl-N (or select the menu option Location→New Window). Alternately, you can split a window horizontally or vertically using the Window menu, and then drag and drop between the two panes. To view more information about the files, select the menu option View→View Mode→Detailed List View, which shows information similar to that displayed by ls -l. There are other options on the View Mode menu that are useful in different situations, such as the Photobook view for directories of photographs.
You can change to child directories by double-clicking on them, or you can change to parent directories by using the up-arrow icon on the toolbar. You can also select a directory from the Navigation Panel, shown on the left in Figure 4-3 (the Navigation Panel can be toggled on and off using the F9 key).
To manage files, start by selecting one or more files:
To select a single file, click on it.
To select several files that are located close together, click on a point to the left or right of the files (which will start drawing a rectangle) and then drag the mouse pointer so that the rectangle touches all of the files you wish to select.
To select several files that are not adjacent, click on the first one, and then hold Ctrl and click on additional ones.
To select a range of files (rectangular region), click on the first file, and then hold Shift and click on the last file.
Once you have selected a file (or files):
Move, copy, or link the file by dragging it between windows (or window panes). When you drop the file on the destination, a pop-up menu will appear with Move Here, Copy Here, and Link Here options.
Delete a file by dragging and dropping it on the Trash icon on the desktop, by pressing the Delete key, or by right-clicking and selecting "Move to Trash."
To rename a file, right-click, select Rename, and then edit the name below the file icon.
As with Nautilus, you can also use traditional cut, copy, and paste operations on the files:
To cut a file, press Ctrl-X, or right-click and select Cut. Note that the file will not disappear from the original location until it is pasted into a new location; this effectively performs a move operation.
To copy a file, press Ctrl-C or right-click and select Copy.
To paste a file that has been cut or copied, click on the window of the directory you wish to paste into, and then press Ctrl-V, or right-click on the window background and select Paste.
You can also perform cut, copy, and paste operations using the Edit menu at the top of the Konqueror window.
Linux shells use a process called globbing to find matches for ambiguous filenames before commands are executed. Consider this command:
$ ls /etc/*release*
When the user presses Enter, the shell converts /etc/*release* into a list of matching filenames before it executes the command. The command effectively becomes:
$ ls /etc/fedora-release /etc/lsb-release /etc/redhat-release
This is different from some other platforms, where the application itself is responsible for filename expansion. The use of shell globbing simplifies the design of software, but it can cause unexpected side effects when an argument is not intended to be a filename. For example, the echo command is used to display messages:
$ echo This is a test.
This is a test.
However, if you add stars to either side of the message, then globbing will kick in and expand those stars to a list of all files in the current directory:
$ echo *** This is a test. ***
bin boot dev etc home lib lost+found media misc mnt net opt proc ptal root sbin selinux srv sys tftpboot tmp usr var This is a test. bin boot dev etc home lib lost+found media misc mnt net opt proc ptal root sbin selinux srv sys tftpboot tmp usr var
The solution is to quote the argument to prevent globbing:
$ echo "*** This is a test. ***"
*** This is a test. ***
Microsoft Windows uses drive designators at the start of pathnames, such as the C: in C:\Windows\System32\foo.dll , to indicate which disk drive a particular file is on. Linux instead merges all active filesystems into a single file hierarchy; different drives and partitions are grafted onto the tree in a process called mounting.
You can view the mount table, showing which devices are mounted at which points in the tree, by using the mount command:
$ mount
/dev/mapper/main-root on / type ext3 (rw)
/dev/proc on /proc type proc (rw)
/dev/sys on /sys type sysfs (rw)
/dev/devpts on /dev/pts type devpts (rw,gid=5,mode=620)
/dev/md0 on /boot type ext3 (rw)
/dev/shm on /dev/shm type tmpfs (rw)
/dev/mapper/main-home on /home type ext3 (rw)
/dev/mapper/main-var on /var type ext3 (rw)
/dev/sdc1 on /media/usbdisk type vfat
(rw,nosuid,nodev,_netdev,fscontext=system_u:object_r:removable_t,user=chris)
Or you can view the same information in a slightly more readable form, along with free-space statistics, by running the df command; here I've used the -h option so that free space is displayed in human-friendly units (gigabytes, megabytes) rather than disk blocks:
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/main-root
30G 12G 17G 42% /
/dev/md0 251M 29M 210M 13% /boot
/dev/shm 506M 0 506M 0% /dev/shm
/dev/mapper/main-home
48G 6.6G 39G 15% /home
/dev/mapper/main-var 30G 13G 16G 45% /var
/dev/sdc1 63M 21M 42M 34% /media/usbdisk
Note that /media/usbdisk is a flash drive, and that /home and /var are stored on separate disk partitions from / .
While the cursor is on or adjacent to the ambiguous filename, press Tab twice. bash will display all of the matching filenames, and then reprint the command and let you continue editing:
$ ls a* (press Tab, Tab)
a2.html all-20090412
a3f1.html
$ ls a*
Alternately, press Esc-* and bash will replace the ambiguous filename with a list of matching filenames:
$ ls a* (press Esc-*)
$ ls a2.html all-20050412 a3f1.html
Type the first few characters of the filename, then press Tab. bash will fill in the rest of the name (or as much as is unique). For example, if there is only one filename in the current directory that starts with all :
$ ls all (press Tab)
$ ls all-20090412
Press Esc-_ (underscore) to copy the last argument from the previous command. For example, to create a directory and then change to that directory:
$ mkdir backup-directory-august
$ cd (press Esc, _)
$ cd backup-directory-august
The Linux Standard Base project: http://www.linuxbase.org/
The manpages for bash , rm , cp , mv , ls, file , and less
The Konqueror Handbook (press F1 in a Konqueror window)
The GNOME User's Guide (press F1 in a Nautilus window)
Fedora Core, like most other Linux and Unix systems, stores most of its configuration information in text files. These files can be edited using various system administration tools, but they can also be edited by hand using any standard text editor.
vi is one such text editor. Some people love it, and some people hate it, but it has one advantage over just about every other editor available: it's universal. If you know how to use vi , you can confidently walk up to just about any Linux or Unix computer in the world and edit text files, so it's a valuable skill. The other nice fact about Vi is that it's not very demanding; you can use it in character mode or graphic mode, over a congested remote connection or with a foreign keyboard, and still get the job done. You can get by with less than a dozen commands to start, and then learn more when you need them.
vi is pronounced "vee-eye," not "vye" or "six."
To start up the vi editor, simply type its name at a shell prompt, optionally providing the name of a file you wish to edit as an argument:
$ vi filename
The screen will clear, and the specified file will be displayed, as shown in Figure 4-4 .
Figure 4-4. Initial vi display
Notice that unused lines are marked with a tilde (~) character.
vi uses two distinct modes:
Normal mode , where the text keys issue editing commands. This is sometimes called command mode .
Insert mode , where text keys insert text into the document.
The lower-left corner of the display shows the current mode: if it says -- INSERT -- , then you're in insert mode; otherwise, you're in normal mode.
You can move the cursor around using the arrow keys. If your arrow keys don't work (which may be the case if you're using a remote connection from a bad terminal program), you can use the h, j, k, and l keys, as shown in Table 4-7 .
Table 4-7. Basic vi movement commands
Command | Description |
---|---|
Left, h, or Backspace | Move left one character. |
Down or j | Move down one line. |
Up or k | Move up one line. |
Right, l, or Space | Move right one character. |
Enter | Move to the start of the next line. |
Home, ^, |, or 0 (Zero) | Move to the start of the line. |
End, $ | Move to the end of the line. |
:number Enter | Move to line number. |
:0 Enter | Move to the start of the file. |
:$ | Move to the end of the file. |
w | Move forward one word. |
You can put a number in front of any command to repeat the command. For example, typing 10j will move down 10 lines.
There are several commands for inserting text, as shown in Table 4-8 .
Table 4-8. Commands to enter insert mode
Command | Description |
---|---|
i | Insert before the cursor. |
I | Insert at the start of the line. |
a | Append after the cursor. |
A | Append at the end of the line. |
o | Open a line after the current line and insert text. |
O | Open a line before the current line and insert text. |
All of these commands place the editor into insert mode; the only difference is where the cursor is positioned for the inserted text. The word -- INSERT -- will appear in the lower-left corner of the display.
To exit from insert mode and return to normal mode, press Esc. The -- INSERT -- indicator in the lower-left corner of the display will disappear.
vi offers three basic commands for deleting or yanking, as shown in Figure 4-9 . Deleting is roughly equivalent to cutting in a GUI-based editor, and yanking is similar to copying.
Table 4-9. Basic delete and yank commands
Command | Description | Examples |
---|---|---|
x | Delete one character to the right of the cursor. | x deletes one character to the right of the cursor; 25x deletes the character at the cursor position and 24 characters to the right. |
X | Delete one character to the left of the cursor. | X deletes one character to the left of the cursor; 19X deletes 19 characters to the left. |
d, followed by a cursor movement | Delete from the cursor position to the indicated position. | dj deletes the current line and the line below; dw deletes one word. |
dd | Deletes a line. | dd deletes the current line; 15dd deletes 15 lines. |
y, followed by a cursor movement | Yank from the cursor position to the indicated position. | yj yanks the current line and the line below; yw yanks one word. |
yy | Yanks a line. | yy yanks the current line; 15yy yanks 15 lines. |
p | Puts yanked or deleted text after the cursor. If the text contains any partial lines, it is inserted directly after the cursor; otherwise, it is inserted starting on the next line. | p puts one copy of the yanked text into the document after the cursor; 20p puts 20 copies of the yanked text after the cursor. |
P | Puts yanked or deleted text before the cursor. If the text contains any partial lines, it is inserted directly before the cursor; otherwise, it is inserted on the previous line. | P puts one copy of the yanked text into the document before the cursor; 20P puts 20 copies of the yanked text before the cursor. |
Typing / followed by some text (actually, a regular expression) and pressing Enter will search forward in the document. Typing n will repeat the previous search in the forward direction. Typing ? instead of / will search backward instead of forward; N will repeat a search backward.
Searching can be combined with deleting and yanking; for example, d/hello will delete from the cursor position up to the start of the word hello .
Pressing u will undo the last operation performed; pressing Ctrl-R will redo it. Typing a dot ( . ) will repeat the last operation.
There are a number of commands available for saving the document and exiting vi , as shown in Table 4-10 ; you must press Enter after these commands.
Table 4-10. Saving text and exiting vi
Command | Description |
---|---|
:w | Write (save) using the current filename. |
:w newfilename | Write to the file newfilename (subsequent :w commands will still write to the original filename). |
:w! | Force-write (write even if in read-only mode). |
:q | Quit (succeeds only if the document is saved). |
:q! | Force quit even if the document isn't saved (abort!). |
:wq or :x or ZZ | Write and quit (exit with save). |
vi is one of a group of programs that uses a terminal-control system called curses. curses enables an application to manage a character-mode display by positioning the cursor and interpreting keystrokes using a database of information about each terminali.e., which codes to send to produce different effects and which codes can be received from the terminal. Fedora's terminfo database has entries for about 2,500 different hardware terminals and terminal programs that have been produced through the years.
curses keeps two buffers areas of memory arranged in the same size and layout as the screento store the current terminal screen contents and the desired display. When vi needs to update the screen, it updates the display buffer; curses compares the two buffers to determine the minimum number of commands it can send to the terminal to produce the desired display. It then sends the appropriate codes from the terminal database ( terminfo / termcap ) to update the terminal, copies the display buffer to the terminal buffer, and repeats the process.
The version of vi used by Fedora Core is Vim (Vi iMproved), which adds many, many features to the traditional vi capabilities; the commands covered in this chapter outline only the basics. Vim offers syntax highlighting, macro recording, support for multiple character sets, accents, right-to-left text, and many other features, making it a useful text editor for programming, scripting, and editing system files.
Vim can be configured by creating a .vimrc file; for details, type :help vimrc-intro within Vim.
If you execute gvim instead of vi , a window will appear with a full graphical user interfaceincluding pull-down menus and a toolbaras shown in Figure 4-5 . Using the File→Save menu option, clicking on the Save toolbar icon, or typing the vi save command ( :w) will perform the same operation.
Figure 4-5. gvim: vi with a GUI
In addition to vi , Fedora ships with a plethora of other text editors, including:
nano (an improved clone of the easy-to-use editor Pico )
mcedit
joe (the commands jstar , jmacs , or jpico will start joe configured to emulate WordStar , emacs , or Pico ).
emacs and emacs-x
kedit and gedit
All of these text editors are capable of editing just about any text file. Each has its advantages and disadvantages.
Since the choice of editor is very personal, take some time to experiment with each of the editors to see which one you prefer. In any case, I'd recommend knowing the basics of vi so that you can always fall back to it if you encounter a situation where your favorite editor is unavailable.
The Vim web site: http://www.vim.org/
The vi help file and online tutorial: start vi , then type :help and press Enter
Fedora can be booted into different runlevels , each of which starts a specific collection of software for a particular purpose. The most commonly used are runlevel 3, which starts the system with a character-based user interface, and runlevel 5, which starts the system with a graphical user interface. Table 4-11 lists the standard runlevels.
Table 4-11. Standard runlevels
Runlevel | Description | Purpose |
---|---|---|
s (or S) | Single-user maintenance mode | Emergency system recovery work |
0 | Halt | Stops the system |
1 | Single-user mode | System administration |
2 | (Multiuser without networking) | (Not normally used) |
3 | Multiuser, character-mode | Normal system operation without graphical login; useful for servers |
4 | (Not defined) | (Not normally used) |
5 | Graphical | Normal system operation with graphical login. |
6 | Reboot | Restarts the system |
7, 8, 9, a, b, c | (Not defined) | Available for custom purposes |
The ability to choose the runlevel lets you save system resources (for example, by not running the graphical user interface when it isn't needed) or start the system in a minimal configuration so that you can fix problems.
You can change the runlevel on the fly, or configure your system to start in a different runlevel.
The Fedora boot menu can be used to specify the runlevel:
1. Press a key (such as the spacebar) when the Fedora Core boot display appears. This will reveal the boot menu.
2. Select the Fedora Core boot option you wish to use using the arrow keys.
3. Press the letter a (Append). An edit display will appear that allows you to append information to the boot command line.
4. Add a space and then the runlevel to the end of the list of boot options (for example, press space then 3 to select runlevel 3).
5. Press Enter to boot into the runlevel that you've specified.
If you have configured a GRUB password, you will be prompted to enter it before changing the boot options.
Take the following steps to change the runlevel after booting:
1. Obtain a root prompt using the su command:
2. $ su
3. Password: rootPassword
4. #
5. Use the init command to change to the runlevel of your choice:
6. # init 3
System administrators often configure servers to start in runlevel 3, freeing up memory to increase the server's performance.
The default runlevel is controlled by a line in the file /etc/inittab ; to change the default runlevel, edit that file using the vi editor:
1. Obtain a root prompt using su .
2. Start vi with the /etc/inittab file:
3. # vi /etc/inittab
4.
5. Find this line in the file:
6. id:5:initdefault:
7. Change the second field to the default runlevel of your choice; in this case, I've used 3 :
8. id: 3 :initdefault:
9. Save the file and exit vi . The change will take effect next time you boot the system.
The boot menu is configured using the file /boot/grub/grub.conf . You can edit this file so that options for various runlevels appear on the boot menu:
1. Obtain a root prompt.
2. Start vi with the /boot/grub/grub.conf :
3. # vi /boot/grub/grub.conf
4.
5. The file will look something like this:
6. # grub.conf generated by anaconda
7. #
8. # Note that you do not have to rerun grub after making changes to this file
9. # NOTICE: You have a /boot partition. This means that
10. # all kernel and initrd paths are relative to /boot/, eg.
11. # root (hd0,1)
12. # kernel /vmlinuz-version ro root=/dev/Main/root
13. # initrd /initrd-version.img
14. #boot=/dev/hdc
15. default=0
16. timeout=5
17. splashimage=(hd0,1)/grub/splash.xpm.gz
18. hiddenmenu
19. title Fedora Core (2.6.17-1.2517.fc6)
20. root (hd0,1)
21. kernel /vmlinuz-2.6.17-1.2517.fc6 ro root=/dev/Main/root rhgb quiet
22. initrd /initrd-2.6.17-1.2517.fc6.img
23. title Windows XP
24. rootnoverify (hd0,0)
25. chainloader +1
26. This example shows two Fedora Core entries for two different kernel versions. There may be additional entries for other operating systems (such as Windows) or additional kernels.
27. Find a Fedora Core entry (the bold lines in the example above) usually, the one with the latest kernel. Make an identical copy of it immediately after the original location in the file:
28. title Fedora Core (2.6.17-1.2517.fc6)
29. root (hd0,1)
30. kernel /vmlinuz-2.6.17-1.2517.fc6 ro root=/dev/Main/root rhgb quiet
31. initrd /initrd-2.6.17-1.2517.fc6.img
32. title Fedora Core (2.6.17-1.2517.fc6)
33. root (hd0,1)
34. kernel /vmlinuz-2.6.17-1.2517.fc6 ro root=/dev/Main/root rhgb quiet
35. initrd /initrd-2.6.17-1.2517.fc6.img
36. Change the description of the copied section to indicate the runlevel that will be used:
37. title Fedora Core (2.6.17-1.2517_fc6) - Runlevel 3 - Character mode
38.
39. On the kernel line, append the runlevel that you wish to use (this will override the default runlevel in /etc/inittab ):
kernel /vmlinuz-2.6.17-1.2517.fc6 ro root=/dev/Main/root rhgb quiet 3
1. Optionally, change the default , timeout , or hiddenmenu options to suit your tastes.
2. The default option specifies which of the menu entries is booted by default; the menu entries are numbered starting at 0 , so you could set this line to 1 to boot the second item on the menu automatically:
3. default= 1
4.
5. The timeout option sets the number of seconds that the menu will be displayed before the default option is automatically chosen. To give the user 30 seconds to decide which boot option to use, change the timeout line to read:
6. timeout= 30
7.
8. hiddenmenu hides the menu until the user presses a key; remove the hiddenmenu line to automatically reveal the menu every time the system is booted.
9. Save the file and exit vi . The new menu option will appear the next time you boot the system.
Once the kernel has fully started up, it runs just one program: init . All other software is started directly or indirectly by init .
If a runlevel is specified in the kernel boot options, init uses that value for the runlevel; otherwise, it obtains a runlevel from the initdefault line in /etc/inittab .
init then looks for a sysinit enTRy in /etc/inittab and executes the command specified:
si::sysinit:/etc/rc.d/rc.sysinit
This executes the /etc/rc.d/rc.sysinit script, which performs some basic system setup common to all runlevels.
Next, init examines the /etc/inittab file, looking for entries that contain the current runlevel in the second field and wait or respawn in the third field. For runlevel 3, it will find these lines:
l3:3:wait:/etc/rc.d/rc 3
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6
The first line starts the script /etc/rc.d/rc with the argument 3 . This in turn sequentially executes every script in /etc/rc.d/rc3.d that starts with the letter S (for start ); this is how runlevel-specific software and services get started. Scripts in that same directory that start with K (for Kill ) are used to stop software when switching from the runlevel.
The remaining lines listed start character-mode logins on virtual terminals 1 through 6; the respawn keyword indicates that init must restart those programs when they terminate, enabling another user to log in.
If the file /etc/inittab doesn't exist, init cannot start the system normally. Runlevel S was created specifically for this purpose; it's the only runlevel that doesn't require /etc/inittab , so it can be a lifesaver if that file is missing or messed up. In fact, init doesn't even ask for a password in runlevel S; it takes you directly to a root command prompt. This is useful if you've forgotten the root password, but presents a huge security risk.
To protect against the unauthorized use of runlevel S, it's a good idea to add a password entry to the boot menu. If you didn't do this during the installation, you can add the password at any time by following these steps:
1. Generate an encrypted password with the grub-md5-crypt command:
2. $ grub-md5-crypt
3. Password:
4. bigsecret
5. Retype password:
6. bigsecret $1$f1z061$j/UEYyBn0e0996w0gjq4k/
7.
8. The previous line in bold is the encrypted (scrambled) version of the password.
9. Next, edit the /boot/grub/grub.conf file and add this line at the top, substituting the password generated in step 1:
10. password --md5 $1$f1z061$j/UEYyBn0e0996w0gjq4k/
11.
12. When you boot the system, you will still be able to select a boot menu entry, but to perform any advanced operations (such as appending runlevel information to a boot entry) you will need to enter the password.
Just because runlevel 3 doesn't offer a graphical login screen doesn't mean that you can't use a graphical user interface. If you log in on a character-mode display, you can start the GUI with this command:
$ startx
To have the GUI start each time you log in, add this command to your ~/.bash_profile :
exec startx
On a server, this gives you the best of both worlds: the GUI doesn't consume any resources when it's not in use, but it can be started quickly any time you need ituseful when you need to look up documentation on a web site, for example.
The manpages for init and inittab
Fedora starts a number of programs automatically when the system is booted. These services (sometimes called Disk And Execution MONitors , or daemons ) perform automatic actions on the local computer and, in some cases, perform operations for remote computers on the network, such as sharing files and serving web pages.
Each service consumes memory and processor time, and each network service may provide a weak spot for an attack against your system. Disabling unused services can reduce your boot time, speed up your system, and reduce your security risk.
Select the menu option System→Administration→Services (in KDE, it is System→Services) to start the system-config-services tool, shown in Figure 4-6.
Figure 4-6. Services configuration window
The configuration of the current runlevel is shown by default. Every service with a checkmark in front of it will be started when that runlevel is entered; to add or clear a checkmark, click on the checkbox.
Click on a service name to see a description of that service and its current status ( running or stopped ). Click on the Save icon (or File→Save Changes) when you've configured the services to your liking; your changes will take effect next time you change runlevels or boot the system.
You can edit the settings for another runlevel (3, 4, 5, or all three at the same time) using options on the Edit Runlevel menu.
To start, stop, or restart a service immediately, regardless of whether it's configured to start automatically at boot time, click on the service name and then click on the Start, Stop, or Restart icon.
If you're not running a graphical user interface, you can use ntsysv , a character-mode program similar to system-config-services :
# ntsysv
This will configure the current runlevel. To configure a different runlevel, use the --level option:
# ntsysv --level 4
The display shown in Figure 4-7 will appear.
Figure 4-7. The ntsysv display
Use the arrow keys to select a service, the spacebar to check/uncheck a service, and Tab to switch between the service list and the buttons. When you are done, press Tab to advance to the OK button and then press Enter.
The chkconfig command provides an easy way to enable and disable services. The --list option displays the current service configuration:
$ chkconfig --list
NetworkManager 0:off 1:off 2:off 3:off 4:off 5:off 6:off
NetworkManagerDispatcher 0:off 1:off 2:off 3:off 4:off 5:off 6:off
acpid 0:off 1:off 2:off 3:on 4:on 5:on 6:off
amd 0:off 1:off 2:off 3:off 4:off 5:off 6:off
anacron 0:off 1:off 2:on 3:on 4:on 5:on 6:off
apmd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
arptables_jf 0:off 1:off 2:on 3:on 4:on 5:on 6:off
...(Lines snipped)...
If you specify a service name, then only the configuration for that service is shown:
$ chkconfig --list httpd
httpd 0:off 1:off 2:off 3:off 4:off 5:off 6:off
Note that each of the seven runlevels is shown, even though the configurations for runlevels 0 and 6 are ignored except for K files (since 0 is halt and 6 is reboot).
To enable a service in a runlevel, use the --level option to specify the runlevel along with the on argument:
# chkconfig --level 4 httpd on
# chkconfig --list httpd
httpd 0:off 1:off 2:off 3:off 4:on 5:off 6:off
To disable it, use the off argument:
# chkconfig --level 4 httpd off
# chkconfig --list httpd
httpd 0:off 1:off 2:off 3:off 4:off 5:off 6:off
To reset a service to its default configuration, use the reset argument. The configuration will be reset for the runlevel you specify, or for all runlevels if you don't include a - -level option:
# chkconfig --level 4 httpd reset
# chkconfig httpd reset
The service command is used to manage running services. Two arguments are always used: first, the name of the service being managed, and second, the action that is to be performed. The most common actions are:
start
Start the service. This will fail if the service is already running.
stop
Stop the service. This will fail if the service is not running.
restart
Restart the service by stopping it and then starting it.
reload
Reload the configuration files for the service after they have been edited.
status
Display the current status of the service. This will indicate if the service is stopped or running; depending on the service, additional information may be displayed.
For example, to start the web service (named httpd ):
# service httpd start
Starting httpd: [ OK ]
You can then check its status:
# service httpd status
httpd (pid 13154 13153 13152 13151 13150 13149 13148 13147 13117) is running...
The pid values printed are the process IDs of the web server processes.
To make the web server reload its configuration file after it's been edited:
# service httpd reload
Reloading httpd: [ OK ]
Finally, to stop the web server:
# service httpd stop
Stopping httpd: [ OK ]
Services are managed by scripts in the /etc/rc.d/init.d directory; the name of each script corresponds to the name of the service. Each runlevel has its own directory named /etc/rc.d/rc<X> .d , where <X> is the runlevel.
If you examine a runlevel directory, you'll see names beginning with K or S , followed by a 2-digit number, followed by a service name:
$ ls /etc/rc.d/rc5.d
K01rgmanager K36postgresql K90isicom
K01yum K45arpwatch K92ipvsadm
K02NetworkManager K46radvd K94diskdump
K02NetworkManagerDispatcher K50netdump S01sysstat
K05innd K50snmpd S04readahead_early
K05saslauthd K50snmptrapd S05kudzu
K09dictd K50tux S06cpuspeed
...(Lines snipped)...
K35vncserver K85mdmpd S97messagebus
K35winbind K85zebra S98cups-config-daemon
K36dhcp6s K87multipathd S98haldaemon
K36lisa K89netplugd S99local
K36mysqld K89rdisc
All of these files are actually symbolic links to service scripts in /etc/rc.d/init.d , as shown by a long listing:
$ cd /etc/rc.d/rc5.d
$ ls -l S90xfs
lrwxrwxrwx 1 root root 13 Oct 5 14:37 S90xfs -> ../init.d/xfs
The scripts that start with S are used to start services, and the scripts that start with K are used to kill (stop) services. K scripts are only used when switching between runlevels after the system has been booted.
The digits in the filename are used to control the sequence in which the scripts are executed. This is essential because some services rely on others; for example, the web server relies on the network being up and running, so the network script must be run first.
When you examine the top of a service script, you will find a comment line containing the keyword chkconfig: followed by three arguments:
$ head /etc/rc.d/rc5.d/S90xfs
#!/bin/bash
#
# Id:$
#
# xfs: Starts the X Font Server
#
# Version: @(#) /etc/init.d/xfs 2.0
#
# chkconfig: 2345 90 10
# description: Starts and stops the X Font Server at boot time and shutdown. \
The first argument ( 2345 ) is a list of the runlevels in which this service will run by default; this information is used to initially set up the system and to handle chkconfig 's reset argument. If the default for this service is to have it turned off in all runlevels, the value - is used. The second argument is the sequence number (00 through 99) for the start link; the value 90 shown here means that the name of the start link will be S90xfs . The third argument is the sequence number for the kill link, which in this case yields a kill-link name of K10xfs .
When service scripts are called, they are passed a keyword such as start , stop , restart , or reload , indicating the action the script must take.
You can use the system-config-services or chkconfig tools to create a custom set of services for a runlevel and then use that either as the default runlevel or an option on the boot menu.
This technique is particularly useful on laptops, which may be used in different locations and need different services in each location.
To create a service:
1. Create a service script in /etc/rc.d/init.d . Include a chkconfig line as described in the previous section. (You may want to examine an existing service file to see how it works.)
2. Run the command chkconfig --add service to set up the default service links.
You can then configure your service in the same way as any of the other services, using system-config-services , service , and chkconfig .
The manpages for chkconfig , ntsysv , and init
In an age of viruses, worms, and identity theft, keeping information private and secure has taken on great importance. Managing user identity creates the framework for system securityeven on a single-user system, where a distinction is maintained between using the system as the normal user and using the system as the root user.
Almost everyone identifies themselves as both an individual and as a member of several groups. Linux uses separate user and group identities to reconstruct this two-level structure inside the system.
For example, company employee Richard might be all of the following:
A member of the IT department
Located at the company's Toronto office
The leader of the team putting together the big sales pitch to Acme, Ltd.
Part of the Christmas party committee
A player in the Tuesday evening company soccer league
(And that doesn't even touch on life outside of the company!)
The system administrator configures Richard's account to indicate his many involvements within the company. At the user level, the name richard is assigned to him, and a password and home directory are assigned. richard is then placed into the groups it , toronto , acmeproposal , christmas , and soccer .
Fedora Core extends this system using a scheme called user private group (UPG), which means that Richard also has his own private group, also named richard . UPG makes a lot of sense when you look at permissions.
The Fedora GUI tool for managing users and groups is system-config-users , which is accessed through the menu under System→Administration→"Users and Groups." After you supply the root password, the window shown in Figure 4-8 will appear.
Figure 4-8. The Users and Groups configuration window
This window has two tabs, one for managing groups and one for managing users.
To add a user, click on the Add User icon. The window shown in Figure 4-9 will be displayed.
Figure 4-9. The Create New User window
Fill in each of the fields:
User Name
The account name (username) you wish to use (such as jane ). This is what the user will enter when she logs in to the system. It should be an opaque string (no spaces) and consist of letters, digits, dashes, underscores, and periods. Although you can use uppercase characters, traditional user names are all-lowercase for ease of typing.
Full Name
The actual name of the user, in upper- and lowercase ( Jane Smith ). This information is optional and is used for reference only.
Password and Confirm Password
Type the new user's password twice.
Login shell
For most users, this field should be left as is; it can always be changed (using chsh ) later. If you are creating a user account that will never be used for logging in (such as an account used exclusively for email access or file sharing), select /sbin/nologin for the shell.
Create home directory
This should almost always be left checked.
Create a private group for the user
This enables the Fedora User Private Group scheme (which is a great idea), so it should almost always be left checked.
Specify a user ID manually
This controls whether the numeric user ID will be automatically or manually assigned. The only time you would want to specify it manually is when you are configuring the same user ID on two systems. In that case, check the box and enter the user ID in the UID field; otherwise, leave it unchecked.
Once you have filled in all of these fields, click OK. You will be returned to the main User and Group configuration window ( Figure 4-8 ).
To edit a user, double-click on the user's name, or highlight the name and click the Properties icon. An edit window will appear with four tabs, enabling you to edit values that cannot be set during the creation of the account; Figure 4-10 shows each of these tabs.
Figure 4-10. The four tabs of the User Properties window
The four tabs are:
User Data
Contains fields similar to those in the Create New User dialog ( Figure 4-9 ).
Account Info
Allows you to set an expiry date for the account or lock (disable) the account.
Password Info
Configures password expiration (also called password aging ). You can set the number of days before a change is required, to force users to change passwords periodically; the number of days after a change before another change is permitted, to prevent a user from gaming the forced password change by using a temporary password and then immediately switching back to her regular password; how far in advance the user will be warned about an impending password expiry; and the number of days of inactivity permitted before the account is locked as abandoned.
Groups
This tab is one of the least used, but most useful. Here you configure the groups to which the user belongs. In the case of our fictional example of Richard, you would check the it , toronto , acmeproposal , christmas , and soccer groups. By default, the user is automatically assigned to a group with the same name as his username. The significance of groups is that they can be used to manage file access.
The value of password aging is debatable; while it does limit the time that a compromised password can be used, forcing a user to change her password too frequently can make it difficult for her to remember the current password, leading to unsafe practices such as writing passwords on sticky notes or choosing weak passwords.
To delete a user account, click on the username and then click on the Delete icon. You will be warned if the user account is active (i.e., if the user is logged in or has processes running), and you will be asked for confirmation. The confirmation dialog has a checkbox that controls whether the user's files will be deleted along with the user account. If you are planning to keep the user's files, it may be better to lock the account than to delete it, so that the user's name continues to show up as the owner of those files (if the account is deleted, the account number is shown instead of the name).
The Group tab of the User Manager window works in exactly the same way as the Users tab. The only fields that appear in the Add Group dialog are for the group name and, if you want to set it manually, the group number. The Properties dialog adds a tab that shows you a list of all of the users on the system, with checkboxes to indicate which ones are in the group.
Fedora provides six utilities for managing users and groups from the command line. For users, there are useradd , usermod , and userdel ; for groups, there are groupadd , groupmod , and groupdel .
The express way to add a user is to use useradd and then set the new user's password using passwd :
# useradd jane
# passwd jane
Changing password for user jane.
New UNIX password:
bigSecret
Retype new UNIX password:
bigSecret
passwd: all authentication tokens updated successfully.
useradd accepts a number of options; the most common are shown in Table 4-12 . Most of these options can also be used with usermod to change an existing user's options.
Table 4-12. useradd options
Option | Description | Notes |
---|---|---|
-b directory | Base for home directories (a directory with the same name as the username will be created in this directory and used as the home directory) | useradd only; the default is /home. |
-c "fullName" | User comment field; almost always used to hold the user's full name | If the full name contains spaces, quote it. |
-d homedir | User's home directory | |
-e YYYY-MM-DD | Account expiry date | |
-f days | Days of inactivity before the account is considered abandoned and locked | |
-g group | User's primary group | Default is the user's own group (same name as the username). |
-G grp1,grp2,... | Supplementary group membership | |
-M | Don't create a home directory | useradd only. |
-m | Create a home directory if it doesn't exist | This is the default action. |
-p cryptpass | Set encrypted password to cryptpass | Useful when copying accounts from an old system configuration. |
-s shell | Sets the user's shell to shell | |
-u uid | Set the numeric user ID to uid | Useful when copying accounts from an old system configuration or synchronizing with old NFS servers. |
-L | Lock account against login | usermod only. |
-U | Unlock account and permit login | usermod only. |
To set Jane's full name when her account is created, execute:
# useradd -c " Jane Smith " jane
usermod works in a similar way to useradd , but is used to adjust the parameters of existing accounts. For example, to change Jane's full name:
# usermod -c " Jane Lee " jane
As you'd expect, the userdel command deletes a user. The -r option specifies that the user's home directory and mail spool ( /var/spool/mail/ user ) should also be removed:
# userdel -r jane
The groupadd , groupmod , and groupdel commands are used in a similar way to create, modify, and delete groups.
To add a group, just specify the name as an argument to groupadd :
# groupadd groupname
The only option commonly used is -g , which lets you manually select the group ID (useful if converting data from an old system):
# groupadd -g 781 groupname
The groupmod command is rarely used, but it will change the numeric group ID ( -g ) or the name ( -n ) of an existing group:
# groupmod -g 947 groupname
# groupmod -n newname groupname
To delete a group, use groupdel :
# groupdel groupname
passwd is used to set a user's password. Used by a normal user, it sets that user's password by asking for the current password and then asking for the new password twice:
$ passwd
Changing password for user chris.
Changing password for chris
(current) UNIX password:
bigSecret
New UNIX password:
newSecret
Retype new UNIX password:
newSecret
passwd: all authentication tokens updated successfully.
When used by the root user, passwd can be used to change the root password (the default) or any existing user's password if the username is supplied as an argument. You don't need to know the current password:
# passwd
Changing password for user root.
New UNIX password:
topSecret
Retype new UNIX password:
topSecret
passwd: all authentication tokens updated successfully.
# passwd jane
Changing password for user jane.
New UNIX password:
superSecret
Retype new UNIX password:
superSecret
passwd: all authentication tokens updated successfully.
The root user can also delete a password from an account (so a user can log in with just a username):
# passwd -d jane
Removing password for user jane.
passwd: Success
This must be used carefully because it presents a big security risk. Remember that remote users may be able to connect via SSH, and then they won't need a password either!
To find out the password status of an account, use -S :
# passwd -S jane
Empty password.
# passwd -S chris
Password set, MD5 crypt.
The gpasswd command can be used to set a group password. This is rarely done. However, it is also used to manage groups and, better yet, to delegate group administration to any user.
To specify the members of a group, use the -M option:
# gpasswd -M jane,richard,frank audit
In this case, jane , richard , and frank are made members of the audit group. Any previous memberships in that group will be obliterated, so only these three users will now be in that group. (Other group memberships held by those users will not be affected.)
You can also add or delete individual group users using the -a and -d options:
# gpasswd -a audrey audit
# gpasswd -d frank audit
Those commands add audrey to the group audit , then delete frank .
If you delegate group administration to users, they can use the -a and -d optionsa great labor-saving idea! Delegation is performed with the -A (administrator) option:
# gpasswd -A jane audit
jane$ gpasswd -a matthew audit
User accounts are controlled by the /etc/passwd file, which looks like this:
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
...(Lines snipped)...
fax:x:78:78:mgetty fax spool user:/var/spool/fax:/sbin/nologin
nut:x:57:57:Network UPS Tools:/var/lib/ups:/bin/false
privoxy:x:73:73::/etc/privoxy:/sbin/nologin
chris:x:500:500:Chris Tyler:/home/chris:/bin/bash
diane:x:501:501:Diane Tyler:/home/diane:/bin/bash
jane:x:502:502:Jane Smith:/home/jane:/bin/bash
richard:x:503:503:Richard Lee:/home/richard:/bin/bash
The fields in this file are separated by colons. From left to right, they are:
username
The name of the user account, which shows up in ls -l output and is used to log in to the system. This is sometimes (incorrectly) called the user ID.
password
The encrypted password used to be stored in this field. For security, it has now been moved to /etc/shadow .
user ID
The number identifying this user. Process and file ownership is stored as a number; this field is used to cross-reference the number with a username. The user ID is frequently abbreviated to uid . User IDs below 500 are considered system IDs and are reserved for system services.
group ID
The group ID ( gid ) indicates the primary group for this user. It's cross-referenced to a group name through /etc/group .
comment field
This field can be used to store any text associated with the user. On Fedora, it's usually used to store the user's full name; the chfn and finger commands use it to store the user's full name, office location, office phone number, and home phone number, separated by commas.
This field is historically called the gecos or gcos field because it originally cross-referenced user IDs between the Unix and General Electric Comprehensive Operating System (gecos) at Bell Labs. You'll still find this field documented as pw_gecos in Linux library function documentation (for an example, see man getpwent).
home directory
At login, the shell changes to this directory automatically, and the HOME environment variable is set to this value.
shell
This field specifies the user's default shell.
For accounts that require a password but should not permit the user to log in, such as an account used only for file sharing or POP/IMAP email access, use the dummy shell /sbin/nologin. If the user attempts to log in, the message "This account is currently not available" is displayed, and the user is logged out automatically. To use a different message, place the desired text in the file /etc/nologin.txt.
Since /etc/passwd must be readable by everyone so that commands such as ls -l can function correctly, the passwords have been moved to a file that is readable only by root , named /etc/shadow , which looks like this:
root:$1$45ZWBaPE$XvzhGEj/rA4VDJXdQESi0.:13024:0:99999:7:::
bin:*:13024:0:99999:7:::
daemon:*:13024:0:99999:7:::
adm:*:13024:0:99999:7:::
...(Lines snipped)...
fax:!!:13024:0:99999:7:::
nut:!!:13024:0:99999:7:::
privoxy:!!:13024:0:99999:7:::
chris:$1$hUjsHJUHIhUhu889H98hH.8.BGhhY79:13068:0:99999:7:::
diane:$1$97KJHNujHUkh88JHmnjNyu54NUI9JY7:13024:0:99999:7:::
jane:$1$yuaJsudk9jUJHUhJHtgjhytnbYhGJHy:13024:0:99999:7:::
richard:$1$pIjyfRbKo71jntgRFu3duhU97hHygbf:13024:0:99999:7:::
Note that the second field contains an encrypted version of the password. The encryption function, called a hash , is not reversible, so it's not possible to take this data and reconstruct the password. When the user enters his password, it is also encrypted; then the two encrypted values are compared.
The other fields in this file contain information used for password aging (expiry).
In a similar way, /etc/group contains basic information about each group:
root:x:0:root
bin:x:1:root,bin,daemon
daemon:x:2:root,bin,daemon
sys:x:3:root,bin,adm
adm:x:4:root,adm,daemon
...(Lines snipped)...
fax:x:78:
nut:x:57:
privoxy:x:73:
chris:x:500:fen
diane:x:501:
jane:x:502:
richard:x:503:
audit:x:504:jane,richard
soccer:x:505:richard,jake,wilson,audrey,shem,mike,olgovie,newton
toronto:x:506:matthew,jake,wilson,richard,audrey,shem,mike,olgovie,newton,ed,jack
...(Lines snipped)...
The fields here are:
group name
The name assigned to the group.
group password
A password assigned to the group. This is rarely used, because it's just as easy to add a user into a group as it is to give her the password. The actual password values have been moved to /etc/gshadow .
group ID
The numeric value assigned to the group. This file is used to cross-reference group IDs to group names.
supplementary members
The username of each user in this group, except users who have this group as their primary group (field 4 in /etc/passwd ).
The /etc/gshadow file contains the actual passwords, plus group administrator information:
root:::root
bin:::root,bin,daemon
daemon:::root,bin,daemon
sys:::root,bin,adm
adm:::root,adm,daemon
...(Lines snipped)...
fax:x::
nut:x::
privoxy:x::
chris:!:500::fen
diane:!:501::
jane:!:502::
richard:!:503::
audit:!:504:jane:jane,richard,audrey,matthew
soccer:!:505:richard,jake:richard,jake,wilson,audrey,shem,mike,olgovie,newton
toronto:!:506:ed:matthew,jake,wilson,richard,audrey,shem,mike,olgovie,newton,ed
...(Lines snipped)...
The group administrators are in field 4 and group members are in field 5 in this fileso in this case, jane is the group administrator for audit , and jane , richard , andrew , and matthew are group members.
kuser is a KDE program that provides an alternative to system-config-user . The two programs are functional duplicates, but I think system-config-user looks better.
It is possible but must be done carefully to avoid leaving the system in an unusable state.
The vipw and vigr scripts provide the most convenient way of editing these files; vipw edits /etc/passwd and /etc/shadow , and vigr edits /etc/group and /etc/gshadow . In both cases, the files will be locked to prevent concurrent changes by another program, and the vi editor will be used for editing (the EDITOR environment variable can be used to specify another editor if you'd prefer).
The pwck command can be used to check and repair /etc/passwd and /etc/shadow :
# pwck
user adm: directory /var/adm does not exist
user gopher: directory /var/gopher does not exist
user ident: directory /home/ident does not exist
user torrent: directory /var/spool/bittorrent does not exist
invalid password file entry
delete line \Q'? y
pwck: the files have been updated
grpck performs similar checks on /etc/group and /etc/gshadow :
# grpck
invalid group file entry
delete line \Q'? y
invalid group file entry
delete line \Qascasdcasdarg asdfasdf'? y
grpck: the files have been updated
The manpages for passwd, useradd, usermod, userdel, groupadd, groupmod, groupdel, vipw, vigr, pwconv, grpconv, crypt (3), passwd (5), shadow (5), group (5), and gshadow (5)
All Linux and Unix systems use file permissions or modes to control access to files. Fedora extends this with the user-private-group scheme, which simplifies the configuration of permissions for collaboration.
There are two other mechanisms available for file access control: see Lab 8.2, "Using SELinux" and Lab 8.3, "Using Access Control Lists."
There are three basic file permissions:
read (r)
Grants permission to access the contents of a file. There are no restrictions on what can be done with the file contents, so read permission includes permission to view or process the contents of the file, as well as permission to copy the file. On a directory, read permission enables the display of the list of files in the directory; without read permission, you can access a file contained in the directory only if you know the exact name of the file.
write (w)
Grants permission to write to a file; this includes overwriting existing information, append to the end of the file, and truncate (shorten) the file. On a directory, write permission enables the creation and deletion of files within that directory.
execute (x)
Grants permission to execute the file. If the file is a binary, it can be executed by the kernel; if it is a text file, it is treated as a script. On a directory, execute permission grants access to the contents of the directory (some people refer to execute permission on a directory as search , or passthrough , permission).
Remember the order: r w x .
Each of these three permissions is granted or denied to users in three different communities :
user (u)
The user who owns the file. Initially, this is the user who created the file; it may be changed by the superuser ( root ).
group (g)
All members of the group that owns the file. Normally, this starts off as the group of the user who created the file. A file's owner may change the group ownership to any group to which she belongs; e.g., if Jane owns the file foo and is a member of the audit and toronto groups, she can make either group own the file.
other (o)
Everyone else.
The order is significant here, too; you'll want to memorize it: u g o .
This gives a total of nine permissions for each file and directory:
read, write, and execute for the user
read, write, and execute for the group
read, write, and execute for other
There are also three special file permissions, as outlined in Table 4-13 .
Table 4-13. Special file permissions | ||||
---|---|---|---|---|
Name | Abbreviation | Appearance in ls -l output | Meaning when applied to a file | Meaning when applied to a directory |
Set-User-ID | SUID | s in the x column for the user if execute permission is enabled, or S if execute permission is disabled. | When executed, the program takes on the user identity of the file's owner. | (No meaning) |
Set-Group-ID | SGID | s in the x column for the group if execute permission is enabled, or S if execute permission is disabled. | When executed, the program takes on the group identity of the file's group. | All files and subdirectories created in the directory will be owned by the same group that owns the directory. Subdirectories will automatically have their SGID permission enabled. |
Sticky bit | Sticky | t in the x column for other if execute permission is enabled, or T if execute permission is disabled. | (No meaning) | Files in the directory can be deleted or removed only by their owner (otherwise, anyone with write permission on the directory can delete or rename files in that directory). |
The SUID and SGID permissions provide critical abilities. For example, /etc/passwd and /etc/shadow are only writable by root , but normal users need to be able to change their passwords. The program /usr/bin/passwd is owned by root and has the SUID permission enabled, so it runs with root privilegeregardless of who executes itand is therefore able to change /etc/shadow .
When ls is executed with the -l option, a long and detailed listing of file information is displayed. Here is an example:
$ ls -l /etc/aliases.db
-rw-r----- 1 root smmsp 12288 Oct 6 19:31 aliases.db
The first field displayed is -rw-r----- . The first character is reserved for file type information, and the rest of that field contains the file's mode: rw-r----- .
This mode breaks down into three sets of three characters, representing the permissions granted to each of the three communities:
user: rw-
group: r--
other: ---
Notice that these communities are displayed in the u g o order mentioned earlier.
The three characters displayed for each of these communities represent read, write, and execute permission; if the permission is denied, a dash is shown, but if the permission is granted, the letter r , w , or x is shown, in that order ( r w x ).
In the preceding example, the permissions granted to the user are read and write ( rw- ); the permission granted to the group is read ( r-- ); and no permission is granted to other users ( --- ).
In order to correctly interpret the permission, we need to know who the user and group are. The ls -l output shows this information in fields 3 and 4; in this case, the user is root and the group is smmsp .
Putting this all together, we know that:
root can read and write the file.
All users in the smmsp group can read the file.
No one else on the system can read, write, or execute the file.
The permissions on the directories that contain the file also come into play when determining what a user can do with a file. If he does not have execute permission on all of the directories in the path from the root (/) to the file, then he will not be able to access the file, regardless of the permissions on the file itself. Likewise, if he has execute permission on all of those directories, plus write permission on the directory containing the file, then he can delete the file (destroying all the data), even if he can't write to itand then create a new file with the same name.
GNOME's Nautilus file manager normally displays files and directories as icons. To change the display to a list resembling the output of ls -l , select the menu option View→View as List. The default display shows the file name, size, type, and date modified.
You can add the permissions, owner, and group to the display by selecting Edit→Preferences, which presents the File Management Preferences window shown in Figure 4-11. Click on the List Columns tab, and then click on the checkboxes for permissions, owner, and group to include them on the display. You can also use the Move Up and Move Down buttons to change the displayed order of the fields. Click Close when the display is configured to your liking.
Figure 4-11. Nautilus File Management Preferences window
KDE's Konqueror application provides a similar display when you select View→View Mode→Detailed List View.
Right-clicking on a file in Nautilus or Konqueror will bring up the file Properties window shown in Figure 4-12 . The Permissions tab within that window contains checkboxes for each of the three permissions in each of the three communitiesnine checkboxes total, plus three for the special permissions (to view the checkboxes in Konqueror, use the Advanced Permissions button).
Figure 4-12. Nautilus File Properties window
To change the permissions, simply toggle checkmarks in the appropriate boxes using your mouse. When you're done, click Close.
The chmod (change-mode) command is used to change permissions from a shell prompt. The permissions can be specified using either of two different syntaxes: relative symbolic notation or octal notation.
Relative symbolic notation uses any combination of the three community letters ( u , g , or o ) or the letter a to indicate all three communities; an operation symbol, which is + to add a permission and - to remove it, or = to exactly set a permission; and finally, one or more permission letters ( r , w , or x ). Table 4-14 shows some examples of relative symbolic notation; note that multiple operations can be specified using commas as separators (no spaces).
Table 4-14. Relative symbolic notation used by chmod
Notation | Description |
---|---|
u+w | Adds write permission for the user. |
o-rwx | Removes read, write, and execute permission for others. |
ug+r,o-r | Adds read permission for the user and the group; removes read permission for others. |
a-x, ugo-x | Removes execute permission for all users. |
u=rw,go=r | Sets exactly read and write permission for the user, and only read permission for group and others. The difference between = and + is that = will disable other permissions (such as execute for the user in this example), while + will leave other permissions at their previous value. |
Special permissions are specified based on their appearance in ls -l output:
SUID is specified as u+s .
SGUID is specified as g+s .
Sticky is specified as o+t .
Octal notation uses a multidigit number, where each digit represents one community (in u g o order). The digit is the sum of values representing each enabled permission:
4 for read permission
2 for write permission
1 for execute permission
Therefore, the octal permission 764 represents read/write/execute for the user (4+2+1=7), read/write for the group (4+2=6), and read for others (4): rwxrw-r-- .
When using octal notation, special permissions are given as a fourth digit placed in front of the others; the value of this fourth digit is the sum of 4 for SUID, 2 for SGID, and 1 for Sticky. Octal permission 2770 represents rwxrws--- .
To change a permission with chmod , specify the permission as the first argument and one or more filenames as the remaining arguments:
$ ls -l oreilly
-rw-rw-r-- 1 chris chris 40 Oct 12 17:18 oreilly
$ chmod g-w,o= oreilly
$ ls -l oreilly
-rw-r----- 1 chris chris 40 Oct 12 17:18 oreilly
$ chmod 764 oreilly
$ ls -l oreilly
-rwxrw-r-- 1 chris chris 40 Oct 12 17:18 oreilly
The -R option causes chmod to recursively process subdirectories. To remove write permission for others on all files and subdirectories within your home directory, execute:
$ chmod -R o-w ~
Users can belong to more than one group, which enables documents to be shared according to group roles.
Previously, we used Richard in group examples; he's a member of the groups richard , it , toronto , acmeproposal , christmas , soccer , and audit . Richard's primary group is richard , as that is the group listed in his entry in /etc/passwd . When Richard logs in, the shell starts with its group identity set to the primary group, so any new files or directories created have richard as the group owner.
The group identity can be changed at any time using the newgrp command, and verified with the id command:
richard$ id
uid=503(richard) gid=503(richard) groups=503(richard),504(audit),505(soccer), 506(toronto),511(acmeproposal),512(christmas),608(it)
richard$ newgrp audit
richard$ id
uid=503(richard) gid=504(audit) groups=503(richard),504(audit),505(soccer), 506(toronto),511(acmeproposal),512(christmas),608(it)
The current group identity (also called real group ID ) affects only the creation of files and directories; existing files and directories keep their existing group, and a user can access files accessible to any group to which she belongs.
In this case, Richard can access any file that is readable by, say, the acmeproposal group, even when his current real group ID is audit . However, any files he creates will be owned by the group audit and won't be accessible to the acmeproposal group.
chgrp modifies the group ownership of an existing file. The group name is given as the first argument, and all other arguments are filenames:
$ ls -l report.txt
-rw-r--r-- 1 richard richard 3078 Oct 12 19:35 report.txt
$ chgrp audit report.txt
$ ls -l report.txt
-rw-r--r-- 1 richard audit 3078 Oct 12 19:35 report.txt
A normal user can set the group ownership only to one of the groups to which he belongs, and can change the group ownership only of files that he owns. The root user can set the group ownership of any file to any group. Like chmod , chgrp accepts the -R (recursive) option.
Using chgrp and newgrp is cumbersome. A much better solution is to use the SGID permission on directories, which automatically sets the group ownership.
Richard could create a directory named game_scores in his home directory, change the group ownership to soccer , and change the permission to rwxrws--- :
richard$ mkdir game_scores
richard$ chgrp soccer game_scores
richard$ chmod u=rwx,g=rwxs,o= game_scores
richard$ ls -ld game_scores
drwxrws--- 2 richard soccer 4096 Oct 12 19:46 game_scores
Everyone in the soccer group can access that directory. Because the SGID permission is set, any file created in that directory is automatically owned by the group soccer and can be accessed by other group membersexactly what is needed for collaboration within a group. The SGID permission is automatically applied to any directory created within games_scores , too.
When a Fedora program asks the Linux kernel to create a new file or directory, that program requests a default set of permissions. OpenOffice.org, for example, requests mode 0666 ( rw-rw-rw- ) on new files, because it knows that they aren't executable; the C compiler, on the other hand, requests 0777 ( rwxrwxrwx ) because the output of the C compiler should be an executable program.
This requested permission is limited by the current umask , which is an octal value representing the permissions that should not be granted to new files. If you want to prohibit anyone in your group from writing to or executing your files, and prevent others from doing anything at all with your files, the permissions that you want to restrict are ----wxrwx . In octal, that translates to 037.
You can set the umask with the shell command of the same name:
$ umask 037
umask by itself displays the current mask value:
$ umask
0037
This value is inherited by child processes, including all applications started by the shell.
The actual permissions set on a new file will be the permissions requested by the application after the permissions restricted by the umask are removed:
OpenOffice.org requested permission: rw-rw-rw-
Permissions restricted by umask: ----wxrwx
Permission applied to a new file: rw-r-----
The normal umask on Fedora systems is 002, which gives full read and write permission to everyone in your group. This works well in group-collaboration directories that have SGID permission set; other group members will be able to edit the files you have created, and vice versa. The beauty of the Fedora user-private-group system is that when you're not in a collaboration directory, new files default to ownership by your private group. This makes group permissions moot, since they apply only to you and are therefore effectively the same as the user permissions.
The superuser can change the ownership of a file using the chown command:
# chown accountfile barbara
This is useful when moving files between user accounts (for example, when an employee has left a company).
A file's user, group, and mode information is stored in a file's inode a small disk-based data structure containing vital information about a file. The user and group are stored as 32-bit numbers, which means that the maximum GID and UID are both 4,294,967,295 (232-1). However, some older applications still use 16-bit GID and UID values, so it's best to use IDs under 65,532 (216-4) plenty for most systems. IDs under 500 are reserved for system services; this is really just a convention adopted to avoid conflicts, since there is nothing special about user IDs with low numbers.
There is something special about user ID 0, though: it's reserved for the superuser, root . It is possible to create multiple accounts with the same ID, and this is sometimes used to create a second superuser account with a different password from the root account.
Each process also has a data structure that stores its real UID and GID, the effective UID and GID (which are different from the real IDs when a SUID or SGID program is running), and the umask . This data is copied to child processes automatically, but if the child process is a bash or csh shell, the umask value is reset by the shell startup scripts ( /etc/bashrc or /etc/csh.cshrc ).
You can configure the icon view of Nautilus by selecting Edit→Preferences and going to the Display tab. Up to three fields can be configured, in addition to the filename; by default, the first field is blank, the second field is the file size, and the third field is the date modified. Normally, only the first field is shown beneath each icon, but zooming in and out (using the menu options View→Zoom In and View→Zoom Out) will adjust the amount of information displayed.
This feature is not available in Konqueror.
The permissions tab of the file properties window in both Nautilus ( Figure 4-12 ) and Konqueror has a drop-down menu that permits you to change the group ownership if you are a member of multiple groups and you own the file.
/tmp is a special directory used to store temporary files ( /var/tmp is another). Since this directory is shared among all users, the sticky bit has been set to prevent users from deleting one other's files.
The chown command permits you to specify a group after the username, separated by a colon. To make /tmp/input owned by the user barbara and the group smilies , use:
# chown barbara:smilies /tmp/input
The manpages for chmod , chown , chgrp , newgrp , id , ulimit , umask , and groups
"User Private Groups" in the Red Hat Linux 9 manual: http://www.redhat.com/docs/manuals/linux/RHL-9-Manual/ref-guide/s1-users-groups-private-groups.html
A process is a running instance of a program. If you run a program twice, two processes are created. In order to manage a Fedora system effectively, you must be able to monitor and control processes.
Fedora provides multiple tools to monitor process activity and resource usage, modify process priority, and terminate processes.
Processes are identified by a Process ID (PID) number, which is sequentially assigned. There is a small set of information associated with each process, including:
nice
A value used to alter a process's scheduling priority, which determines how much CPU time the process receives. The actual priority assigned to a process is calculated based upon this factor, as well as how much CPU time the process has recently received and how many input/output (I/O) operations it has recently performed. This value is inherited by child processes.
parent process ID
The PID of the process that started the process. If the parent process disappears, this is replaced by 1 (the init process).
real user ID and effective user ID
The numeric user ID of the user actually running the program and the effective user running the program. These can be different only when the suid mechanism is active (see Lab 4.8, "Control Access to Files "), although an effective user ID remains in effect when a suid program calls a non- suid program.
real group ID and effective group ID
The numeric group ID of the group actually running the program and the effective group running the program. These are similar to the real and effective user IDs in that they will be different only when the sgid mechanism is active.
umask
The permission mask received from the parent process.
tty
The terminal associated with the program (if applicable). This permits all programs on that terminal to receive a hangup signal (HUP) when the terminal connection is lost, which is the case when a telephone modem call is hung up, a terminal window is closed, or a remote access Telnet/SSH session is terminated. This value is inherited by child processes.
It's important to realize that at any particular point in time, most processes are sleeping while they wait for some resource to become available. That resource might be a mouse click, a keystroke, a network packet, some data from disk, or a particular time of day.
The menu item Applications→System Tools→System Monitor will run gnome-system-monitor and present the display shown in Figure 4-13.
Figure 4-13. GNOME System Monitor window
This display has two tabs:
Processes
Displays a table of current processes with information about each.
Resources
Displays scrolling graphs displaying CPU, memory, and swap usage.
By default, the Processes tab displays the name of the program executing, process status (Sleeping or Running), Virtual Memory (VM) size, percentage of CPU time, the SELinux Security Context, and the arguments used on the command line that started the process (including the command name).
The default display shows the most useful information about each process, but to configure the display to your liking, you can:
Add and remove fields
Select Edit→Preferences to view a list of available fields (columns) with a checkbox for each. Check or uncheck items to add them to or remove them from the list. Close this window when you are done editing the field list.
Reorder and resize columns
Drag column headings to rearrange the order in which they are displayed. To change a column width, click between it and an adjacent column, and then drag to the desired width.
Sort a column
Click on a column heading to select that column for the sort sequence. An arrow will appear in the header (as shown on the VM Size column in Figure 4-13 ); click on the heading again to toggle between ascending and descending sort order.
Filter by process type
The Show menu lets you select your own processes, all processes on the system, or just the active (running, not sleeping) processes.
To terminate a process, highlight it by clicking on it and then click the End Process button, type Alt-P, or right-click on the process and select End Process. If that doesn't cause the process to terminate within a few seconds, right-click on the process and select Kill Process (or highlight the process and type Ctrl-K).
You won't be able to terminate processes owned by other users (including system processes) this way because you have insufficient permission. It is possible to run this program as root, which will let you terminate any process:
# gnome-system-monitor
Terminating the wrong process(es) can leave your system in a partially functioning or unusable state, and it may be necessary to reboot the system to recover. Be careful!
If you're using KDE in Fedora, the menu item System→KSysGuard will start ksysguard and display the window shown in Figure 4-14.
Figure 4-14. KSysGuard window
This tool is very customizable, but the basic display is similar to the GNOME System Monitor, except that the CPU usage is broken down into User% and System%, and the memory size is broken down into VmSize (total process size) and VmRSS (Resident Set Size, the portion of the VmSize currently in memory instead of swap). Use the Process Table tab to monitor and control running processes.
To customize the display, you can:
Show and hide columns
To remove a column from the display, right-click somewhere within that column (not on the heading) and select Hide Column. To add a column, right-click in an existing column (again, not on the heading), and select Show Column and then the column name you wish to add.
Reorder and resize columns
Drag column headings to rearrange the order in which they are displayed. To change a column width, click between it and an adjacent column, and then drag to the desired width.
Sort a column
Click on a column heading to select that column for the sort sequence. Click on the heading again to toggle between ascending and descending sort order.
Filter by process type
The pull-down menu at the bottom of the display enables you to choose whether to display all processes, system processes (such as servers), user processes for all users, or just your own processes.
To terminate a process, right-click on the process and select Send Signal→SIGTERM. If that doesn't cause the process to terminate within a few seconds, highlight the process and then click the Kill button in the lower-right corner of the window (right-click on the process and select Send Signal→SIGKILL).
Just like the GNOME System Monitor, the KSysGuard program can't terminate processes owned by other users (including system processes) when run by a normal user. To run the program as root:
# ksysguard
KSysGuard can monitor many aspects of system status in addition to the process table; it's also capable of monitoring remote systems. See the KSysGuard Manual for details (press F1 in the KSysGuard window).
A similar tool is available for character-mode displays, named top :
$ top
The output from top is shown in Figure 4-15 .
Like the graphical process monitors, top updates its display regularlyevery three seconds by default. You can customize the display using the controls shown in Table 4-15 .
Figure 4-15. Output from top
Table 4-15. Top customization options
Key | Description |
---|---|
? | Display help. |
u | Restrict the display to processes owned by one user. |
M | Sort by memory usage. |
P | Sort by current CPU usage. |
T | Sort by time (cumulative CPU usage). |
m | Toggle memory summary on/off. |
f | Field-list customization display. You will see a menu of possible fields; press the letter of the field you wish to toggle on/off, then Enter to exit from this display. |
o | Field-order customization display. You will see a list of displayed fields; type the uppercase letter for a field to shift the field left on the display, or type the lowercase letter to shift it right. Press Enter to exit this display. |
To end a process, type k (for kill ). Type in the process ID and press Enter; top will prompt you for the signal to be used. Press Enter to accept the default (15). If the process does not terminate within a few seconds, repeat the procedure with the signal 9.
Instead of using top to continuously monitor information, you can use the ps (process status) command to display a snapshot of the process table at a particular point in time.
By default, ps shows only processes executed by you on the current terminal:
$ ps
PID TTY TIME CMD
14797 pts/1 00:00:00 bash
22962 pts/1 00:00:00 ps
This shows the process ID, terminal device ( pts/1 means /dev/pts/1 ), total amount of CPU time consumed (less than one second in this example), and the command executed. This information alone is rarely useful, so ps is almost always used with some arguments.
ps uses options to select the processes to be displayed. The most useful ones are:
-A-e
All (or everyone's) processes
-u user
Processes owned by user (which can be a username or numeric user ID)
Other options are used to control the output format:
-f
Displays full information, including the UID, PID, PPID, start time (STIME), terminal (TTY), total CPU time used (TIME), and command (CMD).
-F
Displays extra-full information: everything included in -f , plus the processor number of the CPU the program is running on (PSR) and the approximate kilobytes of RAM used (RSS).
Like ls, the ps command has dozens of options. The Fedora version of ps can use Unix System V syntax or BSD syntax, so many option letters have two meanings; the one that is used depends on whether the option is specified with or without a hyphen!
To see the full documentation for ps, view the manpage but be prepared to take some time; it's over 16 pages long!
You can terminate processes by command name or by PID. When you terminate a process by name, you save yourself the hassle of looking up the PID, but if there is more than one process of the same name running, you will kill them all.
To kill by command name:
$ killall xclock
If the process doesn't terminate within a few seconds, add the -KILL argument:
$ killall -KILL xclock
Note that this will kill only processes of that name that are owned by you ; you don't have permission to kill other users' processes unless you are root . You will see an error message if other users have a process of the same name running, but this will not affect the killing of the processes that you own.
To kill PID 48292:
$ kill 48292
Again, if that doesn't work within a reasonable period of time, add the -KILL argument:
$ kill -KILL 48292
The Linux kernel has only two basic functions for starting processes: fork( ) and exec( ) .
fork( ) makes an exact copy of the current process and starts it running. exec( ) replaces the currently running program with a new program, running in the same process. So to get a new program running, the shell uses fork( ) to create a child process (a copy of the shell) and then uses exec( ) to change the program running in the child process.
When a child process is created, a number of variables are inherited from the parent process, including the real and effective user IDs, the real and effective group IDs, the umask , the terminal, the current working directory, and the environment variables.
Processes are generally permitted to run on a CPU until their timeslice the amount of time allocated to them by the scheduling algorithmis over, at which point another process is scheduled to be run.
However, processes frequently give up the CPU early because they reach a point when they need a resource to continue; this is called blocking . This is often due to slow input/output operations; no matter how fast your disk drive is, the CPU is still faster, so when one process is waiting for disk data, another process can be executing.
The difference between your typing speed and your CPU speed is even greater; most people type six characters per second or less, so on a 3 GHz PC, the CPU will average at least 500 million operations between keystrokes.
Since processes are usually waiting for data, it's not uncommon for programs to run for only a few seconds a day. I've been using my X display server heavily all day, and it's accumulated less than 30 minutes of CPU time; my POP3 mail server, which is accessed 600 times and transfers several hundred megabytes of data each day, accumulates less than 20 seconds of CPU time a day.
The 2.6 kernels now used in Fedora do fully preemptive scheduling, which means that when data does arrive for a sleeping process, and that sleeping process has a higher priority than the process currently running, the kernel will preempt the running process and immediately schedule the new process for execution (instead of waiting for the currently executing process to reach the end of its timeslice).
The kernel dynamically changes the priority of a process based on the amount of time since it last executed, the amount of time it has executed recently, the amount of I/O it is performing, and the nice value.
To terminate a running process, a numeric signal is sent to that process. To see all of the available signals, use the -l argument to kill , which shows the signal names and numbers:
$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL
5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE
9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2
13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD
18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN
22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO
30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1
36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5
40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9
44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13
52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9
56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5
60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1
64) SIGRTMAX
Each of these signals has a specific meaning, which can usually be determined from the signal name; for example, SIGHUP is the hangup signal, SIGINT is the interrupt signal (sent when you use Ctrl-C to try to interrupt a program running on a terminal or character-mode VT), SIGFPE is the signal for floating-point exceptions (such as division by zero), and SIGPWR is the signal for a power failure. Most of these signals are generated automatically by the kernel and basic server processes.
In most cases, a process can arrange to catch a particular signal and do something; for example, a text editor might save the current file when SIGHUP is received (the connection to the terminal is lost). If the process has not arranged to catch a signal, a default action is taken. In most cases, the default action is to terminate the process, but the default for some signals (such as SIGPWR ) is simply to ignore the signal and keep on running.
SIGTERM is used to request that a program terminate itself. Most programs catch this signal and clean up before they terminate, deleting any temporary files, saving data if necessary, informing network peers that they are terminating (where appropriate), and so forth. This is the default signal sent by top and kill , and the signal sent by the GNOME System Monitor when you specify End Program.
SIGKILL is uncatchable. It always terminates a program. This is useful when you wish to definitely terminate a program, but it doesn't give the program an opportunity to shut down gracefully, so files and network communications may be left in half-finished states, which may cause future problems. For this reason, it should be used as a last resort. SIGKILL is the signal sent by the Kill Program option in System Monitor and the Kill button in KSysGuard.
Both KDE and GNOME provide panel applets that display a continuous graph of the current CPU load, memory usage, and more. To add this applet to your panel bar, right-click on an empty area on the bar and select "Add to Panel." For GNOME, select System Monitor; for KDE, select Applet→KSysGuard. You can configure the display by right-clicking on it and selecting Preferences or Properties.
The nice command starts a process with a lower-than-normal priority. The priority can be reduced by any value from 1 to 19 using the -n argument; without -n , the priority is reduced by a value of 10. The command to be run is the only other argument required (any additional arguments are used as arguments to that command):
$ nice -n 15 xboard
To raise the priority of a process, you must be root ; supply a negative priority adjustment between 1 (slight boost in priority over normal) to 20 (highest priority):
# nice -n -12 xboard
renice is the tool for this:
$ xboard &
[3] 27365
$ renice 5 27365
27365: old priority 0, new priority 5
$ renice 2 27365
renice: 27365: setpriority: Permission denied
Note that the value used with the nice command is the opposite of what you may usually associate with a priority. Put another way, a nice level of 20 results in a process that isn't very nice to its fellow processes, since it's running at a high priority and hogs the CPU.
Notice that renice does not permit the user to increase the priority of a process, even if the user lowered it in the first place. However, root can set any priority she chooses:
$ renice -5 27365
renice: 27365: setpriority: Permission denied
# renice 2 27365
27365: old priority 5, new priority 2
# renice -5 27365
27365: old priority 2, new priority -5
You can also adjust the priority of processes in System Monitor and KSysGuard using the options on the context menu (right-click on the process you wish to adjust).
When using the shell, you can start a process in the background by placing an ampersand after the command:
$ xboard &
[21771]
$ mc &
[21783]
$
The shell will display the PID of the background process, then immediately present a new prompt, permitting you to enter additional commands before the background command has finished executing.
You can display background processes using the jobs command:
$ jobs
[1]- Running xboard &
[2]+ Stopped . /usr/share/mc/bin/mc-wrapper.sh
Any program that attempts to communicate through the character interface, such as Midnight Commander ( mc ) in this example, will be stopped. Programs that communicate through the graphical user interface, such as xboard , are free to do so while running in the background.
To put a stopped command in the foreground so that you can interact with it, use the fg command:
$ fg 2
The argument is the job number as reported by the jobs command. You can stop the current foreground process by pressing Ctrl-Z.
To run a stopped process in the background, use the bg command:
$ fg 1
xboard
...User presses Ctrl-Z...
[1]+ Stopped xboard
$ jobs
[1]+ Stopped xboard
[2]- Stopped . /usr/share/mc/bin/mc-wrapper.sh
$ bg 1
[1]+ xboard &
$
You can use a percent sign and a job number instead of a PID when killing processes:
$ kill %1
$
[3]- Exit 15 xboard
Descriptions of each signal: the manpage for signal(7)
The manpages for bash (for job control, including jobs , fg , bg , and the version of kill that is built into bash ), top , ps , and kill
It's often useful to be able to log in to a machine remotely to perform some management operation. To enable secure remote access, Fedora provides the Secure Shell (SSH).
SSH consists of two components: ssh (the client) and sshd (the server). The server is configured automatically when Fedora is installed.
To connect to a Fedora system from another Fedora system (or another Linux system), run the ssh client, providing the remote username and hostname (or IP address) as a single argument ( user @ host ). For example, to log in to a host with the IP address 10.0.0.1 using the user ID jon :
$ ssh jon@10.0.0.1
The authenticity of host '10.0.0.1 (10.0.0.1)' can't be established.
RSA key fingerprint is 1d:dd:20:72:b1:0c:28:90:9a:ff:43:69:03:12:71:02.
Are you sure you want to continue connecting (yes/no)?
yes
Warning: Permanently added '10.0.0.1' (RSA) to the list of known hosts.
jon@10.0.0.1's password:
AnotherSecret
Last login: Tue Oct 25 23:13:40 2005 from london-office
$
The question about the authenticity of the remote host will be asked only the first time you connect. The fingerprint value displayed can be used to verify the identify of the remote host and ensure that you're not being conned by a computer located between you and the computer you're trying to connect to; if you're really paranoid, you can check this value, but for most normal applications this isn't necessary. The fingerprint is cached, though, so if it changes in the future you will be warned. It's necessary to type in yes to confirm that you want to continue connecting; y won't suffice.
Once you are connected to the remote machine, you can use the shell as you normally would.
It's possible to configure ssh to enable you to connect from your account on one machine to your account on another machine using public-key cryptography instead of a password. Unfortunately, this means that if your account on one machine is compromised, your account on the other machine will be compromised, too; to prevent this, you can use a passphrase , a master password that you enter once per session that permits you to connect multiple times to remote systems without entering a password each time.
To set this up, enter these commands on the client machine (i.e., the machine from which you will be connecting to the remote host):
$ ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/home/chris/.ssh/id_dsa):
Enter
Enter passphrase (empty for no passphrase):
BigSecret
Enter same passphrase again:
BigSecret
Your identification has been saved in /home/chris/.ssh/id_dsa.
Your public key has been saved in /home/chris/.ssh/id_dsa.pub.
The key fingerprint is:
3a:f7:e8:88:59:fb:56:f7:0f:55:6b:fe:f6:ec:e2:2c chris@super
$ ssh jon@remoteMachine "cat > ~/.ssh/authorized_keys" <~/.ssh/id_dsa.pub
jon@remoteMachine's password:
AnotherSecret
The entire SSH security model revolves around the fact that the private key is private. If you permit access to your private key, the security is completely compromised.
This generates a public key and installs it on the remote system. If you will be connecting to multiple host systems, distribute your key to all of the systems by repeating the previous ssh command for each host.
Once the public key is installed on the remote host, you can use the ssh-add command to enter your passphrase:
$ ssh-add
Enter passphrase for /home/jon/.ssh/id_dsa:
BigSecret
Identity added: /home/jon/.ssh/id_dsa (/home/jon/.ssh/id_dsa)
If you're not logged in to your Fedora system through the GUI, you will need to enter this command before using ssh-add:
$ eval $(ssh-agent)
Agent pid 15431
When you log in using the GUI, Fedora starts the ssh-agent program automatically.
You can now connect to remote hosts without logging in:
$ ssh jon@remoteMachine
Last login: Wed Oct 26 00:20:29 2005 from toronto-office
If you wish to run just a single command, you can enter it on the ssh command line instead of logging in:
$ ssh jon@remoteMachine cal 3 1967
March 1967
Su Mo Tu We Th Fr Sa
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
The -X option (uppercase) causes ssh to set up an encrypted tunnel for graphical X connections alongside the shell connection. This permits you to start graphical apps on the remote machine and display the output on the local machine (assuming that you're connecting from a graphical session):
$ ssh -C -X jon@10.0.0.1
Last login: Wed Oct 26 00:31:42 2005 from parisoffice
$
oowriter
In order for this to work, the remote host must have X11Forwarding set to yes in its /etc/ssh/sshd_config file.
The -X option may cause remote X clients to be counted as untrusted from the point of view of the X server. This is perfect for most purposes, but if you want the remote client to be able to do screen captures (for example, if the remote application is the GIMP and you want to acquire a screenshot), substitute -Y for -X to configure the remote client as trusted.
SSH uses a variety of ciphers to encrypt your data as it travels across the network. The exact ciphers used can be configured in /etc/ssh/ssh_config (for the client) and /etc/ssh/sshd_config (for the server). Configuring a stronger cipher will provide better protection, but will use more CPU power and possibly reduce communication speed; the default settings are a good compromise between security and performance.
Public-key authentication relies upon the fact that two extremely large numbersthe public key and private key , which are derived mathematically from a single large random number, can be used with cryptographic formulas to encrypt and decrypt data. Anything encrypted with the public key can be decrypted only with the private key (not with the public key or any other number), and anything encrypted with the private key can be decrypted only with the public key. If the private key is kept secret and the public key is distributed to the whole world, then any message that can be decrypted by the public key must have been encrypted with the private key, proving the identity of the sender ( authentication ); any message that is encrypted with the public key can only be decrypted by the private key, ensuring secrecy ( authorization ).
In the case of SSH, the ssh-keygen command generates a public/private key pair, placing the private key in ~/.ssh/id_dsa and the public key in ~/.ssh/id_dsa.pub . When the public key is copied to the remote machine and placed in ~/.ssh/authorized_keys , an access request encrypted with the private key can be authenticated using the public key. If the public key is protected with a passphrase, you will be prompted for it each time you connect to a remote machine; to reduce this burden, the ssh-agent program can store your passphrase for you. The ssh-add command prompts you for your passphrase(s) and hands them over to ssh-agent (which is run automatically when the GUI starts up).
SSH is very susceptible to man-in-the-middle attacks, where a system between the client and server intercepts communication and presents itself as the client to the server, and the server to the client. However, this type of attack is a lot harder to set up than it would first appear and is rarely encountered. The caching of the host key (presented onscreen in summary format as the fingerprint ) guards against this after the first contact between the client and server systems has been made.
The -C option (note the capital letter!) causes ssh to compress data with gzip before encryption. This can significantly improve performance in some cases:
$ ssh -C jon@10.0.0.1
To do this, you need a Windows SSH client. There are several available, but for most purposes I'd recommend the free (libre et gratuit) program Putty, downloadable from http://www.chiark.greenend.org.uk/~sgtatham/putty/ . Of course, you won't be able to use graphical applications unless you've also installed an X server on your windows systembut that's not impossible (see http://x.cygwin.com/ for one possibility).
Mac OS X and most other Unix/Linux/BSD-based systems generally have an SSH client installed.
If you're using a broadband connection with a router or gateway, you'll have to configure the router to pass incoming connections on the SSH port to your Fedora system. Use the router's Applications and Gaming, Port Forwarding, or Servers configuration options to forward TCP/IP port 22 to your Fedora system. Then you can connect to the Fedora system by specifying the address of the gateway system in the ssh client arguments.
For example, if the external IP address of the gateway is 1.2.3.4, and the LAN IP address of your Fedora system is 10.0.0.1, configure the router to pass incoming connections on TCP/IP port 22 to 10.0.0.1, and then use the gateway IP address in the client arguments:
$ ssh jon@1.2.3.4
You may also need to configure Fedora's firewall to permit SSH connections.
Just leave the passphrase blank when running ssh-keygen . This is convenient because you won't need to use ssh-agent and ssh-add , and can always log in to remote systems without the passphrase. However, it's also dangerous because any attacker who obtains access to your local account will automatically gain access to your remote accounts as well.
The OpenSSH web site: http://openssh.org/
The manpages for ssh , sshd , ssh_config , sshd_config , ssh-agent , ssh-add , and ssh-keygen
The Unix/Linux philosophy revolves around the concept of programs as building blockseach one intended to do one job and do it well. Redirection lets you connect these commands to files, and piping enables you to plug commands together like a child's toy.
Each command has three numbered file descriptors that are opened automatically:
standard input (stdin, file descriptor 0)
The normal input to the program
standard output (stdout, file descriptor 1)
The normal output from the program
standard error (stderr, file descriptor 2)
Error messages from the program
By default, these file descriptors are connected to the terminal, if one is available, so standard input comes from the terminal keyboard, and standard output and standard error go to the terminal screen. Programs may open any other connections they need to read or write files, communicate with other local programs, or communicate with programs over the network.
To redirect the output of a program to a file, use the greater-than ( > ) symbol followed by the name of the file:
$ cal 7 2006
July 2006
Su Mo Tu We Th Fr Sa
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
$ cal 7 2006 > month.txt
$ cat month.txt
July 2006
Su Mo Tu We Th Fr Sa
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
When you redirect output with > , the previous contents of the file are overwritten. To append (add) to the file, use >> :
$ cal 3 2009 >> month.txt
$ cat month.txt
July 2006
Su Mo Tu We Th Fr Sa
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
July 2006
Su Mo Tu We Th Fr Sa
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
March 2009
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Error messages are not sent to standard output, so you can still see the messages even when standard output is redirected:
$ cal 17 2009 > month.txt
cal: illegal month value: use 1-12
To redirect error messages, place the file descriptor number ( 2 ) in front of the redirection symbol ( > or >> ):
$ cal 17 2009 2 >errors
$ cat errors
cal: illegal month value: use 1-12
You can redirect both standard output and standard error:
$ cal 17 2009 > month.txt 2 >errors
To redirect the input of a command, use the less-than sign ( < ) followed by the filename containing the data you wish to use as the input:
$ echo " 2^8 " > problem
$ bc < problem
256
bc is a calculator program. The first command places a numeric expression in the file problem ; the second line starts bc , using problem as the input. The output from bc is the solution of the expression: 256 .
Of course, you can redirect both input and output:
$ bc < problem > result
A pipe is a mechanism used to connect the standard output of one program to the standard input of another program. To create a pipe, insert the vertical-bar ( | ) symbol between the two commands:
$ mount
/dev/mapper/main-root on / type ext3 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
/dev/hdc2 on /boot type ext3 (rw)
tmpfs on /dev/shm type tmpfs (rw)
/dev/mapper/main-home on /home type ext3 (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
/dev/sdb on /media/disk type vfat (rw,noexec,nosuid,nodev,shortname=winnt,uid=503)
$ mount | grep /dev/mapper
/dev/mapper/main-root on / type ext3 (rw)
/dev/mapper/main-home on /home type ext3 (rw)
In this example, the output of the mount command is used as the input to the grep command, which outputs only lines that match the specified pattern. A group of commands connected together with pipe symbols is known as a pipeline . You can extend a pipeline by connecting additional commands:
$ mount | grep /dev/mapper | sort
/dev/mapper/main-home on /home type ext3 (rw)
/dev/mapper/main-root on / type ext3 (rw)
The input to a pipeline and the output from a pipeline may be redirected:
$ cut -d: -f1 </etc/passwd|sort|head > output
$ cat output
adm
apache
avahi
beaglidx
bin
chip
chris
daemon
dbus
distcache
However, it's essential that the input redirect take place at the start of the pipeline (at the command on the left) and that the output redirection take place at the end (at the command on the right). Consider this wrong example:
$ cut -d: -f1 </etc/passwd|sort > output |head
In this case, it's unclear whether the standard output of sort should be placed in the file output or used as the standard input to the head command. The result is undefined (which means don't do this! ).
Redirection is set up by the bash shell before the command is executed. If there is a redirection error (such as an invalid filename or a file permission problem), it will be reported by the shell and the command will not be executed:
$ cal > foo/bar/baz
bash: foo/bar/baz: No such file or directory
Note that the error message starts with bash, indicating that it was produced by the shell and not by the cal command.
A command is not aware of file redirection unless it has specifically been programed to check the standard file descriptors or perform special operations on them (such as changing terminal characteristics). Redirected file descriptors are inherited by applications that were started by commands; in this example, the nice command starts the cal command, and cal inherits the redirection set up for nice :
$ nice "cal" > test.txt
$ cat test.txt
July 2006
Su Mo Tu We Th Fr Sa
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
You can use the characters 2>&1 to redirect standard error to the same destination as standard output:
$ cal 17 2009 > /tmp/calresult 2>&1
Notice that the order of the redirections matters. The preceding command will redirect all output to /tmp/calresult , but this command will not redirect standard error:
$ cal 17 2009 2>&1 > /tmp/calresult
The 2>&1 redirection is evaluated first, so standard error is directed to the same destination as standard output (which, at that point, is the terminal); > /tmp/calresult then redirects standard output by itself.
This construct can also be used with piping:
$ cal 17 2009 2>&1 | head -2
This will feed both the standard output and the standard error from cal into the standard input of head .
Linux treats most devices as files, so you can redirect data to and from devices easily. This command copies the first 50 lines of the /etc/services file directly to a parallel printer port:
$ head -50 /etc/services > /dev/lp0
The tee command will receive data on standard input and write one copy to a file and one copy to standard output. This effectively splits a pipe:
$ cal -y | tee /tmp/thisyear.txt | head -2
To send a copy of the data to the screen, use tee with the device file /dev/tty (the current terminal):
$ cal -y | tee /dev/tty | grep Mo | head -1 >/tmp/dow-header.txt
No assumptions are made about the type of data being piped or redirected; in fact, there are many programs that are designed to work with piped graphics, audio, or video data streams. For example, this pipeline will decode a color JPEG image, scale it to half-size, convert it to grayscale, normalize it, convert it back into a JPEG, save a copy as /tmp/final.jpg , and display the output in a window:
$ djpeg /usr/share/wallpapers/floating-leaves.jpg | pnmscale 0.5 | ppmtopgm | ppmnorm | cjpeg | tee /tmp/final.jpg | display -
The manpage for bash
bash command lines can get to be very long, especially when pipes are used. A script is a text file that contains shell commands that may itself be executed as a command, providing an easy way to reuse complex sequences of commands. In fact, bash provides a complete programming language for use in scripts.
To create a script, simply place commands in a text file. For example, this script will display the ten largest files in the current directory:
ls -lS | tail -n +2 | head -10
Save this file as topten . In order to run the script, you will need to set read and execute permission:
$ chmod a+rx topten
The script can be executed by specifying the directory and filename (or an absolute pathname):
$ ./topten
-rw-r--r-- 1 root root 807103 Jul 12 21:18 termcap
-rw-r--r-- 1 root root 499861 Jul 17 08:08 prelink.cache
-rw-r--r-- 1 root root 362031 Feb 23 08:09 services
-rw-r--r-- 1 root root 97966 Jul 15 11:19 ld.so.cache
-rw-r--r-- 1 root root 92794 Jul 12 12:46 Muttrc
-rw-r--r-- 1 root root 83607 Mar 23 07:23 readahead.files
-rw-r--r-- 1 root root 73946 Jul 13 02:23 sensors.conf
-rw-r--r-- 1 root root 45083 Jul 12 18:33 php.ini
-rw-r--r-- 1 root root 30460 Jul 13 20:36 jwhois.conf
-rw-r--r-- 1 root root 26137 Mar 23 07:23 readahead.early.files
The directory name is required because the current directory ( . ) is not in the list of directories normally searched for commands (called the PATH). To make your script accessible to all users, move it to the /usr/local/bin directory, which appears by default in everyone's PATH:
# mv topten /usr/local/bin
bash uses shell variables to keep track of current settings. These shell variables are private to the shell and are not passed to processes started by the shellbut they can be exported , which converts them into environment variables , which are passed to child processes.
You can view all shell and environment variables using the set command:
$ set
BASH=/bin/bash
BASH_ARGC=( )
BASH_ARGV=( )
BASH_LINENO=( )
BASH_SOURCE=( )
BASH_VERSINFO=([0]="3" [1]="1" [2]="17" [3]="1" [4]="release" [5]="i686-redhat-linux-gnu")
BASH_VERSION='3.1.17(1)-release'
COLORS=/etc/DIR_COLORS.xterm
COLORTERM=gnome-terminal
COLUMNS=172
CVS_RSH=ssh
DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-I4CWWfqvE6,guid=e202bd44a31ea8366b20151327662e00
DESKTOP_SESSION=default
DESKTOP_STARTUP_ID=
DIRSTACK=( )
DISPLAY=:0.0
EUID=503
GDMSESSION=default
GDM_XSERVER_LOCATION=local
GNOME_DESKTOP_SESSION_ID=Default
GNOME_KEYRING_SOCKET=/tmp/keyring-FJyfaw/socket
GROUPS=( )
GTK_RC_FILES=/etc/gtk/gtkrc:/home/hank/.gtkrc-1.2-gnome2
G_BROKEN_FILENAMES=1
HISTFILE=/home/hank/.bash_history
HISTFILESIZE=1000
HISTSIZE=1000
HOME=/home/hank
HOSTNAME=bluesky.fedorabook.com
HOSTTYPE=i686
IFS=$' \t\n'
INPUTRC=/etc/inputrc
KDEDIR=/usr
KDE_IS_PRELINKED=1
LANG=en_US.UTF-8
LESSOPEN='|/usr/bin/lesspipe.sh %s'
LINES=55
LOGNAME=hank
LS_COLORS='no=00:fi=00:di=00;34:ln=00;36:pi=40;33:so=00;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=00;32:*.cmd=00;32:*.exe=00;32:*.com=00;32:*.btm=00;32:*.bat=00;32:*.sh=00;32:*.csh=00;32:*.tar=00;31:*.tgz=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.zip=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.bz=00;31:*.tz=00;31:*.rpm=00;31:*.cpio=00;31:*.jpg=00;35:*.gif=00;35:*.bmp=00;35:*.xbm=00;35:*.xpm=00;35:*.png=00;35:*.tif=00;35:'
MACHTYPE=i686-redhat-linux-gnu
MAIL=/var/spool/mail/hank
MAILCHECK=60
OLDPWD=/usr/share/wallpapers
OPTERR=1
OPTIND=1
OSTYPE=linux-gnu
PATH=/usr/lib/qt-3.3/bin:/usr/kerberos/bin:/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/home/hank/bin
PIPESTATUS=([0]="0" [1]="141" [2]="0")
PPID=3067
PRELINKING=yes
PRELINK_FULL_TIME_INTERVAL=14
PRELINK_NONRPM_CHECK_INTERVAL=7
PRELINK_OPTS=-mR
PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/~}"; echo -ne "\007"'
PS1='$ '
PS2='> '
PS4='+ '
PWD=/etc
QTDIR=/usr/lib/qt-3.3
QTINC=/usr/lib/qt-3.3/include
QTLIB=/usr/lib/qt-3.3/lib
SESSION_MANAGER=local/beige.fedorabook.com:/tmp/.ICE-unix/2621
SHELL=/bin/bash
SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
SHLVL=2
SSH_AGENT_PID=2659
SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
SSH_AUTH_SOCK=/tmp/ssh-dNhrfX2621/agent.2621
TERM=xterm
UID=503
USER=hank
USERNAME=hank
WINDOWID=58721388
XAUTHORITY=/home/hank/.Xauthority
_=
qt_prefix=/usr/lib/qt-3.3
Many of these variables contain settings for particular programs. Some of the common variables used by many programs are shown in Table 4-16.
Table 4-16. Key environment variables
Name | Purpose | Format |
---|---|---|
DISPLAY | Information on which X display is being used | hostname:display.screen hostname is the hostname or IP address of the X server or blank for the local host, display is the display number, and screen is the screen number (optional; the screen number specifies the monitor in a multimonitor, single-person display configuration). |
HOME | Home directory | Absolute pathname of the user's home directory. |
HOSTNAME | Name of this computer | Fully qualified domain name of the local host. |
Location of the user's default mailbox | Absolute pathname of the user's mailbox (usually /var/spool/mail/<username>). | |
PATH | List of directories to be searched to find a command | Absolute pathnames of directories to be searched, separated by colons. |
PS1, PS2 | Primary and secondary shell prompts | Plain text. Special characters sequences consisting of \ and a letter are replaced with other information; for example, \w is replaced by the current working directory (see the manpage for bash for a complete list). |
TERM | Model number of the current terminal | Must correspond to a filename in /usr/share/terminfo/?/*. |
To set a shell variable, type the variable name, an equal sign, and the value you wish to assign (all values are treated as text):
$ A= red
Once a variable has been assigned a value, you can use it in commands, preceded by a dollar sign:
$ ls -l red
ls: red: No such file or directory
$ touch $A
$ ls -l red
-rw-r--r-- 1 hank hank 0 Jul 18 15:26 red
The echo command can be used to view the value of a variable:
$ echo $A
red
To destroy a variable, use the unset command:
$ echo $A
red
$ unset A
$ echo $A
$
Finally, to make a variable accessible to processes started by the current process, use the export command:
$ unset A
$ TEST=blue
$ echo $TEST # variable is known to the shell
blue
$ bash # start a child shell
[hank@beige foo]$ echo $TEST # variable is not known to child
[hank@beige foo]$ exit # exit back to parent shell
exit
$ export TEST # export the variable
$ echo $TEST # value is still known to the shell
blue
$ bash # start a new child shell
[hank@beige foo]$ echo $TEST # exported value is known to the child
blue
The PATH value is stored in an environment variable of the same name. Its value can be viewed like any other environment variable:
$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin
To add a directory to the existing directories, use $PATH on the righthand side of an assignment to insert the current value of the variable into the new value:
$ PATH=$PATH: /home/hank/bin
$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/home/hank/bin
You don't need to export PATH in this case because it has already been exported; assigning a new value does not changes its exported status.
Assuming that the topten script is saved in /home/hank/bin , you can now execute it by just typing its name:
$ topten
-rw-r--r-- 1 root root 807103 Jul 12 21:18 termcap
-rw-r--r-- 1 root root 499861 Jul 17 08:08 prelink.cache
-rw-r--r-- 1 root root 362031 Feb 23 08:09 services
-rw-r--r-- 1 root root 97966 Jul 15 11:19 ld.so.cache
-rw-r--r-- 1 root root 92794 Jul 12 12:46 Muttrc
-rw-r--r-- 1 root root 83607 Mar 23 07:23 readahead.files
-rw-r--r-- 1 root root 73946 Jul 13 02:23 sensors.conf
-rw-r--r-- 1 root root 45083 Jul 12 18:33 php.ini
-rw-r--r-- 1 root root 30460 Jul 13 20:36 jwhois.conf
-rw-r--r-- 1 root root 26137 Mar 23 07:23 readahead.early.files
Within a script, you can prompt the user using the echo command, and then use the read command to read a line from the user and place it in an environment variable:
echo "Please enter your name:"
read NAME
echo "Hello $NAME!"
Or you can collect the standard output of a command and assign it to a variable using the $( ) symbols:
$ NOW=$(date)
$ echo $NOW
Tue Jul 18 22:25:48 EDT 2006
There are several special parameters , or special variables , that bash sets automatically; Table 4-17 contains a list of the most important ones.
Table 4-17. Important special variables
Name | Description | Notes |
---|---|---|
$$ | Process ID of the shell | Since process IDs are unique (at any one point in time), this can be used to ensure unique filenames (e.g., /tmp/$$.txt will never conflict with the same filename used by another copy of the same script). |
$0 | Name of the script | Useful to generate error messages, and when one script is invoked through more than one name. |
$1, $2, $3, ... | Arguments given on the script's command line | The shift command will eliminate $1 and then shift all of the parameters accordingly ($2 becomes $1, $3 becomes $2, and so forth). |
$# | Number of arguments from the script's command line | If $# is 0, then no options were given on the command line. |
$* $@ | All of the arguments from the script's command line | When quoted, "$*" becomes a single block of text containing all of the arguments, while "$@" becomes separate words. If the script is called with the arguments "green" and "yellow", then "$*" would evaluate to "green yellow", while "$@" would evaluate to "green" "yellow". |
$? | Exit status of the last command | Manpages document the possible exit-status values for most commands. |
Like most programming languages, bash features a number of control structures to enable looping and conditional execution. The three most common control structures are listed in Table 4-18 ; there is also a C-style for loop that I'll discuss in the next section.
Table 4-18. Common bash control structures
Structure | Notes | Example |
---|---|---|
for variable in list | The variable is assigned the first value in list, and loop-commands are executed. The process is then repeated for all of the other values in list. | # Set X to 'hosts', then display the filename and file contents. Repeat for 'services' |
do | for X in hosts services | |
loop-commands | do | |
done | echo "==== $X" | |
cat /etc/$X | ||
done | ||
if control-command | If the control-command succeeds, the if-commands are executed; otherwise, the else-commands are executed. | # Tell the user if the text 'test' appears in file1 |
then | if grep -q test file1 | |
if-commands | then | |
[else | echo "Found it!" | |
else-commands] | else | |
fi | echo "Not found." | |
fi | ||
while control-command | As long as control-command executes successfully, loop-commands are repeated. | # Display the free disk space every 2 seconds, forever |
do | while sleep 2 | |
loop-commands | do | |
done | df -h | |
done |
The for..in control structure is great for looping over a range of values. This loop will display the status of the httpd , ftpd , and NetworkManager services:
for SERVICE in httpd ftpd NetworkManager
do
/sbin/service $SERVICE status
done
for...in is even more useful when the list of values is specified as an ambiguous filename. In this script, the loop is repeated once for each file in the directory /etc/ that ends in .conf :
mkdir backup
for FILE in /etc/*.conf
do
echo "Backing up the file $FILE..."
cp $FILE backup/
done
For the if and while control structures, a control-command determines the action taken. The control-command can be any command on the system; an exit status of zero is considered TRue and any other exit status is considered false .
For example, the grep command exits with a value of zero if a given pattern is found in the file(s) specified or in the standard input. When combined with an if structure, you can cause a program to take a particular action if a pattern is found. For example, this code displays the message "Helen is logged in!" if the output of who contains the word helen :
if who | grep -q helen
then
echo "Helen is logged in!"
fi
The exit status of the last command is taken as the exit status of a pipeline, which is grep in this case. The -q argument to grep suppresses the outputotherwise, matching lines are sent to standard output.
The built-in command test can be used to test conditions; the exit status will be zero if the condition is TRue . The most common conditional expressions are listed in Table 4-19.
Table 4-19. Common bash conditional operators
Operator | Tests whether... | Example using an environment variable |
---|---|---|
-f file | File exists and is a regular file | -f "$A" |
-d file | File exists and is a directory | -d "$B" |
-r file | File exists and is readable | -r "$C" |
-w file | File exists and is writable | -w "$D" |
-x file | File exists and is executable | -x "$E" |
value1 == value2 | Strings match | "$F" == "red" |
value1 != value2 | Strings don't match | "$G" != "blue" |
value1 -eq value2 | Integer values are equal | "$H" -eq 2 |
value1 -ne value2 | Integer values are unequal | "$J" -ne 10 |
value1 -gt value2 | value1 integer value is greater than value2 | "$K" -gt 25 |
value1 -ge value2 | value1 integer value is greater than or equal to value2 | "$L" -ge 25 |
value1 -lt value2 | value1 integer value is less than value2 | "$M" -lt 75 |
value1 -le value2 | value1 integer value is less than or equal to value2 | "$N" -le 75 |
expression1 -a expression2 | expression1 and expression2 are both true | "$P" -gt 36 -a "$P" -lt 71 |
expression1 -o expression2 | expression1 or expression2 (or both) are true | "$P" -lt 12 -o "$P" -eq 50 |
So if you wanted to print "Too high!" if the value of the variable A was over 50, you would write:
if test "$A" -gt 50
then
echo "Too high!"
fi
The variable expression $A is quoted in case A has a null value ("") or doesn't existin which case, if unquoted, a syntax error would occur because there would be nothing to the left of -gt .
The square brackets ( [] ) are a synonym for test , so the previous code is more commonly written:
if [ "$A" -gt 50 ]
then
echo "Too high!"
fi
You can also use test with the while control structure. This loop monitors the number of users logged in, checking every 15 seconds until the number of users is equal to or greater than 100, when the loop will exit and the following pipeline will send an email to the email alias alert :
while [ "$(who | wc -l)" -lt 100 ]
do
sleep 15
done
echo "Over 100 users are now logged in!"|mail -s "Overload!" alert
bash provides very limited integer arithmetic capabilities. An expression inside double parentheses (( )) is interpreted as a numeric expression; an expression inside double parentheses preceded by a dollar sign $(( )) is interpreted as a numeric expression that also returns a value.
Inside double parentheses, you can read a variable's value without using the dollar sign (use A=B+C instead of A=$B+$C).
Here's an example using a while loop that counts from 1 to 20 using integer arithmetic:
A=0
while [ "$A" -lt 20 ]
do
(( A=A+1 ))
echo $A
done
The C-style increment operators are available, so this code could be rewritten as:
A=0
while [ "$A" -lt 20 ]
do
echo $(( ++A ))
done
The expression $(( ++A )) returns the value of A after it is incremented. You could also use $(( A++ )) , which returns the value of A before it is incremented:
A=1
while [ "$A" -le 20 ]
do
echo $(( A++ ))
done
Since loops that count through a range of numbers are often needed, bash also supports the C-style for loop. Inside double parentheses, specify an initial expression, a conditional expression, and a per-loop expression, separated by semicolons:
# Initial value of A is 1
# Keep looping as long as A<=20
# Each time you loop, increment A by 1
for ((A=1; A<=20; A++))
do
echo $A
done
Note that the conditional expression uses normal comparison symbols ( <= ) instead of the alphabetic options ( -le ) used by test .
Don't confuse the C-style for loop with the for...in loop!
So far we have been assuming that the user is using the bash shell; if the user of another shell (such as tcsh ) tries to execute one of your scripts, it will be interpreted according to the language rules of that shell and will probably fail.
To make your scripts more robust, add a shebang line at the beginning a pound-sign character followed by an exclamation mark, followed by the full path of the shell to be used to interpret the script ( /bin/bash ):
#!/bin/bash
# script to count from 1 to 20
for ((A=1; A<=20; A++))
do
echo $A
done
I also added a comment line (starting with # ) after the shebang line to describe the function of the script.
The shebang line gets its name from sharp and bang, common nicknames for the #! characters.
Here is an example of a longer script, taking advantage of some of the scripting features in bash :
#!/bin/bash
#
# number-guessing game
#
# If the user entered an argument on the command
# line, use it as the upper limit of the number
# range.
if [ "$#" -eq 1 ]
then
MAX=$1
else
MAX=100
fi
# Set up other variables
SECRET=$(( (RANDOM % MAX) + 1 )) # Random number 1-100
TRIES=0
GUESS=-1
# Display initial messages
clear
echo "Number-guessing Game"
echo "--------------------"
echo
echo "I have a secret number between 1 and $MAX."
# Loop until the user guesses the right number
while [ "$GUESS" -ne "$SECRET" ]
do
# Prompt the user and get her input
((TRIES++))
echo -n "Enter guess #$TRIES: "
read GUESS
# Display low/high messages
if [ "$GUESS" -lt "$SECRET" ]
then
echo "Too low!"
fi
if [ "$GUESS" -gt "$SECRET" ]
then
echo "Too high!"
fi
done
# Display final messages
echo
echo "You guessed it!"
echo "It took you $TRIES tries."
echo
This script could be saved as /usr/local/bin/guess-it and then made executable:
# chmod a+rx /usr/local/bin/guess-it
Here's a test run of the script:
$ guess-it
Number-guessing Game
--------------------
I have a secret number between 1 and 100.
Enter guess #1:
50
Too low!
Enter guess #2:
75
Too low!
Enter guess #3:
83
Too low!
Enter guess #4:
92
Too high!
Enter guess #5:
87
Too high!
Enter guess #6:
85
Too low!
Enter guess #7:
86
You guessed it!
It took you 7 tries.
Another test, using an alternate upper limit:
$ guess-it 50
Number-guessing Game
--------------------
I have a secret number between 1 and 50.
Enter guess #1:
25
Too low!
Enter guess #2:
37
Too low!
Enter guess #3:
44
Too high!
Enter guess #4:
40
You guessed it!
It took you 4 tries.
When a user logs in, the system-wide script /etc/profile and the per-user script ~/.bash_profile are both executed. This is the default /etc/profile :
# /etc/profile
# System wide environment and startup programs, for login setup
# Functions and aliases go in /etc/bashrc
pathmunge ( ) {
if ! echo $PATH | /bin/egrep -q "(^|:)$1($|:)" ; then
if [ "$2" = "after" ] ; then
PATH=$PATH:$1
else
PATH=$1:$PATH
fi
fi
}
# ksh workaround
if [ -z "$EUID" -a -x /usr/bin/id ]; then
EUID=\Qid -u\Q
UID=\Qid -ru\Q
fi
# Path manipulation
if [ "$EUID" = "0" ]; then
pathmunge /sbin
pathmunge /usr/sbin
pathmunge /usr/local/sbin
fi
# No core files by default
ulimit -S -c 0 > /dev/null 2>&1
if [ -x /usr/bin/id ]; then
USER="\Qid -un\Q"
LOGNAME=$USER
MAIL="/var/spool/mail/$USER"
fi
HOSTNAME=\Q/bin/hostname\Q
HISTSIZE=1000
if [ -z "$INPUTRC" -a ! -f "$HOME/.inputrc" ]; then
INPUTRC=/etc/inputrc
fi
export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC
for i in /etc/profile.d/*.sh ; do
if [ -r "$i" ]; then
. $i
fi
done
unset i
unset pathmunge
This script adds /sbin , /usr/sbin , and /usr/local/sbin to the PATH if the user is the root user. It then creates and exports the USER , LOGNAME , MAIL , HOSTNAME , and HISTSIZE variables, and executes any files in /etc/profile.d that end in .sh .
The default ~/.bash_profile looks like this:
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH
You can edit /etc/profile to change the login process for all users, or ~/.bash_profile to change just your login process. One useful change that I make to every Fedora system I install is to comment out the if statements for path manipulation in /etc/profile so that every user has the superuser binary directories in his path:
# Path manipulation
# if [ "$EUID" = "0" ]; then
pathmunge /sbin
pathmunge /usr/sbin
pathmunge /usr/local/sbin
# fi
bash comments start with # and are not executed so commenting out code means adding # at the start of selected lines to disable them
Environment variables are inherited by child processes, so any environment variables set up during the login process are accessible to all shells (and other programs) you start. bash also supports the use of aliases , or nicknames, for commands, but since these are not inherited by child processes, they are instead placed in the file ~/.bashrc , which is executed each time a shell starts. If you log in once and then start three shells, ~/.bash_profile is executed once at login and ~/.bashrc is executed three times, once for each shell that starts.
This is the default ~/.bashrc :
# .bashrc
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
# User-specific aliases and functions
As you can see, there aren't any alias definitions in there (but you can add them). The file /etc/bashrc is invoked by this script, and it contains common aliases made available to all users:
# System-wide functions and aliases
# Environment stuff goes in /etc/profile
# By default, we want this to get set.
# Even for noninteractive, nonlogin shells.
umask 022
# Are we an interactive shell?
if [ "$PS1" ]; then
case $TERM in
xterm*)
if [ -e /etc/sysconfig/bash-prompt-xterm ]; then
PROMPT_COMMAND=/etc/sysconfig/bash-prompt-xterm
else
PROMPT_COMMAND='echo -ne ↵
"\033]0;${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/~}";
echo -ne "\007"'
fi
;;
screen)
if [ -e /etc/sysconfig/bash-prompt-screen ]; then
PROMPT_COMMAND=/etc/sysconfig/bash-prompt-screen
else
PROMPT_COMMAND='echo -ne "\033_${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/~}"; echo -ne "\033\\"'
fi
;;
*)
[ -e /etc/sysconfig/bash-prompt-default ] && PROMPT_COMMAND=/etc/sysconfig/bash-prompt-default
;;
esac
# Turn on checkwinsize
shopt -s checkwinsize
[ "$PS1" = "\\s-\\v\\\$ " ] && PS1="[\u@\h \W]\\$ "
fi
if ! shopt -q login_shell ; then # We're not a login shell
# Need to redefine pathmunge, it get's undefined at the end of /etc/profile
pathmunge ( ) {
if ! echo $PATH | /bin/egrep -q "(^|:)$1($|:)" ; then
if [ "$2" = "after" ] ; then
PATH=$PATH:$1
else
PATH=$1:$PATH
fi
fi
}
for i in /etc/profile.d/*.sh; do
if [ -r "$i" ]; then
. $i
fi
done
unset i
unset pathmunge
fi
# vim:ts=4:sw=4
This script sets up the umask , configures a command that will be executed before the display of each prompt (which sets the terminal-window title to show the user, host, and current directory), and then executes each of the files in /etc/profile.d that end in .sh .
Packages installed on your Fedora system can include files that are placed in /etc/profile.d , providing a simple way for each package to globally add aliases or other shell configuration options. There are a few command aliases defined in these script files, including:
alias l.='ls -d .* --color=tty'
alias ll='ls -l --color=tty'
alias ls='ls --color=tty'
alias vi='vim'
If you type ll at a command prompt, ls -l will be executed, due to the alias highlighted in the preceding listing:
$ ll /
total 138
drwxr-xr-x 2 root root 4096 Jul 17 08:08 bin
drwxr-xr-x 4 root root 1024 Jul 15 11:16 boot
drwxr-xr-x 12 root root 3900 Jul 19 07:56 dev
drwxr-xr-x 102 root root 12288 Jul 18 18:14 etc
drwxr-xr-x 8 root root 4096 Jul 16 22:51 home
drwxr-xr-x 11 root root 4096 Jul 17 07:58 lib
drwx------ 2 root root 16384 Jun 9 19:34 lost+found
drwxr-xr-x 4 root root 4096 Jul 18 18:14 media
drwxr-xr-x 2 root root 0 Jul 18 11:48 misc
drwxr-xr-x 6 root root 4096 Jul 15 11:38 mnt
drwxr-xr-x 2 root root 0 Jul 18 11:48 net
drwxr-xr-x 2 root root 4096 Jul 12 04:48 opt
dr-xr-xr-x 126 root root 0 Jul 18 11:46 proc
drwxr-x--- 9 root root 4096 Jul 18 00:18 root
drwxr-xr-x 2 root root 12288 Jul 17 08:08 sbin
drwxr-xr-x 4 root root 0 Jul 18 11:46 selinux
drwxr-xr-x 2 root root 4096 Jul 12 04:48 srv
drwxr-xr-x 11 root root 0 Jul 18 11:46 sys
drwxrwxrwt 98 root root 4096 Jul 19 11:04 tmp
drwxr-xr-x 14 root root 4096 Jul 14 04:17 usr
drwxr-xr-x 26 root root 4096 Jul 14 04:17 var
Similarly, if you type vi the shell will execute vim .
You can create your own aliases using the alias command; for example, I like to use l for ls -l , sometimes use cls to clear the screen, and like to have machine report the hostname (old habits):
$ alias l='ls -l
$ alias cls='clear'
$ alias machine='hostname'
Adding the same lines to ~/.bashrc will make them available every time you start a new shell; adding them to ~/.bashrc will make them available to all users.
You can see the currently defined aliases by typing alias alone as a command:
$ alias
alias cls='clear'
alias l='ll'
alias l.='ls -d .* --color=tty'
alias ll='ls -l --color=tty'
alias ls='ls --color=tty'
alias machine='hostname'
alias vi='vim'
To destroy an alias, use the unalias command:
$ unalias machine
$ alias
alias cls='clear'
alias l='ll'
alias l.='ls -d .* --color=tty'
alias ll='ls -l --color=tty'
alias ls='ls --color=tty'
alias vi='vim'
When the kernel receives a request to execute a file (and that file is executable), it uses magic number codes at the start of the file to determine how to execute it. For example, there are magic numbers for standard Executable and Linking Format (ELF) binaries and historical assembler output ( a.out ) binaries; the kernel will use them to set up the correct execution environment and then start the program.
If the first two bytes of the file are #! , which counts as a magic number, the file is treated as a script: a pathname is read from the file starting at the third byte and continuing to the end of the first line. The shell or interpreter program identified by this pathname is executed, and the script name and all arguments are passed to the interpreter.
If a file has no magic number or shebang line, the kernel will attempt to execute it as though the value of the SHELL environment variable were given on the shebang line.
Other scripting languages such as Perl and Python can be used to construct full-scale GUI applications, but the zenity program enables a shell script to interact with a GUI user.
zenity presents a simple dialog or information box to the user. There are a number of dialog types available, including information and error boxes, text entry and editing boxes, and date-selection boxes; the type of dialog as well as the messages that appear in the dialog are configured by zenity options.
Here is the number-guessing script rewritten to use zenity for the user interface:
#!/bin/bash
#
# number-guessing game - GUI version
#
# If the user entered an argument on the command
# line, use it as the upper limit of the number
# range
if [ "$#" -eq 1 ]
then
MAX=$1
else
MAX=100
fi
# Set up other variables
SECRET=$(( (RANDOM % MAX) + 1 )) # Random number 1-100
TRIES=0
GUESS=-1
# Display initial messages
zenity --info --text \
"I have a secret number between 1 and $MAX. Try and guess it!" \
--title "Guess-It"
# Loop until the user guesses the right number
while [ "$GUESS" -ne "$SECRET" ]
do
# Prompt the user and get her input
((TRIES++))
GUESS=$(zenity --entry --text "Enter guess #$TRIES:" --title "Guess...")
# Display low/high messages
if [ "$GUESS" -lt "$SECRET" ]
then
zenity --info --text "Too low!"
fi
if [ "$GUESS" -gt "$SECRET" ]
then
zenity --info --text "Too high!"
fi
done
# Display final messages
zenity --info --text "You guessed it! It took you $TRIES tries." --title "Congratulations!"
Figure 4-16 shows the zenity dialogs produced by this script. Obviously, this user interface is not as refined as one that could be provided by a full-featured GUI application, but it is perfectly suitable for simple interactions.
Figure 4-16. zenity dialogs
The manpages for bash, chmod, and zenity