Finding Anything

One of the most useful commands in your arsenal is the find command. Generally speaking, find is used to list files and redirect (or pipe) that output to do some simple reporting or backups. The basic form of the command is as follows.

find starting_dir [options]

One of those options is -print, which makes sense only if you want to see any kind of output from this command. You could easily get a listing of every file on the system by starting at the top and recursively listing the disk.

find / -print

Although that might be interesting and you might want to redirect that to a file for future reference, it is only so useful. It makes more sense to search for something. For instance, look for all the JPEG-type image files sitting on your disk. Because you know that these images end in a .jpg extension, you can use that to search.

find / -name "*.jpg" -print

Depending on the power of your system, this can take a while, and you are likely to get a lot of Permission denied messages (particularly as you traverse a directory called /proc). If you are running this as a user other than root, you will likely get a substantial number of Permission denied messages. At this point, the usefulness of find should start to become apparent because a lot of images stashed away in various parts of the disk can certainly add up as far as disk space is concerned. Try it with an .avi or .mpg extension to look for video clips (which can be very large).

Faster Finds Using Locate

Depending on the power of your system (and the number of files), running a find can take quite a long time, and as I mentioned earlier, you are likely to get a lot of Permission denied messages.

Luckily, there is a faster way. On most Linux systems, you have a process that runs once a day (or once a week on some systems). That process builds a database of all the files on your system for quick and easy searching. The command is called locate or slocate. The process that runs on your system is located in /etc/cron.daily (or /etc/cron.weekly) and called slocate.cron. If your system is not up 24 hours, you can rebuild the slocate database any time you wish by running the cron script manually or with the command updatedb. Let us try to find those .jpg files again.

slocate jpg

Amazingly fast, isn't it? I should tell you that the find command is still quite a bit more powerful than slocate, but if you need to lay your hands on a file quickly and you have no idea where it has gone, try slocate.

Using grep

grep: Global regular expression parser.

That definition of the acronym is one of many. Don't be surprised if you hear it called the "gobble research exercise program" instead of what I called it. Basically, grep's purpose in life is to make it easy for you to find strings in text files. This is its basic format:

grep pattern file(s)

As an example, let's say you want to find out whether you have a user named natika in your /etc/passwd file. The trouble is that you have 500 lines in the file.

[root@testsys /root]# grep natika /etc/passwd
natika:x:504:504:Natika the Cat:/home/natika:/bin/bash

Sometimes you just want to know whether a particular chunk of text exists in a file, but you don't know which file, specifically. Using the -l option with grep enables you to list file names only, rather than lines (grep's default behavior). In the next example, I am going to look for Natika's name in my e-mail folders. Because I don't know whether Natika's name is capitalized in the mail folders, I'll introduce another useful flag to grep: the -i flag. It tells the command to ignore case.

[marcel@testsys Mail]# grep -i -l natika *
Baroque music
Linux Stuff
Personal stuff
Silliness
sent-mail

As you can see, the lines with the word (or name) Natika are not displayed?only the files. Here's another great use for grep. Every once in a while, you will want to scan for a process. The reason might be to locate a misbehaving terminal or to find out what a specific login is doing. Because grep can filter out patterns in your files or your output, it is a useful tool. Rather than trying to scan through 400 lines on your screen for one command, let grep narrow down the search for you. When grep finds the target text, it displays that line on your screen.

[root@testsys /root]# ps ax | grep httpd
1029 ?        S      0:00 httpd
1037 ?        S      0:00 httpd
1038 ?        S      0:00 httpd
1039 ?        S      0:00 httpd
1040 ?        S      0:00 httpd
1041 ?        S      0:00 httpd
1042 ?        S      0:00 httpd
1043 ?        S      0:00 httpd
1044 ?        S      0:00 httpd
30978 ?      S      0:00 httpd
1385 pts/2  S      0:00 grep httpd

Notice the last line that shows the grep command itself in the process list. You'll use that line as the launch point to one last example with grep. If you want to scan for strings other than the one specified, use the -v option. Using this option, it's a breeze to list all processes currently running on the system but ignore any that have a reference to root.

ps aux | grep ?v root

And speaking of processes....

Processes

All you have to remember is that any command you run is a process. Processes are also sometimes referred to as jobs.

The session program that executes your typed commands (the shell) is a process. The tools I am using to write this chapter are creating several processes. Every terminal session you have open, every link to the Internet, every game you have running?all these programs generate one or more processes on your system. In fact, there can be hundreds, even thousands of processes running on your system at any given time. To see your own processes, try the following command:

[root@testsys /root]# ps
  PID TTY          TIME CMD
12293 pts/5    00:00:00 login
12316 pts/5    00:00:00 su
12317 pts/5    00:00:00 bash
12340 pts/5    00:00:00 ps

For a bit more detail, try using the u option. This will show all processes owned by you that currently have a controlling terminal. Even if you are running as root, you will not see system processes in this view. If you add the a option to that, you'll see all the processes running on that terminal?in this case, revealing the subshell that did the su to root.

[root@testsys /root]# ps au
USER       PID %CPU %MEM   VSZ  RSS TTY      STAT START   TIME COMMAND
root     12293  0.0  0.4  2312 1196 pts/5    S    21:23   0:00 login ? mgagne
mgagne   12294  0.0  0.3  1732  976 pts/5    S    21:23   0:00 -bash
root     12316  0.0  0.3  2156  952 pts/5    S    21:23   0:00 su - root
root     12317  0.0  0.3  1736  980 pts/5    S    21:23   0:00 -bash
root     12342  0.0  0.2  2400  768 pts/5    R    21:24   0:00 ps au

The most common thing someone will do is add an x option. This will show you all processes, controlled by your terminal or not, as well as those of other users.

Killing Processes

Sometimes, a process (or program) gets hung and needs to be terminated. You can interrupt a foreground process (one you are running from the shell) by pressing <Ctrl+C>, but that does not work with background processes. The command used to terminate a process is called kill, which as it turns out is an unfortunate name for a command that does more than just terminate processes. By design, kill sends a signal to a job (or jobs). That signal is sent as an option (after a hyphen) to a process ID.

kill ?signal_no PID

For instance, you can send the SIGHUP signal to process 7612 like this:

kill ?1 7612

Signals are messages. They are usually referenced numerically, as with the ever-popular kill -9 signal, but there are a number of others. The ones you are most likely to use are 1, 9, and 15. These signals can also be referenced symbolically with these names.

Signal 1 is SIGHUP. This is normally used with system processes such as xinetd and other daemons. With these types of processes, a SIGHUP tells the process to hang up, reread its configuration files, and restart. Most applications will just ignore this signal.

Signal 9 is SIGKILL, an unconditional termination of the process. Some people I've worked with over the years call this "killing with extreme prejudice." The process is not asked to stop, close its files, and terminate gracefully. It is simply killed. This should be your last-resort approach to killing a process, and it works 99% of the time. Only a small handful of conditions will ever ignore the -9 signal.