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通讯,缓存文件要大小限制。或自己主动清除等。

文章最后。是不是有点取巧。你有什么更好的办法,欢迎评论交流!

參考:

linux获取后台进程的控制台数据的更多相关文章

  1. Linux 获取设备树源文件(DTS)里描述的资源

    Linux 获取设备树源文件(DTS)里的资源 韩大卫@吉林师范大学 在linux使用platform_driver_register() 注册 platform_driver 时, 需要在 plat ...

  2. I.MX6 Android Linux shell MMPF0100 i2c 设置数据

    #!/system/bin/busybox ash # # I.MX6 Android Linux shell MMPF0100 i2c 设置数据 # 说明: # 本文主要记录通过shell脚本来设置 ...

  3. ASP.NET Core 2.2 : 十六.扒一扒新的Endpoint路由方案 try.dot.net 的正确使用姿势 .Net NPOI 根据excel模板导出excel、直接生成excel .Net NPOI 上传excel文件、提交后台获取excel里的数据

    ASP.NET Core 2.2 : 十六.扒一扒新的Endpoint路由方案   ASP.NET Core 从2.2版本开始,采用了一个新的名为Endpoint的路由方案,与原来的方案在使用上差别不 ...

  4. Linux下Rsync+Inotify-tools实现数据实时同步

    Linux下Rsync+Inotify-tools实现数据实时同步 注意:下面的三个案例都是rsync 每次都是全量的同步(这就坑爹了),而且 file列表是循环形式触发rsync ,等于有10个文件 ...

  5. Android中WebView的跨域漏洞分析和应用被克隆问题情景还原(免Root获取应用沙盒数据)

    一.前言 去年年底支付宝的被克隆漏洞被爆出,无独有偶就是腾讯干的,其实真正了解这个事件之后会发现,感觉是针对支付宝.因为这个漏洞找出肯定花费了很大劲,主要是因为支付宝的特殊业务需要开启了WebView ...

  6. Linux下mongodb安装及数据导入导出教程

    Linux下mongodb安装及数据导入导出教程 #查看linux发行版本 cat /etc/issue #查看linux内核版本号 uname -r 一.Linux下mongodb安装的一般步骤 1 ...

  7. Linux 获取设备树源文件(DTS)里的资源【转】

    本文转载自:http://blog.csdn.net/keleming1/article/details/51036000 http://www.cnblogs.com/dyllove98/archi ...

  8. [转帖]Linux TCP/IP协议栈,数据发送接收流程,TCP协议特点

    Linux TCP/IP协议栈,数据发送接收流程,TCP协议特点 http://network.51cto.com/art/201909/603780.htm 可以毫不夸张的说现如今的互联网是基于TC ...

  9. 基于 Golang 完整获取百度地图POI数据的方案

    百度地图为web开发者提供了基于HTTP/HTTPS协议的丰富接口,其中包括地点检索服务,web开发者通过此接口可以检索区域内的POI数据.百度地图处于数据保护对接口做了限制,每次访问服务,最多只能检 ...

随机推荐

  1. Windows获取FSMO角色

    获取 FSMO 角色若要使用 Ntdsutil 实用工具获取 FSMO 角色,请按照下列步骤操作:1.登录到基于 Windows 2000 Server 或 Windows Server 2003 的 ...

  2. 小Z爱图论(NOIP信(sang)心(bin)赛)From FallDream

    题目: 小Z最近喜欢上了图论,于是他研究了一下图的连通性问题.但是他遇到了一个难题. 给定一个n个点的有向图,求有多少点对(i,j)满足从i点出发能到达点j ? 小Z仅会简单的朴素算法,所以他想问问你 ...

  3. 转 C++中的static关键字

    C++中的static关键字 C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static.前者应用于普通变量和函数,不涉及类:后者主要说明static在类中的作 ...

  4. "select一直返回0"的问题解决和总结

    场景:一个简单的TCP 服务器,以实现UPNP的事件体系结构 我在linux平台下,创建一个TCP套接字,绑定到49156端口,向UPNP SERVER发一个subscribe订阅请求,超时时间设置为 ...

  5. Segment Tree

    姑且叫这种数据结构这个名字 #include<iostream> #include<cstdio> #define N 200005 #define Lson ret<& ...

  6. 【C语言】指针增减

    int *pa = NULL; ; printf("%x\n", pb); char *pca = NULL; ; printf("%x\n", pcb); s ...

  7. EntityFramework之一对多关系(三)

    上篇介绍了一对一关系,下面介绍下一对多关系代码编写. 1.新建model实体,Product是产品类,Order是订单,一个产品对应多个订单 public class Product { public ...

  8. Usage of API documented as @since 1.6+

    报错:即方法是Java1.6才开始有的 File ->Project Structure->Project Settings -> Modules -> Language Le ...

  9. (26)C#WebService

    一.创建webservice 二.发布webservice 1.正式发布 (1)配置IIS 自己在局域网用的话,只需1,2,3 三步 1:网站的名称,将来IIS里有多个网站时可以方便区分 2:文件的本 ...

  10. POJ 1044: Date bugs

    题目描述 There are rumors that there are a lot of computers having a problem with the year 2000. As they ...