免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: cu_liang
打印 上一主题 下一主题

用dup2()能关闭标准输出吗? [复制链接]

论坛徽章:
0
1 [报告]
发表于 2008-04-13 22:39 |显示全部楼层
原帖由 cu_liang 于 2008-4-11 10:52 发表
在APUE第三章中讲到
       dup2( filedes, filedes2 );  
is equivalent to
          close( filedes2 );
          fcntl( filedes, F_DUPFP, filesdes2 );

那为什么在执行下面这段代码时,还能打印出 ...


其实重点不是在dup2(),对于下面的代码:


  1. #include<stdio.h>
  2. #include<unistd.h>
  3. #include<fcntl.h>
  4. #include<sys/types.h>
  5. #include<stdlib.h>

  6. int main()
  7. {
  8.         close(STDOUT_FILENO);
  9.         write(0, "hello\n", 6);
  10.         return 0;
  11. }

复制代码

照样可以输出hello来。

而dup2()完成的功能是什么呢?它是让文件描述符的指针指向文件表。
当dup2(0, STDOUT_FILENO);时 首先关闭STDOUT_FILENO,也就是将标准输出关闭掉。此时再让STDOUT_FILENO描述符的指针指向STDIN_FILENO所指向的那个文件表。所以说对于楼主所列的第一个代码仍然可以输出也就是这样的原因。


  1. #include <unistd.h>
  2. #include <stdio.h>
  3. int main()
  4. {
  5.         dup2(0, STDOUT_FILENO );        
  6.         printf("how!!\n" );
  7. }
复制代码

此时STDIN_FILENO,STDOUT_FILENO两个都指向的是标准输入,也即是0的那个文件表,而这个又与终端相连,所以能够输出数据来。

不信你可以这样来试试,
gcc test.c -o test

./test 1>test.out
此时你可以看到那个how!!仍然是打印到终端而没有写入到test.out中,证明不是从标准输出得到的数据。

而如果
./test 0>test.out
你则可以看到那个how!!输出到了test.out文件中。证明是从标准输入这个描述符得到的数据。

不知道我说清楚没有?有什么大家再一起讨论。

评分

参与人数 1可用积分 +9 收起 理由
MMMIX + 9 精品文章

查看全部评分

论坛徽章:
0
2 [报告]
发表于 2008-04-13 22:42 |显示全部楼层
另外,楼主可以看看APUE2中3.12节的那个图,此时相当于是fd1与fd0都指向了fd0之前指向的那个file table。所以说你此时能够打印出东西来。

论坛徽章:
0
3 [报告]
发表于 2008-04-13 23:42 |显示全部楼层
原帖由 cu_liang 于 2008-4-13 23:30 发表
果然如此!将程序改为如下就不能输出“how!!”了#include
#include
#include
int main()
{
    int fd;
    fd = open( "./1.txt", O_CREAT|O_RDWR );
    printf( "the fd is :%d\n", fd );
     ...


我想应该就是这个原因,至于具体的实现我也不是太清楚,抱歉。

论坛徽章:
0
4 [报告]
发表于 2008-04-17 10:09 |显示全部楼层
原帖由 bierdaci 于 2008-4-17 00:17 发表


你这个实验让我对shell重定向原理产生了疑惑,./test 1>out中的"1"和write(1, .....)中的"1"难道不一样?


是一样的啊.

论坛徽章:
0
5 [报告]
发表于 2008-04-17 13:54 |显示全部楼层
原帖由 bierdaci 于 2008-4-17 11:37 发表


如果一样的话,为什么./test 1>out没有输出到out里呢?
我原来的理解./test 1>out shell大概会在程序中有类似如下的动作
fd = open("out", ...);
dup2(fd, 1);

如果是这样的话write(1, ...)怎么会不写 ...


因为楼主这个是特殊的情况, 此时的STDOUT_FILENO也即是1已经被关闭了.

论坛徽章:
0
6 [报告]
发表于 2008-04-28 11:42 |显示全部楼层
原帖由 源方 于 2008-4-28 11:02 发表
可是为什么标准输入与终端项链就把结果输出都终端。它毕竟是输入,是要接收终端的数据的。
难道还能像终端写???不是只读方式打开的?


我想描述符0是与终端相连, 它是读/写的方式打开的, 所以说它既能够接收到输入(这是它本来就该做的), 同时也能够作为输出.
我想可能有两点比较重要:
1. 它与终端相连.
2. 它是读/写.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP