免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 13809 | 回复: 21
打印 上一主题 下一主题

将stdout和stderr重定向到同一个文件的问题。 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-09-28 16:03 |只看该作者 |倒序浏览
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
2 [报告]
发表于 2011-09-28 16:21 |只看该作者
  1. $ strace ./a.out
  2. execve("./a.out", ["./a.out"], [/* 43 vars */]) = 0
  3. brk(0)                                  = 0x25bc000
  4. mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe820527000
  5. access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
  6. open("/etc/ld.so.cache", O_RDONLY)      = 3
  7. fstat(3, {st_mode=S_IFREG|0644, st_size=50155, ...}) = 0
  8. mmap(NULL, 50155, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fe82051a000
  9. close(3)                                = 0
  10. open("/lib64/libc.so.6", O_RDONLY)      = 3
  11. read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260\24\2\0\0\0\0\0"..., 832) = 832
  12. fstat(3, {st_mode=S_IFREG|0755, st_size=1946144, ...}) = 0
  13. mmap(NULL, 3773688, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fe81ff70000
  14. mprotect(0x7fe8200ff000, 2097152, PROT_NONE) = 0
  15. mmap(0x7fe8202ff000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18f000) = 0x7fe8202ff000
  16. mmap(0x7fe820304000, 21752, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fe820304000
  17. close(3)                                = 0
  18. mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe820519000
  19. mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe820517000
  20. arch_prctl(ARCH_SET_FS, 0x7fe820517720) = 0
  21. mprotect(0x7fe8202ff000, 16384, PROT_READ) = 0
  22. mprotect(0x7fe820528000, 4096, PROT_READ) = 0
  23. munmap(0x7fe82051a000, 50155)           = 0
  24. fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 1), ...}) = 0
  25. mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe820526000
  26. write(1, "test stdout\n", 12test stdout
  27. )           = 12
  28. write(2, "test stderr\n", 12test stderr
  29. )           = 12
  30. exit_group(12)                          = ?
复制代码
但是重定向之后
  1. $ strace ./a.out >>std.txt 2>>std.txt
  2. $ cat std.txt
  3. execve("./a.out", ["./a.out"], [/* 43 vars */]) = 0
  4. brk(0)                                  = 0xe04000
  5. mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1580b7a000
  6. access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
  7. open("/etc/ld.so.cache", O_RDONLY)      = 3
  8. fstat(3, {st_mode=S_IFREG|0644, st_size=50155, ...}) = 0
  9. mmap(NULL, 50155, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f1580b6d000
  10. close(3)                                = 0
  11. open("/lib64/libc.so.6", O_RDONLY)      = 3
  12. read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260\24\2\0\0\0\0\0"..., 832) = 832
  13. fstat(3, {st_mode=S_IFREG|0755, st_size=1946144, ...}) = 0
  14. mmap(NULL, 3773688, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f15805c3000
  15. mprotect(0x7f1580752000, 2097152, PROT_NONE) = 0
  16. mmap(0x7f1580952000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18f000) = 0x7f1580952000
  17. mmap(0x7f1580957000, 21752, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f1580957000
  18. close(3)                                = 0
  19. mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1580b6c000
  20. mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1580b6a000
  21. arch_prctl(ARCH_SET_FS, 0x7f1580b6a720) = 0
  22. mprotect(0x7f1580952000, 16384, PROT_READ) = 0
  23. mprotect(0x7f1580b7b000, 4096, PROT_READ) = 0
  24. munmap(0x7f1580b6d000, 50155)           = 0
  25. fstat(1, {st_mode=S_IFREG|0600, st_size=1459, ...}) = 0
  26. mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1580b79000
  27. write(2, "test stderr\n", 12test stderr
  28. )           = 12
  29. write(1, "test stdout\n", 12test stdout
  30. )           = 12
  31. exit_group(12)                          = ?
复制代码

论坛徽章:
0
3 [报告]
发表于 2011-09-28 16:40 |只看该作者
./a.out 2>&1 >>std.txt
./a.out &>std.txt

都试过, 只要重定向了stderr, 顺序就变...

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
4 [报告]
发表于 2011-09-28 16:45 |只看该作者
但是重定向之后
adam8157 发表于 2011-09-28 16:21


只解释了系统调用方面的原因, 但c库方面的原因没有解释。
原因应该是 stdout 的特点决定的: stdout 在定向到文件后, 将使用全缓冲, 而stderr 仍然是无缓冲的;
但我一直不明白的是 c 库怎么能知道 stdout 重定向到文件了: 如果不使用 freopen 这类函数, 而直接使用 dup2,  那么没有理由 c runtime 强大到能够探知的

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
5 [报告]
发表于 2011-09-28 16:46 |只看该作者
除非是 bash 特意和 libc配合

论坛徽章:
0
6 [报告]
发表于 2011-09-28 17:11 |只看该作者
本帖最后由 adam8157 于 2012-01-08 15:39 编辑

明白了 =,=

论坛徽章:
0
7 [报告]
发表于 2011-09-28 17:27 |只看该作者
#include<stdio.h>
main()
{
    printf("test stdout\n");
    fflush(NULL);
    fprintf(stderr,"test stderr\n");
}

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
8 [报告]
发表于 2011-09-28 17:29 |只看该作者
但我一直不明白的是 c 库怎么能知道 stdout 重定向到文件了: 如果不使用 freopen 这类函数, 而直接使用 dup2,  那么没有理由 c runtime 强大到能够探知的
zylthinking 发表于 2011-09-28 16:45



    通过 fcntl(2),还是能分辨 fd 是不是关联到了终端,如果不是终端,那就假设它是文件好了。

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
9 [报告]
发表于 2011-09-28 17:33 |只看该作者
本帖最后由 zylthinking 于 2011-09-28 17:40 编辑
通过 fcntl(2),还是能分辨 fd 是不是关联到了终端,如果不是终端,那就假设它是文件好了。
MMMIX 发表于 2011-09-28 17:29


但调用fcntl的时机是什么时候呢, 总不能开一个循环不停的fcntl, 你可以说在 fwrite/fprintf 的时候触发一个检测, 但如果这么个情景: 先定向到文件, 然后写上10行, 总长度不达到全缓冲长度限制, 然后来一个 dup 给重定向到中断, 那么现在应该是行缓冲了, 但我再也不调用 FILE 系列函数了, 那你怎么保证被缓冲的数据被 flush以符合行缓冲定义?

论坛徽章:
0
10 [报告]
发表于 2011-09-28 17:34 |只看该作者
但调用fcntl的时机是什么时候呢, 总不能开一个循环不停的fcntl
zylthinking 发表于 2011-09-28 17:33



    你想多了, 看七楼
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP