Week 4: Communicating processes
nohup
commandNote
Can’t we do that with pipes?
SIGKILL
→ immediately terminates a process.SIGTERM
→ gracefully terminates a process.SIGHUP
→ hangup signal, often sent when a terminal closes.We’ll be using a little python program to illustrate how signals work. For now the program will just print a digit every second:
Create a file named amsa.py
and paste the code. Naming the file this way will come handy later when searching for the process PID.
kill
, which requires:
kill -KILL <PID>
, we are going to terminate the targeted process with SIGKILL
signal.SIGKILL
in actionRun the python program and open a second terminal. We’ll be sending signals from the second one.
Since we know that sending SIGKILL
to a process will terminate it, we expect the program to stop printing digits and finish.
Find out the PID of the process and run kill -KILL <PID>
, watch what happens with the python program.
Tip
Use ps aux | grep amsa
to easily find the PID
amsa@amsa:~$ ps aux | grep amsa
fnao 42419 0.1 0.0 18952 9964 pts/1 S+ 11:29 0:00 python3 amsa.py
fnao 42525 0.0 0.0 7300 2288 pts/4 S+ 11:29 0:00 grep --color=auto amsa
The PID of the process here is 42419.
Signal | Default Action | Comment |
---|---|---|
SIGHUP |
Terminate | Hangup: sent when terminal closes |
SIGINT |
Terminate | Interrupt from keyboard (Ctrl-C ) |
SIGQUIT |
Dump | Quit from keyboard (Ctrl-\ ) |
SIGKILL |
Terminate | Forced termination, cannot be ignored |
SIGTERM |
Terminate | Graceful termination request |
SIGSTOP |
Stop | Stop process execution (cannot ignore) |
SIGTSTP |
Stop | Stop from terminal (Ctrl-Z ) |
SIGCONT |
Continue | Resume a stopped process |
SIGCHLD |
Ignore | Sent when a child process exits or stops |
SIGSEGV |
Dump | Invalid memory access (segmentation fault) |
SIGUSR1 |
Terminate | User-defined signal (custom use) |
kill
?kill
command is confusing:
SIGKILL
.kill
could only forcibly kill a process.SIGSTOP
, SIGCONT
, SIGCHLD
…).signal()
syscallHave you noticed many signals share the same default actions? (SIGTERM
and SIGKILL
for example).
signal()
system call lets processes define how are they going to behave when they receive a signal. Here is what the man page says:
The action a process performs upon receiving a signal is called the handler.
It can be the default action, ignoring the signal, or a programmer-defined function.
We can run any code we want as a response to an action.
Note
Although we could change the action in response to any signal, SIGUSR1
and SIGUSR2
are already intended to mess with.
SIGUSR1
on pythonModify the python program so it now registers a custom handler for SIGUSR1
as shown below:
Run the python program and open a separate terminal.
Get the PID of the program with ps aux | grep amsa
.
Which command are we going to use now for sending SIGUSR1
to our python program?
Note
Remember the syscall is always kill()
no matter which signal are we sending. In this case: kill -USR1 <PID>
fnao@fnao-phd-energy:~$ ps aux | grep amsa.py
fnao 42471 0.3 0.0 18952 9972 pts/2 S+ 10:50 0:00 python3 amsa.py
fnao 42491 0.0 0.0 7304 2292 pts/3 S+ 10:50 0:00 grep --color=auto amsa.py
fnao@fnao-phd-energy:~$ kill -USR1 42471
SIGHUP
Its default action is to terminate the process, same as SIGKILL
, SIGTERM
, SIGINT
and many others.
It’s sent when we close the terminal where we launched a program, thus the name.
Send the SIGHUP
signal
Try sending the SIGHUP
signal to the python program with kill -HUP <PID>
. It should terminate as when sending SIGKILL
and print ‘Hangup’ a the end.
In order to experiment with the SIGHUP
signal, we’ll want to redirect the output of the python program to a file so we can see what happens when the terminal is closed.
To do so, run your program like this: python amsa.py > out.txt
.
Now, after running the program, from another terminal run cat out.txt
and you’ll see the output is being written there.
Apart from the default action and a custom handler, we can also choose to ignore a signal, which is going to override the default action.
Modify the script and add a call to signal()
that ignores SIGHUP
as shown below:
import signal
import time
import sys
def handle_sigusr1(signum, frame):
print("Hello world")
def main():
signal.signal(signal.SIGUSR1, handle_sigusr1)
signal.signal(signal.SIGHUP, signal.SIG_IGN)
counter = 0
while True:
print(f"Tick {counter}")
sys.stdout.flush()
counter += 1
time.sleep(1)
if __name__ == "__main__":
main()
SIG_IGN
on SIGHUP
python amsa.py > out.txt
.SIGHUP
signal kill -HUP <PID>
.out.txt
file.SIGKILL
signal kill -KILL <PID>
to terminate the program.nohup
But what if I want to achieve this with a program I haven’t built? It will not ignore SIGHUP
, how can I close the terminal where I launched while not killing the program?
This is when the nohup
command comes handy, it as simple as it sounds. It lets the user run any program while making it ignore the SIGHUP
signal.
It also automatically redirect the output of the program to nohup.out
.
nohup
Modify the python program so it no longer ignores SIGHUP
(remove the last line we added)
Run the program like this: nohup python amsa.py
Try sending the SIGHUP
signal or closing the terminal as we did before, we expect the result to be the same.
Great! Now we can run any command we want, close the terminal and have it still running!
LINUX Signals: https://faculty.cs.niu.edu/~hutchins/csci480/signals.htm
signal()
man page: https://man7.org/linux/man-pages/man2/signal.2.html
kill()
man page: https://man7.org/linux/man-pages/man1/kill.1.html
nohup
man page: https://www.man7.org/linux/man-pages/man1/nohup.1.html
Source code for nohup
command: https://github.com/coreutils/coreutils/blob/master/src/nohup.c
Linux Signals. I Spent 2 Years to Understand This Part: https://www.youtube.com/watch?v=d0gS5TXarXc
The history of the terminal and signals: https://www.linusakesson.net/programming/tty/index.php
Why is the UNIX system call kill named ‘kill’?: https://unix.stackexchange.com/questions/185027/why-is-the-unix-system-call-kill-named-kill
History of SIGHUP
: https://en.wikipedia.org/wiki/SIGHUP
If you really want to understand a little bit more what happens under the hood, you can do the following exercices. Be aware that you should read the “Really Recommended References” first, and then try to do this exercises.
Modify handler of SIGTSTP so Ctrl-Z does nothing.
Modify handler of SIGKILL so “Avada Kedavra” is printed when received.
Implement nohup in python.
Ready to have some fun? Check out the third part of the second AMSA activity here!
AMSA 2025-2026 - 🏠 Home