Linux:重定向(redirect)

来源:互联网 发布:java防止页面脚本注入 编辑:程序博客网 时间:2024/04/25 22:14

Linux:重定向(redirect)

今天写了个测试的小程序,用到了stdout以及stderr,输出的时候太乱,很难分析,想到了重定向。

1.一个进程运行时,一般打开三个文件:stdin,stdout,stderr;

2.stdin是标准输入,stdout是标准输出,stderr是标准错误;

3.程序正确的输出一般输出到stdout中,程序错误的输出一般输出到stderr中;

4.stdout与stderr一般都直接显示在终端屏幕上;

5.鉴于4,这样会将错误的信息和正确的信息都混在一起,不便于查看;

先看一个例子:

[test1280@localhost ~]$ cat abccat: abc: 没有那个文件或目录[test1280@localhost ~]$ cat abc > jiangcat: 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 <stdio.h>#include <stdlib.h>int main(){    fprintf(stdout, "standard-output-info\n");    fprintf(stderr, "standard-error-info\n");    return 0;}
[test1280@localhost ~]$ !ggcc -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 mystdoutstandard-output-info[test1280@localhost ~]$ cat mystderr standard-error-info

如果我想要将stdout和stderr都重定向到一个文件,那该怎么写?

程序还是上面的那个,主要看下下面的命令:

[test1280@localhost ~]$ ./main >>myoutput 2>>myoutput[test1280@localhost ~]$ cat myoutput standard-error-infostandard-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-infostandard-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-infostandard-output-info

关键的两句:

./main >myoutput 2>&1./main &>myoutput

我一般使用2>&1来处理。


关于重定向输入==》

#include <stdio.h>#include <stdlib.h>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 ~]$ ./mainabcinfo is abcdefinfo is deftest1280info is test1280

后面的abc、def、test1280都是从键盘上输入进去的,最后按Ctrl+D代表结束输入。

现在可以这样子(程序不变):

[test1280@localhost ~]$ cat myinput ijkopqrst[test1280@localhost ~]$ ./main <./myinput info is ijkinfo is opqinfo is rst

吼吼,看明白了嘛?

至于<<用得比较少,那天工作中用了再来这里记一下。

总结:

1.>与>>的区别;

2.>stdout 2>stderr;

3.>stdout 2>&1;

4.标准输入stdin;