【问题标题】:Why is my deamon not printing to console after I re-launch it?为什么我的守护程序在我重新启动后没有打印到控制台?
【发布时间】:2015-08-16 04:22:39
【问题描述】:

这是我的代码:

#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(void)
{
    pid_t pid;
    pid = fork();

    if (pid != 0)
    {
        exit(0);
    }

    setsid();
    chdir("/");

    while(1){
        sleep(4);
        printf("%s\n", "Hello world!");
    }

    return 0;
}

好的,现在我将打开终端,然后再次在里面启动 bash,输出将是:

Last login: Tue Jun  2 14:29:49 on ttys000
Korays-MacBook-Pro:~ koraytugay$ bash
bash-3.2$ ./a.out 
bash-3.2$ Hello world!
Hello world!
Hello world!
exit
exit
Korays-MacBook-Pro:~ koraytugay$ Hello world!
Hello world!

我想在这里展示的是,我启动了终端,据我所知,它启动了 bash,在 bash 中我又启动了一个 bash 并启动了我的程序。

即使我退出了 bash,守护进程仍在运行,这正是我所期待的......

但问题是,如果我退出终端应用程序,然后重新启动它,我将不再看到“Hello World”..

我看到的是:

Last login: Tue Jun  2 14:30:46 on ttys000
Korays-MacBook-Pro:~ koraytugay$ 

我关闭终端后我的守护进程死了吗?为什么在第一种情况下,即使我退出 bash,父 bash 仍然显示 Hello Worlds,但在我重新启动终端后不显示?

这就是我所说的终端:http://blog.teamtreehouse.com/introduction-to-the-mac-os-x-command-line

我也想补充一下这些信息,

执行时在新终端中

ps -A 

我还在看:

41891 ??         0:00.01 ./a.out
41902 ??         0:00.01 ./a.out

但是没有文字?为什么没有文本发送到标准输出?据我所知,守护进程仍在执行,终端正在向我显示标准输出,不是吗?

【问题讨论】:

    标签: c linux bash shell daemon


    【解决方案1】:

    这是意料之中的,因为当您退出应用程序写入其输出的终端文件处理程序时(stdout)消失了。当您再次启动终端时,它不会恢复相同的文件处理程序。如果您的应用程序正在写入文件并且您已将其删除,则情况相同。如果您创建具有相同路径的新文件,它将不会继续在里面写入。如果要保留输出,则必须在终端之后写入文件,例如来自 httpd、samba、sshd 等守护进程的日志文件。

    【讨论】:

    • 标准输出不总是0吗?你是什​​么意思文件是不同的文件?
    • 检查 lsof 应用程序的打开文件描述符。然后,您将看到 stdout 指向的位置。
    【解决方案2】:

    如果终端关闭,所有写入该 TTY 设备的进程都将关闭其标准输出。打开一个新的终端不会导致关闭的stdout神奇地恢复。

    【讨论】:

    • 标准输出不是全球性的吗?怎么可能关闭?每个进程都有自己的标准输出吗?
    • 为什么关闭终端会关闭标准输出文件?为什么退出 bash(如我的第一个示例)不会关闭标准输出?
    • @KorayTugay shellterminal 之间是有区别的。 shell是读取输入并解析并执行命令的程序,终端是处理输入和输出的设备。进程连接到终端设备,如果该设备关闭,使用该设备的进程当然不能继续写入该设备。
    • 终端是设备是什么意思?不就是另一个程序吗?
    • @KorayTugay 终端 program 设置终端 device(也称为 TTY 设备)用于输入和输出。我认为您需要搜索并阅读更多有关终端设备以及 POSIX 终端 I/O 工作原理的信息。
    【解决方案3】:

    您已经从最初的bash 实例分叉,该实例将标准输入、标准输出和标准错误与特定终端连接起来。当您终止 bash 实例时,stdin、stdout 和 stderr 所连接的终端将被关闭,因此对于您的守护进程,写入任何这些描述符实际上是写入链接到已删除文件或设备的描述符。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-17
      • 1970-01-01
      • 2013-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-21
      • 2020-06-05
      相关资源
      最近更新 更多