Signals with trap

chakib

New Member
Joined
Oct 21, 2018
Messages
1
Reaction score
0
Credits
0
Hello,

I am preparing a small class for students on signals with trap. I understood the use of this principle with the example on signal 2 SIGINT:

trap "echo hello" 2: which displays "hello" each time you press the shortcut ctrl + c.

On the other hand, I have difficulty assimilating the use of the following cases:

1. The effect of signal 3 SIGQUIT.

2. The effect of siganl 9 SIGKILL.

3. The effect of the signal 19 SIGSTOP.

Can you guide me with simple examples please?

Best regards.
 


1. SIGQUIT tells a process to quit and perform a core dump. So perhaps if a process is misbehaving in some way, you might decide that you want to end the process and trigger a core-dump. Then you can perform a back-trace on the core-file using a debugger like gdb and try to determine the state of the program and ascertain the cause of the programs problems.

2. The SIGKILL signal causes a process to immediately end. This signal typically cannot be caught or ignored - Any process receiving the SIGKILL signal will instantly end and will be unable to perform any kind of clean up, so using SIGKILL can cause data loss.

SIGKILL should only be used as a last resort to shut down a process. SIGTERM or SIGINT should be used instead as these allow the process to clean up any resources and save its state before ending.

There are certain types of processes that cannot be killed by SIGKILL too:
- Sleeping processes are sometimes unkillable by SIGKILL.
- Processes that are in a blocked state are unkillable until they wake again.
- Init is another process that is typically unkillable because it does not get signals that it doesn't want to handle and can ignore SIGKILL.
- Zombie processes are unkillable, because they are already dead and waiting for their parent process to clean up after them.

But generally speaking, SIGKILL will instantly end pretty much any process, with no clean-up and no saving of state.

3. SIGSTOP (which can be sent via the terminal using the key ctrl+z ) will simply stop a process from running. It doesn't end the process. The process is still in memory - it is just stopped. So it can be resumed later.

So for example if you typed the following command:
Code:
man kill
This will bring up the man-page for the kill command.
Then hit ctrl+z - this will stop the "man kill" process and bring us back to the terminal.
Now type another command. e.g.
Code:
man man
This brings up the manpage for man.
Now hit ctrl+z again - and the "man man" command will stop and you will be returned to the console.

So now we have two stopped jobs.
Stopped processes can be viewed using the "jobs" command.
Code:
jobs -ls
In the above command, the -l option will cause jobs to list the process ID's for any jobs that are running.
The -s option causes jobs to only list stopped jobs. Without the -s option, jobs would list all of the current terminals jobs that are either stopped or running. But at the moment, we are only interested in the stopped jobs.

This will give us output that looks something like this:
Code:
$ jobs -ls
[1]-  3868 Stopped                 man kill
[2]+  8068 Stopped                man man
If you have more than one stopped process - the jobs command will list ALL stopped jobs.

To resume a job, you can use the fg command to resume a stopped job in the terminal
Code:
fg
That will re-start the most recently stopped process (which is marked with a + in the output from the jobs command) - in this case "man man"
Or, if you wanted you could use a numeric index to restart a particular job.
e.g.
Code:
fg 1
Would resume the "man kill" command.

So simply just use the "fg" command a couple of times to restart the stopped "man" processes and then quit them properly by pressing q.

Now if you use the "jobs -l" command again and you can see that there are no jobs stopped or running.

There is also the "bg" command, which can be used to resume a job in the background.
It works in exactly the same way as "fg", but the program will run in the background - allowing you to continue using the terminal whilst the process is still running. Running processes in the background really only works if they do not require any user input. So scripts that take a long time to run, that require no user input are good candidates to be ran in the background.
Whereas scripts that require the user to answer questions or which require any other kind of input should be started as foreground processes.

So for example, lets say that you started a script in the foreground - it takes a really long time to run but you also want to run some other commands, while you wait for it to finish.
However, because it is running in the foreground you are forced to wait for your long script to end, before you can enter the other commands.

We have a lot of work to do and we don't want to wait for the long script to finish. Perhaps we are logged into a remote machine and we can't easily bring up another terminal. What can we do so we can work more efficiently?

What we can do is temporarily stop the script and then send it to the background and free up our terminal so we can get on with other work while the script is doing it's thing.

So in this case, we can stop the long script by pressing "ctrl+z".

Then you can use the "bg" command to restart the process in the background
Code:
bg

Now you can use the terminal to run other commands whilst your long script carries on running in the background.

And to start programs in the background straight away, you simply put a & at the end of the command-line.
e.g.
Code:
./mylongscript.sh &
That will start mylongscript.sh running in the background.
This will display a job-number and a process ID.
e.g.
Code:
[1] 8168

You can use "jobs -l" to see all jobs:
Code:
$ jobs -l
[1]+  8168 Running                 mylongscript.sh &

And you will be notified when the script ends.


So by using the SIGSTOP signal (ctrl+z) and the "jobs", "fg" and "bg" commands - you can stop processes and resume them in the foreground (blocking the terminal until they end), or in the background (without blocking the terminal).

"jobs", "fg" and "bg" are all built-ins in bash, so you can get help with them via the help command.
e.g.
Code:
help jobs
help fg
help bg

And again, when sending processes to the background - it really only works best with scripts or programs that do not require user input. As soon as a program requires input, it will just hang there in the background waiting for input and will be unable to receive anything.

But if you do accidentally put a process that requires user-input into the background - you can use the "jobs -l" command to get the process ID for the job.
e.g. 9000

Then you can use the kill command to send a SIGSTOP signal to the process:
Code:
kill -17 9000
or
Code:
kill -SIGSTOP 9000
This should cause the process to stop.

Then you can use the "jobs -l" command to get a list of jobs. And finally you can use "fg" to resume the stopped job in the foreground and you will be able to provide input for the program.

[edit]
I've just noticed that you mentioned signal 19 in your original post, which is NOT SIGSTOP, but SIGCONT.
SIGCONT will cause a stopped thread to resume/continue.

So after sending a SIGSTOP (17) to a process (by using ctrl+z, or using the kill command) you can resume it again by sending a SIGCONT signal from kill (or use fg or bg).
e.g.
Code:
kill -19 9000
or
Code:
kill -SIGCONT 9000
[/edit]
 
Last edited:


Top