I have a program running on a remote computer which shouldn't be stopped. I need to track when this program is stopped and immediately execute a command. PID is known. How can I do that?
-
Do you have control on how the program start? Do you want the execution on already run program or on the next execution? – Romeo Ninov Feb 12 '20 at 07:58
-
@RomeoNinov This program is already running, I need to wait when it stops. – Michael Feb 12 '20 at 07:59
-
1Something like can do the work. But its ugly and power consuming: while true do if [ "$(ps -efl|grep $PIDN|wc -l)" -lt 1 ] then
; break fi sleep 5 done – Romeo Ninov Feb 12 '20 at 08:05 -
@RomeoNinov I think that wouldn't work on `a remote computer` as the OP said – ChatterOne Feb 12 '20 at 08:10
-
@ChatterOne it will, I'm using ssh and screen – Michael Feb 12 '20 at 08:11
-
@RomeoNinov thanks, I launched it, let's wait till the program stops :) – Michael Feb 12 '20 at 08:12
-
@RomeoNinov I meant that you'd need to launch SSH first, of course, which is not included in the command you suggested – ChatterOne Feb 12 '20 at 08:12
-
@ChatterOne, yes, and create the script. And run it (it can be in background) – Romeo Ninov Feb 12 '20 at 08:13
4 Answers
You cannot wait
for non-child processes.
Probably the most efficient way in a shell would be to poll using the exit code of kill -0 <pid>
to check if the process still exists:
while kill -0 $PID 2>/dev/null; do sleep 1; done
This is both simpler and more efficient than any approaches involving ps
and grep
. However, it only works if your user has permission to send signals to that process.

- 174,939
- 50
- 355
- 478
-
1I agree that `kill -0` is a good way to check for a running process, with one caveat -- it only succeeds if the current user has permission to send signals to that process. – traal Feb 12 '20 at 09:58
Code like this can do the work (to be run on remote computer)
while true
do
if [ "$(ps -efl|grep $PIDN|grep -v grep|wc -l)" -lt 1 ]
then <exec code>; break
fi
sleep 5
done
It expect the variable PIDN to contain the PID.
P.S. I know the code is ugly and power hungry
EDIT: it is possible to use -p
in ps
to avoid one grep
while true
do
if [ "$(ps -p $PIDN|wc -l)" -lt 2 ]
then <exec code>; break
fi
sleep 5
done

- 6,538
- 1
- 22
- 31
-
3Now sure how portable it would be, but at least on the BSD version of `ps` there's an option `-p` to display only a specific process – ChatterOne Feb 12 '20 at 08:22
-
1@ChatterOne, on linux `ps` you have also `-p` (or `p`) option to select one pid. But on some UNIXes you may not found it. But will add it, thank you for the idea – Romeo Ninov Feb 12 '20 at 08:27
Here's a fairly simple way to wait for a process to terminate using the ps -p PID
strategy:
if ps -p "$PID" >/dev/null 2>&1; then
echo "Process $PID is running ..."
while ps -p "$PID" >/dev/null 2>&1; do
sleep 5
done
echo "Process $PID is not running anymore."
fi
Checking for a process by PID
In general, to check for process ownership or permission to kill (send signals to) a proccess, you can use a combination of ps -p PID
and kill -0
:
if ps -p "$PID" >/dev/null 2>&1; then
echo "Process $PID exists!"
if kill -0 "$PID" >/dev/null 2>&1; then
echo "You can send signals to process $PID, e.g. with 'kill $PID'"
else
echo "You do not have permission to send signals to process $PID"
fi
else
echo "Process $PID does not exist."
fi

- 461
- 3
- 7
You can use exitsnoop
to achieve this.
The bcc
toolkit implements many excellent monitoring capabilities based on eBPF
. Among them, exitsnoop
traces process termination, showing the command name and reason for termination,
either an exit or a fatal signal.
It catches processes of all users, processes in containers, as well as processes that
become zombie.
This works by tracing the kernel sched_process_exit() function using dynamic tracing, and
will need updating to match any changes to this function.
Since this uses BPF, only the root user can use this tool.
exitsnoop
examples:
Trace all process termination
# exitsnoop
Trace all process termination, and include timestamps:
# exitsnoop -t
Exclude successful exits, only include non-zero exit codes and fatal signals:
# exitsnoop -x
Trace PID 181 only:
# exitsnoop -p 181
Label each output line with 'EXIT':
# exitsnoop --label EXIT
You can get more information about this tool from the link below:
- Github repo: tools/exitsnoop: Trace process termination (exit and fatal signals). Examples.
- Linux Extended BPF (eBPF) Tracing Tools
- ubuntu manpages: exitsnoop-bpfcc
Another option
use this project: https://github.com/stormc/waitforpid

- 1,888
- 18
- 25