Wednesday, April 24, 2013

Mastering the Linux Shell : Killing Processes and Dire Warnings

Today's installment of Mastering the Linux Shell comes with a warning. Actually, it comes with a few warnings. .And a viewer advisory. Well, actually a reader advisory.
You see, some of what I cover sounds pretty violent and discretion is advised. I'll be talking about processes and their children, and the need, at times to kill a process. You may even have to kill child processes so this is not for the squeamish. If it makes you feel any better, these processes are just code running somewhere in memory. It's not like Tron at all. They're just bits of information and when you power off your machine, they die anyway. I should point out that many long time Linux users never power their down their machines. Most people think it's because you really don't need to shut down or reboot Linux systems all that often. For some, however, it's because they can't bear to kill processes.
Enough silliness. On to the serious stuff.

Killing Processes

When we talk about killing a process, the common understanding is that you end the process. The program is closed and no longer running. That can be one way you kill processes, but there's more to it than that. You can usually interrupt a foreground process with the Control-C sequence 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 which does more than just terminate processes.   By design, kill sends signals to jobs.   That signal is sent as an option (after a hyphen) to a process ID. The process ID can be found using the ps command as I demonstrated in an earlier article.
kill –signal_no PID
For instance, I 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 inetd 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 admins I've known 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 works 99% of the time.   Only a small handful of conditions will ever ignore the -9 signal.
Signal 15, the default, is SIGTERM, a call for normal program termination.  The system is asking the program to wrap it up and stop doing whatever it was doing.
Remember when we suspended a process earlier using Control-Z?  That was another signal.  Try this to get a feel of how this works.  If you are running in an X display, start a digital xclock with a seconds display updated every second.
xclock -digital -update 1 &

You should see the second digits counting away.   Now, find its process ID with “ps ax | grep xclock”.   We’ll pretend the process ID is 12136.  Let’s kill that process with a “SIGSTOP”. 
kill SIGSTOP 12136
The digits have stopped incrementing, right?  Here's a cool trick. Try closing the window for the xclock by clicking on the x in the corner. It doesn't work, does it? I'll let you think about that one. For now, let’s restart the xclock.
kill SIGCONT 12136
As you can see, kill is probably a bad name for a command that can suspend a process, then bring it back to life.  For a complete list of signals and what they do, look in the man pages with this command.
man 7 signal
If you wanted to kill a process by specifying the symbolic signal, you would use the signal name minus the SIG prefix.  For instance, to send the -1 signal to cupsd, I could do this instead.
kill -HUP `pidof cupsd`
Note that these are back-quotes around the command string aboveThe pidof command does exactly what you think; it returns the PID of the cupsd daemon.

Dire Warnings

Since I've gone told you about terminating processes, it seems fitting that I revisit another, much earlier topic, where I discussed deleting files.  When killing processes, you want to be very careful. Some processes, when terminated, will terminate your entire desktop session, your network connection, or the entire running machine. Look for the process you need to terminate, then act accordingly. When operating as the superuser (i.e. the 'root' user), you can do anything and the system naturally assumes you know what you are doing. It's true when dealing with processes and it's true when deleting files.
I've used the explanation that everything on your Linux system is a file, but then I also said that there were different types of files.  In order to work with directory files, we have the following batch of commands which are ideally suited to this.
pwd (Print Working Directory)
cd (Change to a new Directory)
mkdir (MaKe or create a new DIRectory)
mv (MoVe directories, or like files, rename them)
rmdir (ReMove or delete DIRectories.)
One way to create a complicated directory structure is to use the mkdir to create each and every directory.
mkdir /dir1
mkdir /dir1/sub_dir
mkdir /dir1/sub_dir/yetanotherdir
What you could do instead is save yourself a few keystrokes and use the "-p" flag instead.  This tells "mkdir" to create any parent directories that might not already exist.   If you happen to like a lot of verbiage from your system, you could also add the "--verbose" flag for good measure.
mkdir –p /dir/sub_dir/yetanotherdir
To rename or move a directory, the format is the same as you used with a file or group of files.  Use the mv command.
mv path_to_dir new_path_to_dir
Removing a directory can be just a bit more challenging.   The command "rmdir" seems simple enough.  In fact, removing this directory was no problem.
$ rmdir trivia_dir
Removing this one, however, gave me this error.
$ rmdir junk_dir
rmdir: junk_dir: Directory not empty
You can only use rmdir to remove an empty directory.  There is a "-p" option (as in parents) that lets you remove a directory structure.  For instance, you could remove a couple of levels like this.
$ rmdir –p junk_dir/level1/level2/level3
All the directories from junk_dir on down will be removed, but only if they are empty of files. This is where it gets interesting. And dangerous.  The better approach is to use the rm command with the "-r", or recursive option.  Unless you are deleting only a couple of files or directories, you will want to use the "-f" option as well.
$ rm –rf junk_dir

And now, the DIRE WARNING!

Beware the "rm  –rf  *" command!  Better yet.  Never use it.  If you must delete a whole directory structure, change directory to the one above it and explicitly remove the directory.  This is also the first and best reason to do as much of your work as possible as a normal user and not root.  Since root is all powerful, it is quite capable of completely destroying your system.  Imagine that you are in the top level directory ( / ) instead of /home/myname/junkdir when you initiated that recursive delete.  It is far too easy to make this kind of mistake.  Beware.
With that last bit of warning, I leave you until the next instalment. Many thanks to all of you who have followed me in this series. As usual, if you wish to comment, please do so here on Google Plus or over here on Facebook and add me to your circles or friend list if you haven't already done so. Also, make sure you sign up for the mailing list over here so that you're always on top of what you want to be on top of.  Until next time . . .
A votre santé! Bon appétit!

No comments:

Post a Comment