你/etc/rc5/myscript
没有因为$SERVICESCRIPT
. 它是阻塞的,因为它正在等待logger
终止,直到写入其 STDIN 的所有内容都终止(在这种情况下,这是您的守护程序),它才会终止。
您可以通过这个简化的示例看到这种行为。考虑这个简单的 C 程序,它会孤立自己,然后永远什么都不做:
#include <stdlib.h>
int main( int argc, char *argv[] ){
if( fork() ){
exit( 0 );
}
while( 1 ){
sleep( 1 );
}
return EXIT_SUCCESS;
}
这个简单的“记录器”从 STDIN 读取直到 EOF:
#include <stdio.h>
int main( int argc, char *argv[] ){
char c;
while( 1 ){
c = getc( stdin );
if( c == EOF ){
break;
}
}
return 0;
}
如果我一起运行这些,我不会得到我的命令提示符。
$ ./forktest | ./logger
<hangs>
这是因为我的 shell 正在等待整个管道完成。 forktest
“完成”(它会杀死自己)但logger
没有完成,这就是我们正在等待的。的孤儿进程forktest
保持打开logger
. 通过在上述运行时logger
签入另一个终端,您可以看到来自孤儿的 STDOUT (fd 1) 的管道(注意其父进程是 1)进入 STDIN (fd 0) :/proc/$pid/fd
$ ps -ef | grep forktest
cneylan 25451 1 0 16:27 pts/7 00:00:00 ./forktest
$ ps -ef | grep logger
cneylan 25450 24379 0 16:27 pts/7 00:00:00 ./logger
$ ls -l /proc/25451/fd
total 0
lrwx------ 1 cneylan cneylan 64 Jul 2 16:28 0 -> /dev/pts/7
l-wx------ 1 cneylan cneylan 64 Jul 2 16:28 1 -> pipe:[944400]
lrwx------ 1 cneylan cneylan 64 Jul 2 16:28 2 -> /dev/pts/7
lrwx------ 1 cneylan cneylan 64 Jul 2 16:28 3 -> /dev/pts/7
$ ls -l /proc/25450/fd
total 0
lr-x------ 1 cneylan cneylan 64 Jul 2 16:28 0 -> pipe:[944400]
lrwx------ 1 cneylan cneylan 64 Jul 2 16:28 1 -> /dev/pts/7
lrwx------ 1 cneylan cneylan 64 Jul 2 16:28 2 -> /dev/pts/7
lrwx------ 1 cneylan cneylan 64 Jul 2 16:28 3 -> /dev/pts/7
作为旁注,当发生这种情况时执行 ^C 只会向logger
进程发出信号,因为您的守护程序 [应该] 调用 ,这是守护进程自身setsid(2)
的必要步骤之一。所以要么 ^C 正在杀死你的守护进程,你需要调用你的代码,或者你的代码已经调用,并且你有一堆流氓守护进程在后台运行:)setsid(2)
setsid(2)