unix/linux 下标准输出重定向

有时,我们需要将标准输出(stdout),标准错误输出(stderr)重定向到文件中,方便我们追踪程序运行信息。这在守护进程(daemon)中非常重要,因为这类进程与控制台脱离关系,所以它们的标准输出都无法在控制台显示。这样只能通过重定向到文件的方法记录标准输出信息。

那么如何才能将标准输出重定向呢?这与unix的文件句柄有关。标准输入、标准输出、标准错误输出对应的文件句柄分别为0、1、2,这些句柄在进程启动时就默认存在的。此后每打开一个文件,文件的句柄就取尚未被占用的最小值。例如,目前只有0、1、2这三个句柄,那么你打开一个文件,这个文件的句柄就是3,再打开一个,就是4。如果现在关闭句柄3,目前存在的句柄就为0、1、2、4。此时你再打开一个文件,那么该文件的句柄就是3,而不是5。了解呼!

利用unix文件句柄的生成特点,我们来完成重定向操作如下:

1.  首先新建文件out.txt,作为我们重定向的文件。然后打开这个文件int old_fd = open("out.txt",O_WRONLY | O_CREAT |  O_APPEND,0644); 这样我们就获得了操作这个文件的文件句柄,假设为3。

2.  关闭标准输出句柄close(STDOUT_FILENO); 这为我们下一步复制上面的文件句柄,创造条件。

3.  利用unix的系统调用dup函数,复制文件句柄,并返回新的文件句柄。int new_fd = dup(old_fd); 根据unix文件句柄的生成规则(取尚未占用的最小句柄),这个new_fd的值应为1(STDOUT_FILENO);

4.  最后,当然不要忘了关闭old_fd,因为这个文件句柄已经没有用了。close(old_fd),释放系统资源。

我们将上面的操作转化为代码并测试如下:

#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>

#define	err_exit(m) 	{perror(m); exit(1);}

void	main(){
	int old_fd, new_fd;
	printf("Before Redirect: Hello, World\n");
        old_fd = open("out.txt", O_WRONLY | O_CREAT | O_APPEND , 0644);
	if(old_fd == -1) err_exit("open error");
	close(STDOUT_FILENO);//关闭标准输出句柄;
	new_fd = dup(old_fd);//复制old_fd文件句柄,并返回新的文件句柄;
	if(new_fd == -1) err_exit("dup error");
	close(old_fd);	     //关闭old_fd,释放系统资源;
	printf("After  Redirect: Hello, World\n");
}
当然linux也提供了更为方便的系统调用dup2(old_fd, new_fd);它会先将new_fd关闭,然后复制old_fd,最后自动关闭old_fd,这样简化了我们操作,如下所示:

#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>

#define	err_exit(m) 	{perror(m); exit(1);}

void	main(){
	int old_fd, new_fd;
	int retVal;
	printf("Before Redirect: Hello, World\n");
	old_fd = open("out.txt", O_WRONLY | O_CREAT | O_APPEND , 0644);
	if(old_fd == -1) err_exit("open error");
	retVal = dup2(old_fd, STDOUT_FILENO);
	if(retVal == -1) err_exit("dup2 error");
	printf("After Redirect: Hello, World\n");
}

 

我们查看一下结果:cat out.txt

最后,祝贺你完成了输入输出重定向的功能!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值