Linux:重定向(redirect)

Linux:重定向(redirect)

今天写了个测试的小程序,用到了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;

你可能感兴趣的:(LINUX,OTHER)