linux提供了一个daemon函数,使得进程可以脱离控制台运行,实现了后台运行的效果。但是进程后台运行后,原本在终端控制台输出的数据就看不到了。那么,怎样才能找回这些数据?
这里,文章主题就围绕着 如何获得后台进程的控制台数据,其中的原理要从daemon说起。
daemon主要做两件事:
1、创建子进程,退出当前进程,并且以子进程创建新会话。这样,就算父进程退出,子进程也不会被关闭
2、将标准输入,标准输出,标准错误都重定向/dev/null
daemon 实现大致如下:
int daemonize(int nochdir, int noclose)
{
int fd;
switch (fork()) {
case -1:
return (-1);
case 0:
break;
default:
_exit(EXIT_SUCCESS);
}
if (setsid() == -1)
return (-1);
if (nochdir == 0) {
if(chdir("/") != 0) {
perror("chdir");
return (-1);
}
}
if (noclose == 0 && (fd = open("/dev/null", O_RDWR, 0)) != -1) {
if(dup2(fd, STDIN_FILENO) < 0) {
perror("dup2 stdin");
return (-1);
}
if(dup2(fd, STDOUT_FILENO) < 0) {
perror("dup2 stdout");
return (-1);
}
if(dup2(fd, STDERR_FILENO) < 0) {
perror("dup2 stderr");
return (-1);
}
if (fd > STDERR_FILENO) {
if(close(fd) < 0) {
perror("close");
return (-1);
}
}
}
return (0);
}
所以,想取回进程的控制台数据,只要将标准输出,标准错误重定向到指定文件,然后读取这个文件就好了。
文章这里写了个例子,简单演示下(这里通过kill信号完成进程通信,有点粗暴)
代码如下,保存为 daemon_example.c
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
static int fd = -1;
void sigroutine(int dunno) {
switch (dunno) {
case SIGUSR1:
fprintf(stderr, "Get a signal -- SIGUSR1 \n");
if (fd != -1) close(fd);
fd = open("/tmp/console_temp.log", O_RDWR|O_APPEND|O_CREAT, 0600);
if (fd == -1) break;
dup2(fd, STDIN_FILENO);
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
break;
case SIGUSR2:
fprintf(stderr, "Get a signal -- SIGUSR2 \n");
if (fd != -1) close(fd);
fd = open("/dev/null", O_RDWR, 0);
if (fd == -1) break;
dup2(fd, STDIN_FILENO);
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
break;
}
return;
}
int main() {
signal(SIGUSR1, sigroutine);
signal(SIGUSR2, sigroutine);
daemon(1,0);
for (;;){
fprintf(stderr,"test \n") ; // 不断打印test
sleep(1);
}
return 0;
}
然后,编译和执行这个程序:
$ gcc -o
daemon_example daemon_example.c
$ chmod +x daemon_example
$ ./daemon_example
$ ps -ef| grep daemon_example
root 11328 1 0 19:15 ? 00:00:00 ./daemon_example
如上,进程后台运行了,拿到pid 11328
接着,写个脚本测试这个程序, 保存为test.sh:
#!/bin/bash
pid=$1
ps -p $pid>/dev/null
if [ ! $? -eq 0 ] ; then
echo pid does not exist!
exit 1
fi
echo pid $pid
trap "kill -usr2 $pid && exit 1" HUP INT QUIT TERM
kill -usr1 $pid
echo it works,please wait..
sleep 1
tail -f -n 0 /tmp/console_temp.log
echo done!
执行这个脚本,结果如下:
$ ./test.sh 11328
pid 11328
it works,please wait..
test
test
然后,按ctrl+c 退出脚本,这时脚本会通知进程将标准输出和标准错误重定向到 /dev/null,继续后台运行。
这样,这个脚本就成了后台进程的调试工具了,需要后台数据的时候执行一下,不需要就关闭。当然,这只是一个示例,实际应用中要做改善,比如kill信号改成pipe或socket通讯,缓存文件要限制大小,或自动清除等。
文章最后,是不是有点取巧,你有什么更好的办法,欢迎评论交流!
参考:
分享到:
相关推荐
4. **在GUI中操作管道**:在父进程中,GUI程序可以写入数据到管道的另一端,模拟控制台程序的输入;同时,它也可以读取管道中的数据,展示在界面上。 5. **关闭不再需要的管道端口**:为了防止资源泄漏,当不再需要...
进程是正在执行的程序的一个实例,包含了程序的执行上下文、相关数据以及程序本身。与静态的程序不同,进程具有动态性,体现在其生命周期的创建、执行、等待和终止等阶段。 在Linux中,创建进程主要通过`fork`和`...
1. **后台进程挂起**: 在SUN Solaris系统中,可以使用`stop %num`命令挂起后台任务。在Red Hat等其他系统中,可以使用`kill -STOP PID`来实现相同的效果。 2. **恢复挂起的后台任务**: 若要重新激活挂起的后台任务...
Linux后台是指在没有图形用户界面的情况下运行程序和服务的环境,它是服务器和许多自动化任务的核心。在Linux系统中,后台执行程序通常与控制台或终端分离,使得用户可以继续进行其他工作,而不需要等待某个程序完成...
管道是一种特殊的文件描述符,它允许我们在不同的进程之间传递数据。在本脚本中,我们使用了 `exec` 命令来将标准输入重定向到管道中。 知识点四:Shell 脚本编程 本脚本使用到了 shell 脚本编程技术,我们使用了...
在IT领域,进程是操作系统中执行程序的基本单元,包含了运行中的代码和数据。获取和监控进程信息对于系统管理和性能分析至关重要。本主题将详细讲解如何实现一个获取进程信息的类以及创建一个监控进程变化的线程。 ...
在Linux操作系统中,多进程是实现并发执行的一种方式,它允许多个程序同时运行,以提高系统的资源利用率和效率。本资料"linux多进程.rar"包含的易语言源码,显然是为了教学或实践如何在Linux环境下创建和管理多进程...
守护进程(Daemon)通常是指在后台运行且不与终端交互的进程,它在Linux环境中常见。而在Windows中,我们称之为服务。Delphi提供了一种简便的方式来创建服务程序,这主要得益于它的VCL库中的TService组件。 在描述...
2. **GM后台**:GM后台系统是游戏管理员的控制台,用于监控游戏状态、处理玩家投诉、进行数据调整、执行特殊操作等。通过分析GM后台源码,我们可以了解到游戏管理的常见功能和实现方式。 3. **工具**:这部分可能...
守护进程是Linux系统中非常重要的一种进程类型,它运行在后台,通常用于执行特定的任务或提供系统服务。守护进程对于维持系统的稳定性和可靠性至关重要。 #### 守护进程的特点 守护进程具有以下几个显著特点: 1....
如果要在Red Hat Enterprise Linux上将.NET Core进程作为后台进程运行,则可以创建自定义systemd单元。今天我将为.NET Core编写两个自定义系统单元的例子。一个是运行.NET Core控制台应用程序的一种类型,另一个是...
Spring Boot 在 Linux 后台运行的方法 Spring Boot 是一个基于 Java 的开源框架,最近几年来非常流行,许多开发者选择使用 Spring Boot 来开发 Web 应用程序。然而,在生产环境中,如何让 Spring Boot 项目在 Linux...
Linux守护进程,或称为守护程序或精灵进程,是Linux操作系统中的关键组成部分,它们在后台运行,没有控制终端,且通常以超级用户权限运行。守护进程的主要任务是提供系统服务,如网络服务(如HTTP服务器httpd)、...
这意味着,如果父进程是一个控制台应用程序,那么它创建的子进程也将共享同一个控制台窗口,除非子进程明确地创建了自己的控制台。这种情况下,父子进程可以通过控制台进行通信,例如,父进程可以打印信息到控制台,...
1. **创建守护进程**:在Unix/Linux系统中,通过`fork()`和`setsid()`函数可以创建一个脱离控制台的守护进程。而在Windows中,我们需要使用`CreateService()` API来创建服务。 2. **设置定时器**:选择合适的定时器...
使用这种方法时,Python程序同样会在后台运行,且标准输出stdout和标准错误stderr的输出都将无效,因此程序的运行结果无法在控制台中被看见。此外,使用.pyw扩展名的Python脚本无法再通过标准输入stdin读取数据,...
NewLife.Agent是一个服务管理框架,用于开发随系统自动启动的长时间运行后台应用程序,支持Windows/Linux。 在Windows上注册为Windows服务,在Linux上注册为Systemd守护进程。 Agent支持...
此外,控制台应用还常被用作其他复杂程序的后台服务或组件。 总之,控制台应用是计算机科学中的基本构建块,它们在软件开发中占据重要地位。无论你是初学者还是经验丰富的开发者,理解并掌握控制台应用的开发都是...
进程控制是Linux管理后台运行程序的关键。`ps`命令用于查看当前进程状态,`top`提供实时的进程监控,`kill`和`pkill`用来发送信号结束进程,`nohup`则可以让程序在用户退出后继续运行。了解进程ID(PID)和父进程ID...
进程管理是Linux系统管理中的高级主题,书中介绍了进程的工作原理、如何查看和控制进程、中断进程以及如何将进程放置到后台运行。最后,书中还简要介绍了信号的概念,这是进程间通信的一种方式。 总的来说,Linux...