c 中 stdout, stderr 容易忽视的一些细节
2012-11-02 15:54
253 查看
先看下面一个例子
a.c :
$ ./a
normal
bad
$ ./a > tmp 2>&1
$ cat tmp
bad
tmp
我们看到, 重定向到一个文件后, bad 到了 normal 的前面.
原因如下:
"The stream stderr is unbuffered. The stream stdout is line-buffered when it points to a
terminal. Partial lines will not appear until fflush(3) or exit(3) is called, or a newline
is printed. This can produce unexpected results, especially with debugging output. The
buffering mode of the standard streams (or any other stream) can be changed using the
setbuf(3) or setvbuf(3) call. "
因此, 可以使用如下的代码:
但是尽量不要同时使用 文件流 和 文件描述符,
"Note that mixing use of FILEs and raw file descriptors can produce unexpected results and
should generally be avoided. A general rule is that file
descriptors are handled in the kernel, while stdio is just a library. This means for exam-
ple, that after an exec(), the child inherits all open file descriptors, but all old
streams have become inaccessible."
a.c :
int main(int argc, char *argv[]) { fprintf(stdout, "normal\n"); fprintf(stderr, "bad\n"); return 0; }
$ ./a
normal
bad
$ ./a > tmp 2>&1
$ cat tmp
bad
tmp
我们看到, 重定向到一个文件后, bad 到了 normal 的前面.
原因如下:
"The stream stderr is unbuffered. The stream stdout is line-buffered when it points to a
terminal. Partial lines will not appear until fflush(3) or exit(3) is called, or a newline
is printed. This can produce unexpected results, especially with debugging output. The
buffering mode of the standard streams (or any other stream) can be changed using the
setbuf(3) or setvbuf(3) call. "
因此, 可以使用如下的代码:
int main(int argc, char *argv[]) { fprintf(stdout, " normal\n"); fflush(stdout); fprintf(stderr, " bad\n"); return 0; }这样重定向到一个文件后就正常了. 但是这种方法只适用于少量的输出, 全局的设置方法还需要用 setbuf() 或 setvbuf(), 或者采用下面的系统调用:
int main(int argc, char *argv[]) { write(1, "normal\n", strlen("normal\n")); write(2, "bad\n", strlen("bad\n")); return 0; }
但是尽量不要同时使用 文件流 和 文件描述符,
"Note that mixing use of FILEs and raw file descriptors can produce unexpected results and
should generally be avoided. A general rule is that file
descriptors are handled in the kernel, while stdio is just a library. This means for exam-
ple, that after an exec(), the child inherits all open file descriptors, but all old
streams have become inaccessible."
相关文章推荐
- 解析c中stdout与stderr容易忽视的一些细节
- Android init进程一些容易忽视的技术细节
- C语言中一些容易忽视的细节
- 自定义View中我们比较容易忽视的一些小细节
- 容易忽视的一些细节
- 细节决定成败,浅析一些容易被忽视的Java关键字
- 一些容易被初学者忽视的C#语言细节
- HttpClient容易忽视的细节(关闭连接)
- 维护中一些明显但容易忽视的好方法
- SQL开发中容易忽视的一些小地方( 三)
- SQL开发中容易忽视的一些小地方(一)
- Windows 在处理 dll 的一些容易被人忽略的细节
- 一个容易被忽视的 strlen 细节
- ASP.NET常被忽视的一些细节
- 产品需求文档中容易被忽视的10个细节
- ASP.NET常被忽视的一些细节
- SQL开发中容易忽视的一些小地方(二)
- HttpClient容易忽视的细节——连接关闭
- 在字符数组中容易忽视的一些小的问题
- SQL开发中容易忽视的一些小地方(一)