linux获取后台进程的控制台数据

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

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

參考:

[1] linux获取daemon进程的控制台数据 没有开花的树

时间: 2024-10-08 02:11:47

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

linux获取daemon进程的控制台数据

linux提供了一个daemon函数,使得进程可以脱离控制台运行,实现了后台运行的效果.但是进程后台运行后,原本在终端控制台输出的数据就看不到了.那么,怎样才能找回这些数据? 这里,文章主题就围绕着 如何获得后台进程的控制台数据,其中的原理要从daemon说起. daemon主要做两件事: 1.创建子进程,退出当前进程,并且以子进程创建新会话.这样,就算父进程退出,子进程也不会被关闭 2.将标准输入,标准输出,标准错误都重定向/dev/null daemon 实现大致如下: int daemon

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

Linux下mongodb安装及数据导入导出教程 #查看linux发行版本 cat /etc/issue #查看linux内核版本号 uname -r 一.Linux下mongodb安装的一般步骤 1.到mongodb的官网(https://www.mongodb.org/downloads) 下载相应你系统的安装包,拷贝(能够用ftp工具如winscp)到你的linux系统上面. 2.解压相应的安装包 命令例如以下:tar zxvf mongodb-linux-x86_64-3.0.4.tgz

安装redis-py并连接Redis服务器设置和获取redis的二进制数据

本文档简单介绍一下使用python版的Redis客户端redis-py来连接Redis并执行设置和获取redis的二进制数据. 说明: set,get,setnx,append等命令同样也可以用于设置二进制数据. 因为Redis的自带的客户端redis-cli不方便设置二进制数据,所以我们这里使用Python的客户端来进行 安装redis-py有三种方式: 1.   pip install redis 2.   easy_install redis 3.   从源码安装: python setu

http的post方式连接服务器,发送数据到服务端,并获取服务端的数据

大概的流程是:客户端填写了用户名和密码,在服务端进行判断,验证密码如果正确,则返回登录成功,如果密码错误,则返回登录失败 客户端是java程序,具体代码如下: package lgx.java.test; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Unsupport

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

#!/system/bin/busybox ash # # I.MX6 Android Linux shell MMPF0100 i2c 设置数据 # 说明: # 本文主要记录通过shell脚本来设置MMPF0100的数据. # # 2016-4-6 深圳 南山平山村 曾剑锋 # # 检查参数个数 if [ $# -lt 3 ]; then echo "USAGE:" echo " i2cSetData.sh <curPage> <address(hex)&

python分别使用多线程和多进程获取所有股票实时数据

python分别使用多线程和多进程获取所有股票实时数据 前一天简单介绍了python怎样获取历史数据和实时分笔数据,那么如果要获取所有上市公司的实时分笔数据,应该怎么做呢? 肯定有人想的是,用一个列表存储所有上市公司的股票代号,然后无限循环获取不就得了吗? 现在深市和沪市的股票一共有3400多只,如果你真这样做的话,获取一次所有股票的实时数据需要十几二十秒的时间,甚至更多,而且非常容易因为等待超时而使程序挂掉,如果你的模型对实时数据的质量要求非常高,这肯定是不行的,即使不考虑数据质量,获取数据的

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

Linux TCP/IP协议栈,数据发送接收流程,TCP协议特点 http://network.51cto.com/art/201909/603780.htm 可以毫不夸张的说现如今的互联网是基于TCP/IP构建起来的网络.弄懂协议栈的原理,无论对调试网络IO性能还是解决网络问题都是有很大帮助的.本片文章就带领大家来看看内核是如何控制网络数据流的. 作者:底层软件架构来源:今日头条|2019-09-30 09:28 收藏 分享 可以毫不夸张的说现如今的互联网是基于TCP/IP构建起来的网络.弄懂

linux获取目录下文件

查看当前目录下的文件:find . -type f查看当前目录下的文件夹: find . -type d如果文件file1不为空: if [ -s file1 ];then       echo "file1 不为空"fi #!/bin/sh for f in `find ./testdir -type f`; do         if [ -s $f ];then                 echo $f is not empty.                 echo 

获取百度地图POI数据二(准备搜索关键词)

上篇讲到  想要获取尽可能多的POI数据 需要准备尽可能多的搜索关键字   那么这些关键字如何得来呢?   本人使用的方法是通过一些网站来获取这些关键词   http://poi.mapbar.com/这个网站有全国各地的POI数据  对各个城市的POI数据都有归类  我便是从这个网站上面获取了上海市的各个类别的关键词  比如上海市所有的门牌号码  公路名称  地铁名称等等  下面介绍如何获取这些信息 和获取百度POI数据所用的方法一样,都是通过分析这个网站的url然后替换其中的参数获取不同的数