Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
执行守护进程时的Linux/Bash文件描述符_Linux_Bash_Daemon_File Descriptor_Io Redirection - Fatal编程技术网

执行守护进程时的Linux/Bash文件描述符

执行守护进程时的Linux/Bash文件描述符,linux,bash,daemon,file-descriptor,io-redirection,Linux,Bash,Daemon,File Descriptor,Io Redirection,我正在为我正在处理的一个C项目编写一个服务脚本,它在启动时执行一些实用程序。我想使用日志记录实用程序捕获所有输出。我在/etc/rc5/myscript中有如下内容 #!/bin/bash #save fd 1 in fd 3 for use later exec 3<&1 $SERVICESCRIPT | logger #/bin/bash #将fd 1保存在fd 3中以供以后使用 exec 3您的/etc/rc5/myscript没有因为$SERVICESCRIPT中

我正在为我正在处理的一个C项目编写一个服务脚本,它在启动时执行一些实用程序。我想使用日志记录实用程序捕获所有输出。我在/etc/rc5/myscript中有如下内容

#!/bin/bash    
#save fd 1 in fd 3 for use later
exec 3<&1
$SERVICESCRIPT | logger
#/bin/bash
#将fd 1保存在fd 3中以供以后使用

exec 3您的
/etc/rc5/myscript
没有因为
$SERVICESCRIPT
中的任何内容而被阻塞。它之所以阻塞,是因为它正在等待
logger
终止,直到写入其STDIN的所有内容都终止(在本例中,这是您的守护进程)后才会终止

您可以通过这个简化的示例看到这种行为。考虑这个简单的C程序,孤儿本身,然后什么也不做:< /P>
#include <stdlib.h>

int main( int argc, char *argv[] ){
        if( fork() ){
                exit( 0 );
        }
        while( 1 ){
                sleep( 1 );
        }
        return EXIT_SUCCESS;
}

作为旁注,在发生这种情况时执行^C只会向
记录器
进程发出信号,因为您的守护进程[应该已经]调用了中的一个必要步骤。因此,要么^C正在杀死你的守护进程,你需要让你的代码调用
setsid(2)
,要么你的代码已经调用
setsid(2)
,而你有一堆恶意守护进程在后台运行:)

正如你正确认识到的那样,
logger
的阻塞是读取端和读取端之间的管道问题(最终)写入端的
$daemon_进程
。由于您希望后者的输出写入屏幕

$daemon_process >/dev/tty

将解决问题。

我想在调用守护程序之前关闭管道fd,这样程序就不会永远保持其打开状态。问题是bash中我希望执行的命令实际上不会执行此操作。本质上,我想为“forktest”关闭任何管道fd我使用Linux提供的daemon()函数。我已经用(1,1)参数和(1,0)尝试过了。在(1,1)的情况下守护程序函数应该将0-2个FD重定向到/dev/null。但是,我想保留它们,以便将错误写入屏幕,因此最好在脚本中关闭管道FD。随机打开文件描述符不会导致您的问题。您的问题是
/etc/rc5/myscript
正在等待
记录器
完成。Right、 但是,记录器正在等待EOF,而EOF永远不会到来,因为守护进程在管道打开的情况下持有一个文件描述符。一旦记录器获得EOF,它就会完成。好吧,似乎我无法从bash中获得我想要的。这是一个有趣的相关主题:我为解决我的问题所做的是在服务启动指示启动成功,并让日志记录器记录它,睡眠一秒钟,然后关闭。当然,这不是一个很好的解决方案,但它足够了,而且比在它引导的每个守护程序实用程序中手动关闭文件描述符要好。通常,守护程序应该关闭所有的输入/输出句柄,或者写入一个它打开或使用syslog。因此,如果您希望守护进程生成输出,那么您应该执行其中一项操作,但在任何一种情况下,守护进程都在内部处理它。另一方面,如果您只想使用记录器记录“success”消息,那么您应该启动守护进程,然后选中$?以编写相关消息。
#include <stdlib.h>

int main( int argc, char *argv[] ){
        if( fork() ){
                exit( 0 );
        }
        while( 1 ){
                sleep( 1 );
        }
        return EXIT_SUCCESS;
}
#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>
$ 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
$daemon_process >/dev/tty