How to get the pid of the last executed command that was sent to the background in a bash shell

Recently we came to the need of writing a bash script that needed periodically to check if a specific process, that was started by the script, had ended and restart it (something like watchdog but with not so many features).

To achieve this, we used the one of the shell special parameters, the $!. Like all other special parameters $! may only be referenced and the user cannot make an assignment to it.

($!) Expands to the process ID of the job most recently placed into the background, whether executed as an asynchronous command or using the bg builtin command.


Example of Usage

In this example we wanted to get the PID of the application called server to be used later on in the script.

server &
echo $!; #This will print the process ID of the 'server' application

How to “pause” (suspend) an active process

Recently, we were executing the following time-wasting application and we wanted to pause it somehow and release the CPU that was being used temporarily for other tasks.
Unfortunately, the process was not executing on an active console, so we could not press CTRL+Z and suspend it.
Conveniently, the kill command provides us with the suspend functionality as long as we know the PID of the process to be suspended.

Using ps x, we found the PID of the application even though it was not attached to an active console.

Then to suspend the application, we used

kill -TSTP "$PID";

which instructed the process to stop by sending it the SIGTSTP signal.

Fortunately, our application did not block the signal and it was suspended.

Note: In case an application ignores the SIGTSTP signal, you can still force it to suspend by sending it the SIGSTOP signal as follows

kill -STOP "$PID";

After we were done, we resumed the execution of the process by sending the SIGCONT signal to it

kill -CONT "$PID";


Bash: Close a range of open sockets by killing the PIDs that are holding them open

Sometimes you want to use a specific port number but some other process(es) is using it. To get the control of the port you need to terminate all other processes and free it.
To find out which process(es) you need to kill, use lsof -i :port. It will return a list of each command and PID that is using the specific port. After that kill those PID using kill -s 9.

The following script will accept a range of ports to free, and for each it will try to kill all processes that are holding them blocked.

for i in `seq $low $high`; do
  lsof -i :$i | tail -n +2 | awk '{system("kill -s 9 " $2)}';

Using tail -n +2 we skip the first line of the input which would be the header information.
The system method will invoke a new sh shell and execute the command in it.
Using kill -s 9 we signal the processes that they have to terminate immediately.