有时,我们须要将标准输出(stdout),标准错误输出(stderr)重定向到文件中,便捷我们追踪程序运行信息。这在守护进程(daemon)中十分重要,由于这类进程与控制台脱离关系,所以它们的标准输出都未能在控制台显示。这样只能通过重定向到文件的方式记录标准输出信息。
这么怎么能够将标准输出重定向呢?这与unix的文件句柄有关。标准输入、标准输出、标准错误输出对应的文件句柄分别为0、1、2,这种句柄在进程启动时就默认存在的。随后每打开一个文件,文件的句柄就取仍未被占用的最小值。诸如,目前只有0、1、2这三个句柄,这么你打开一个文件,这个文件的句柄就是3,再打开一个,就是4。假如现今关掉句柄3,目前存在的句柄就为0、1、2、4。此时你再打开一个文件,这么该文件的句柄就是3,而不是5。了解呼!
借助unix文件句柄的生成特性,我们来完成重定向操作如下:
1.首先新建文件out.txt,作为我们重定向的文件。之后打开这个文件intold_fd=open("out.txt",O_WRONLY|O_CREAT|O_APPEND,0644);这样我们就获得了操作这个文件的文件句柄unix/linux,假定为3。
2.关掉标准输出句柄close(STDOUT_FILENO);这为我们下一步复制里面的文件句柄,创造条件。
3.借助unix的系统调用dup函数,复制文件句柄,并返回新的文件句柄。intnew_fd=dup(old_fd);按照unix文件句柄的生成规则(取仍未占用的最小句柄),这个new_fd的值应为1(STDOUT_FILENO);
4.最后,其实不要忘了关掉old_fd,由于这个文件句柄早已没有用了。close(old_fd),释放系统资源。
我们将里面的操作转化为代码并测试如下:
#include
#include
#include
#include
#define err_exit(m) {perror(m); exit(1);}
void main(){
int old_fd, new_fd;
printf("Before Redirect: Hello, Worldn");
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, Worldn");
}
其实linux也提供了更为便捷的系统调用dup2(old_fd,new_fd);它会先将new_fd关掉linux计划任务,之后复制old_fdunix/linux,最后手动关掉old_fd,这样简化了我们操作linux社区,如下所示:
#include
#include
#include
#include
#define err_exit(m) {perror(m); exit(1);}
void main(){
int old_fd, new_fd;
int retVal;
printf("Before Redirect: Hello, Worldn");
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, Worldn");
}
我们查看一下结果:catout.txt
最后,庆贺你完成了输入输出重定向的功能!!
文章评论