Episode: 4627
Title: UNIX Curio #5 - Faster, Pussycat! Kill! Kill!
Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr4627/hpr4627.mp3
Transcribed: 2026-07-31 16:15:24 (official HPR transcript)

---

This is Hacker Public Radio Episode 4627, for 2026-04-28
Today's show is entitled, "UNIX Curio #5 - Faster, Pussycat! Kill! Kill!"
The host is Vance and the duration is 00:14:35
The flag is Clean, and the license is CC-BY-SA
The summary is "Sending signals to processes, or just checking if they exist"
Hi there, I'm Vance and welcome to Unix Curio number 5.
This series is dedicated to exploring little known and occasionally useful,
trinkets lurking in the dusty corners of Unix-like operating systems.
Let me start by admitting that I've never actually seen the film referenced in the episode title,
but I couldn't resist using it anyway.
If you've used the Unix command line to any extent, chances are good that you are familiar with the
kill command. A common use is to terminate a misbehaving program.
But there is more behind how kill works, including a curio you might not know about.
The kill utility works by sending a signal to the targeted process.
This signal is selected from a predefined list and triggers the process to interrupt its normal
flow and handle the signal before potentially returning back to its work.
This signal handler can do whatever activities are written in its code, but typically it will take
actions connected to the purpose of the specific signal received.
One option is for the process to not have a signal handler at all.
In that case, there is a default action that the operating system will take
on behalf of the process, depending on what the signal is.
The possible default actions are to terminate the process,
take some implementation defined action, usually rating a core file to disk,
and then terminate the process, stop that is to say pause execution of the process,
continue execution of a stopped process, or just ignore the signal.
By default, kill sends the term signal to the process and indicate that it should terminate.
Each signal has a name and a number assigned to it.
Sig term is the name of the terminate signal.
You can use the hyphen S option with the name to choose which signal to send.
The kill command is specified to take these names without the Sig prefix,
though some implementations will accept them either way.
Also, kill is supposed to be case insensitive when it comes to these names,
but the convention is to write them in all upper case.
The assigned numbers for signals can vary depending on the operating system,
and on Linux, depending on what process our architecture you're on.
However, there is a short list of signals that have a stable number assigned to them.
A link to this is provided in the shown notes.
Despite this, I recommend using the signal name, not the number in your scripts,
both to make them clear and to ensure maximum portability to different systems.
Well-behaved programs will have a signal handler that responds to the term signal
by stopping what they are doing, cleaning up any open resources like temporary files and promptly exiting.
However, not every program behaves well, so sometimes it becomes necessary to send them the kill signal.
This one is special and cannot be handled or ignored by the program.
The operating system will immediately terminate the program,
possibly leaving a mess behind.
Two other signals that can come in handy sometimes are stop and count,
spelled CONT.
As you might expect, stop forces a process to pause in the middle of whatever it was doing.
Its counterpart, CONT, that's short for, continue, causes it to resume execution.
This can be useful if a program consumes CPU time when not actually doing anything worthwhile.
Sending it the stop signal will end that, and when you're ready to use it again, CONT will
cause it to pick up right where it left off.
Like the kill signal, stop cannot be handled or ignored by the program.
I have used this to pause the game free-sive when I wanted to break away to do something else,
but didn't one have to deal with exiting my current game and having to reload it later.
Take note, though, that the program might get confused if it expects the system clock not to suddenly
jump forward as that is exactly how the situation will appear to it.
Network connections or other resources the process is using, that change while it is stopped,
our other potential trouble spots.
Also be aware that a stopped graphical program will not update its window.
So I find it best to minimize the window before stopping it and then continuing the process
before trying to raise the window again.
Programs are not necessarily required to interpret signals in the way they are described.
For example, the HUP signal was originally intended to be sent when a modem or serial connection
hang up occurred. Today, some demons use it for other purposes and take a specific action in response.
For example, the Apache web server will restart and network manager will reload its configuration.
These uses of signals are usually described in the demons manual page,
often in a separate section dedicated to signals.
While all this background might be interesting or maybe not,
it's pretty commonly known. So it isn't really a curio.
Our Unix curio for today is the zero signal.
This is not actually a signal at all. Instead, it tells the kill utility
to just check for the existence of a process.
If the process exists, kill will exit with a status of zero.
If it doesn't exist, the exit status will be greater than zero.
This provides a handy way to check whether a particular process is still around.
A shell command can use this exit status with its control structures like if
to take a particular action depending on whether a process exists.
Somewhat oddly, the numerals zero is both the number and the name of this pseudo signal.
Why would you want to do this? I've used it for a script to analyze log files that runs
daily on a web server. Depending on how much traffic the site is getting,
the log files can grow to the point where it takes longer than a day for the script to get through them.
If a second instance of the script is started, while one is still running, it will slow down both.
And if more keep being added, eventually the machine will run out of memory.
My solution was to create a PID file containing the process ID number of the running script.
You might see examples of these if you look in the slash run or slash var slash run
directories on your system. The script creates a file named something like
my script dot PID in this directory containing its own process ID, which can be accessed in the
shell with the variable dollar sign dollar sign.
When my script starts, it checks to see whether this file exists.
If so, it loads the process ID from the file and runs kill, hyphen s, space 0 with it,
to see if the previous process still exists. If the process is no longer around,
that's a sign that it exited abnormally before it had the chance to delete the PID file.
So the script removes the abandoned PID file, replaces it with a new one containing the current
process ID, and continues with its work. If the previous process is still around, my script just
exists with a message to that effect. This way, I can be sure that only one instance of the script will
ever be running at one time. Be aware that the kill utility might also return a non-zero exit
status, if the user running it does not have privileges to send a signal to the process with the
specified ID. This is not a concern if you are running a script as the root user, but could be if you
are not. This can occur even if you aren't actually sending a signal just using the 0 pseudo-signal
to check if a process exists. There is a weakness in this method. Unix lake systems generally
have a limit to the quantity of process ID numbers that can be issued, so they get reused over time.
However, there will never be two processes with the same ID number running at the same time.
Typically, the first process that is run on startup will be given the ID number one,
and each subsequent process will get the next higher number.
Once the maximum is reached, the system starts again at the beginning with the lowest number not in use.
It is possible for the script to crash and leave behind the PID file,
and then the same process ID could be recycled and actively used for another program,
causing a new instance of the script to give up. The chances of this are small enough that for my
purposes it's not worth worrying about, but you should be aware that it could happen.
I should also note that it's not strictly necessary to use kill for the purpose I described.
The PS utility can also be given a process ID with the hyphen P option.
If the process exists, the exit status will be 0, otherwise it will be greater than 0.
In this case, you could also use the output of the PS command to check that the name of the script matches what you expect,
helping avoid the problem of a recycled process ID.
In addition, PS doesn't concern itself with permissions for sending signals,
so it will report on the existence of a process no matter what user you are running it as.
From an efficiency standpoint, kill generally requires fewer resources to run.
In fact, it is built into some shells, but functionally, PS can also do the job.
You can find example scripts in the show notes for this episode,
showing how to use both the kill and PS commands to tell if a process exists and take action depending on the result.
So keep in mind that kill is capable of doing more than just killing off programs.
Maybe you can put it to one of these uses for your needs.
Thanks for listening and keep an eye out for our next Unix Curio,
which will be about the at and bad utilities here on Hacker Public Radio.
If you have a question or a suggestion for a future topic,
please comment on this episode on the HPR website.
You have been listening to the Hacker Public Radio podcast, at hackerpublicradio.org.
Today's show was contributed by a HPR listener like yourself.
If you ever thought of recording a podcast, then visit the HPR site to find out how easy it really is.
Hosting for HPR has been kindly provided by anhonesthost.com, the Internet Archive, rsync.net, and the HPR Community Content Delivery Network.
Unless otherwise stated, today's show is released under a Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.
