以下场景:
-
process_1.bin
启动doSomeThing.sh
-
doSomeThing.sh
应该先杀死process_1.bin
,但继续运行自己并做一些其他事情
我尝试过fork、exec、screen、p_threads、daemon和一些,但都没有成功。每次doSomeThing.sh
启动并杀死process_1.bin
时,它都会杀死自己,因为父进程被杀死了。
CCD_ 7告诉我:;终止信号后离开程序">
不幸的是,这也不起作用:
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;
}
我如何指挥doSomeThing.sh
杀死process_1.bin
,但仍然活着?
除了按照Jonathan Leffler的建议忽略SIGTERM之外,您还可以使子进程成为守护进程,这样它的生命将独立于父进程的生命。Linux有一个命令,可以将进程作为守护进程守护进程或库函数启动,以便程序愿意与其父进程及其控制终端守护进程分离。
您的子进程不应该正在消亡。这里有两个shell脚本模拟您所描述的内容。
process1.bin
#!/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
做某事.sh
#!/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!"
有一次,当我运行它时,我得到了输出:
$ ./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!
$
请注意,我的$
提示出现在"收到死亡威胁"之后。以下输出来自doSomething
;我在"再见,残酷的世界!"以获得最终的CCD_ 12提示。
在运行macOS Catalina 10.15.7的MacBook Pro上使用Bash进行测试。
在一条评论中,oemer_11907说:
shell脚本杀死所有进程来播放更新(包括C更新进程(。一旦C更新进程被shell更新进程终止,它就会向其所有子进程发送一个SIGTERM。因此,shell脚本也被杀死。如果它只是计算而不杀死它的父对象,那么它就会一直运行到最后。
如果父进程向其所有子进程发送SIGTERM,则子脚本doSomething.sh
必须使用以下任一项忽略SIGTERM信号:
trap "" 15
trap "" TERM
在它向其父级发送信号之前。或者父进程可以安排不向该子进程发送信号。或者它可以安排孩子在执行SIGTERM之前忽略它:
signal(SIGTERM, SIG_IGN);
…exec child…
或者…