Reputation: 31
The following scenario:
process_1.bin
starts doSomeThing.sh
doSomeThing.sh
should kill process_1.bin
first but keep running itself and do some other things
I have tried fork, exec, screen, p_threads, daemon, and some without success.
Every time the doSomeThing.sh
starts and kills the process_1.bin
, it kills itself because the parent process is killed.
doSomeThing.sh
tells me: "leaving program after kill signal!"
Unfortunately, this does not work either:
pid_t pid;
pid = fork();
if (pid < 0)
exit(EXIT_FAILURE);
if (pid > 0) // Success: Let the parent terminate
exit(EXIT_SUCCESS);
if (setsid() < 0)
exit(EXIT_FAILURE);
pid = fork();
if (pid < 0)
exit(EXIT_FAILURE);
if (pid > 0)
exit(EXIT_SUCCESS);
// umask(0);
// chdir("/");
switch(pid)
{
case -1: // Fork() has failed
perror ("fork");
break;
case 0: // This is processed by the child
// deamon(0,0);
system("/root/doSomeThing.sh");
// system("screen -dmS doSomeThing /root/doSomething.sh")
// char *name[] = {
// "/bin/bash",
// "-c",
// "/root/doSomeThing.sh",
// NULL
// };
// if(execvp(name[0], name) < 0)
// perror("execvp");
exit(0);
break;
default: // This is processed by the parrent
break;
}
How can I direct the doSomeThing.sh
to kill the process_1.bin
but still stay alive itself?
Upvotes: 3
Views: 2567
Reputation: 753475
Your child process should not be dying. Here's a pair of shell scripts simulating what you describe.
#!/bin/sh
echo "$0: at work"
trap 'echo "$0: Death threat received"; exit 1' 1 2 3 13 15
sh doSomething.sh &
echo "$0: so far, so good"
wait
echo "$0: it's sad when all your children die"
ps -f
echo "$0: exiting normally"
exit 0
#!/bin/sh
#
# Commit parenticide and continue, preferably without dying.
#PPID=$(ps -fp$$ | colnum -c 3)
echo "Before"
ps -f
(
set -x
kill $PPID
)
sleep 1
echo ""
echo "After"
ps -f
sleep 5
echo "$0: Goodbye, Cruel World!"
One time when I ran it, I got the output:
$ ./process1.bin
./process1.bin: at work
./process1.bin: so far, so good
Before
UID PID PPID C STIME TTY TIME CMD
501 649 641 0 9:58AM ttys000 0:00.14 -bash
501 29760 649 0 8:47AM ttys000 0:00.01 sh
501 29793 29760 0 8:47AM ttys000 0:00.01 /bin/sh ./process1.bin
501 29794 29793 0 8:47AM ttys000 0:00.01 sh doSomething.sh
501 661 657 0 9:58AM ttys001 0:00.05 -bash
501 693 688 0 9:58AM ttys002 0:00.05 -bash
501 738 731 0 9:58AM ttys007 0:00.31 -bash
501 769 766 0 9:58AM ttys008 0:00.05 -bash
501 848 847 0 9:58AM ttys009 0:00.05 -bash
501 884 881 0 9:58AM ttys010 0:00.12 -bash
501 946 920 0 9:58AM ttys011 0:00.15 -bash
+ kill 29793
./process1.bin: Death threat received
$
After
UID PID PPID C STIME TTY TIME CMD
501 649 641 0 9:58AM ttys000 0:00.14 -bash
501 29760 649 0 8:47AM ttys000 0:00.01 sh
501 29794 1 0 8:47AM ttys000 0:00.01 sh doSomething.sh
501 661 657 0 9:58AM ttys001 0:00.05 -bash
501 693 688 0 9:58AM ttys002 0:00.05 -bash
501 738 731 0 9:58AM ttys007 0:00.31 -bash
501 769 766 0 9:58AM ttys008 0:00.05 -bash
501 848 847 0 9:58AM ttys009 0:00.05 -bash
501 884 881 0 9:58AM ttys010 0:00.12 -bash
501 946 920 0 9:58AM ttys011 0:00.15 -bash
doSomething.sh: Goodbye, Cruel World!
$
Note that my $
prompt appears after 'Death threat received'. The following output is from doSomething
; I hit return after 'Goodbye, Cruel World!' to get the final $
prompt.
Testing with Bash on a MacBook Pro running macOS Catalina 10.15.7.
In a comment, oemer_1907 says:
The shell script kills all processes to play the update (including the C update process). Once the C update process is killed by the shell update process, it sends a SIGTERM to all its children. Hence, the shell script is also killed. If instead it just calculates without killing its parent, then it just keeps running until the end.
Well, if the parent process sends SIGTERM to all its children, your child script, doSomething.sh
, must ignore the SIGTERM signal using either of these:
trap "" 15
trap "" TERM
before it sends a signal to its parent. Or the parent process could arrange not to send the signal to this child. Or it could arrange for the child to ignore SIGTERM before it is executed:
signal(SIGTERM, SIG_IGN);
…exec child…
Or …
Upvotes: 1
Reputation: 148870
Apart from ignoring SIGTERM as suggested by Jonathan Leffler, you could make the child process a daemon so that its life will become independant of the life of its parent. Linux has a command to start a process as a daemon daemonize or a library function for a program willing to detach from its parent and its controlling terminal daemon.
Upvotes: 2