驱动开发读书笔记. 0.03 如何将可执行文件输出从定向 以及 标准输出重定向和标准输出连到终端的区别
《UNIX环境高级编程》里面(第三版 p184),将a.out > temp.out 即可完成 程序输出的重定向,但是我在上机测试的时候并不能,会提示 command not found;网上查询无结果,只有ls > temp.out 此类 将目录下的文件名输出到temp.out里面,于是灵机一动,想到 ls 是命令, a.out不是命令,但是./aout是命令并带有输出,这样一类比,果然可以了
$ ./a.out > temp.out
这样会将输出都重定向到 temp.out里面
重定向到temp.out的结果(即运行命令 ./a.out > temp.out)
a write to stdout
before fork
pid = 4532,glob = 7,var = 89
before fork
pid = 4533,glob = 7,var = 89
直接输出到终端的结果(即直接运行命令 ./a.out,无重定向)
a write to stdout
before fork
pid = 4625,glob = 7,var = 89
pid = 4626,glob = 7,var = 89
代码
1 #include "unistd.h" 2 #include "stdio.h" 3 int globvar=6; 4 5 char buf[]="a write to stdout "; 6 7 int main(void) 8 { 9 int var; 10 pid_t pid; 11 12 var = 88; 13 if(write(STDOUT_FILENO,buf,sizeof(buf)-1)!=sizeof(buf)-1) 14 err_sys("write error"); 15 printf("before fork "); 16 17 if(pid = fork()<0){ 18 err_sys("fork error"); 19 } else if (0 == pid){ 20 globvar++; 21 var++; 22 } else { 23 sleep(2); 24 } 25 26 printf("pid = %ld,glob = %d,var = %d ", (long)getpid(),globvar,var); 27 28 exit(0); 29 }
为什么两者会有不同?
因为 运行./a.out的时候是标准输出连到终端(屏幕输出),printf会将内容送到缓冲区,然后遇到换行符会进行一次冲洗(行缓冲);
而运行./a.out >temp.out 是将标准输出重定向到一个文件,此时是全缓冲,等到exit 之后才会进行冲洗;
第一个printf 是在fork之前,重定向的时候缓冲区的数据也会复制到子进程中,所以"before fork" 会被打印两次