今天写了个测试的小程序,用到了stdout以及stderr,输出的时候太乱,很难分析,想到了重定向。
1.一个进程运行时,一般打开三个文件:stdin,stdout,stderr;
2.stdin是标准输入,stdout是标准输出,stderr是标准错误;
3.程序正确的输出一般输出到stdout中,程序错误的输出一般输出到stderr中;
4.stdout与stderr一般都直接显示在终端屏幕上;
5.鉴于4,这样会将错误的信息和正确的信息都混在一起,不便于查看;
先看一个例子:
[test1280@localhost ~]$ cat abc
cat: abc: 没有那个文件或目录
[test1280@localhost ~]$ cat abc > jiang
cat: abc: 没有那个文件或目录
咦,为啥第二次重定向之后还是会输出到屏幕上呢?
(为啥我重定向了,但是屏幕上还有输出?)
原因是那句话实际上输出到了stderr中,代表一个错误的信息,我仅仅是将stdout重定向到了一个文件,没有将stderr重定向,结果就很明显了。
[test1280@localhost ~]$ cat abc > mystdout 2>mystderr
[test1280@localhost ~]$ ll mystd*
-rw-rw-r-- 1 test1280 test1280 29 06-21 20:35 mystderr
-rw-rw-r-- 1 test1280 test1280 0 06-21 20:35 mystdout
[test1280@localhost ~]$ cat mystdout
[test1280@localhost ~]$ cat mystderr
cat: abc: 没有那个文件或目录
需要注意的一点是>与>>的区别,>是会将原来文件中的内容都清空,但是>>是追加,当目标文件不存在时,两者都会新建文件。
实际程序是啥样子的?
#include
#include
int main()
{
fprintf(stdout, "standard-output-info\n");
fprintf(stderr, "standard-error-info\n");
return 0;
}
[test1280@localhost ~]$ !g
gcc -o main main.c
[test1280@localhost ~]$ ./main >mystdout 2>mystderr
[test1280@localhost ~]$ ll mystd*
-rw-rw-r-- 1 test1280 test1280 20 06-21 20:42 mystderr
-rw-rw-r-- 1 test1280 test1280 21 06-21 20:42 mystdout
[test1280@localhost ~]$ cat mystdout
standard-output-info
[test1280@localhost ~]$ cat mystderr
standard-error-info
如果我想要将stdout和stderr都重定向到一个文件,那该怎么写?
程序还是上面的那个,主要看下下面的命令:
[test1280@localhost ~]$ ./main >>myoutput 2>>myoutput
[test1280@localhost ~]$ cat myoutput
standard-error-info
standard-output-info
好像是没啥问题哈。
实际上有潜在的隐患,可能stdout与stderr交替输出,这里由于我们输出信息较短,没有出现这样的情况,但是实际是错误的,不可靠的。
那该怎么写呢?
[test1280@localhost ~]$ ./main >myoutput 2>&1
[test1280@localhost ~]$ ll myoutput
-rw-rw-r-- 1 test1280 test1280 41 06-21 20:46 myoutput
[test1280@localhost ~]$ cat myoutput
standard-error-info
standard-output-info
[test1280@localhost ~]$ ./main &>myoutput
[test1280@localhost ~]$ ll myoutput
-rw-rw-r-- 1 test1280 test1280 41 06-21 20:47 myoutput
[test1280@localhost ~]$ cat myoutput
standard-error-info
standard-output-info
关键的两句:
./main >myoutput 2>&1
./main &>myoutput
我一般使用2>&1来处理。
关于重定向输入==》
#include
#include
int main()
{
char s[32];
while (scanf("%s", s) != EOF)
{
fprintf(stdout, "info is %s\n", s);
}
return 0;
}
[test1280@localhost ~]$ gcc -o main main.c
[test1280@localhost ~]$ ./main
abc
info is abc
def
info is def
test1280
info is test1280
后面的abc、def、test1280都是从键盘上输入进去的,最后按Ctrl+D代表结束输入。
现在可以这样子(程序不变):
[test1280@localhost ~]$ cat myinput
ijk
opq
rst
[test1280@localhost ~]$ ./main <./myinput
info is ijk
info is opq
info is rst
吼吼,看明白了嘛?
至于<<用得比较少,那天工作中用了再来这里记一下。
总结:
1.>与>>的区别;
2.>stdout 2>stderr;
3.>stdout 2>&1;
4.标准输入stdin;