右边一条竖线怎么去(左竖线怎么画)
688
2022-05-28
在命令行运行程序时,可以用“>"运算符把标准输出重定向到文件:
~/Desktop/Mc$ echo "hello world" > log.txt ~/Desktop/Mc$ tail -f log.txt hello world
1
2
3
标准输入、标准输出、标准错误是三大默认数据流,除此之外还有其他形式的数据流,如文件连接和网络连接也属于数据流。数据流就是流动的数据,数据从一个进程流出,然后流入另一个进程。
重定向进程的输出,相当于改变进程发送数据的方向。如上面的例子,原本标准输出会把数据发送到屏幕,现在让它把数据发送到文件。
进程含有它正在运行的程序,还有栈和堆空间。除此之外,进程还需要记录数据流的连向,比如标准输出连到了哪里。这些记录记在哪里呢?答案就是描述符表。进程用文件描述符表示数据流,所谓的描述符其实就是一个数字。进程会把文件描述符和对应的数据流保存在描述符表中。
描述符表
描述符表的一列是文件描述符号,另一列是它们对应的数据流。虽然名字叫文件描述符,但它们不一定连接硬盘上的某个文件,也可能连接键盘、屏幕、文件指针、网络。
描述符表的前三项是不会变的:0号标准输入、1号标准输出、2号标准错误。其他项要么为空,要么连接进程打开的数据流。比如程序在打开文件进行读写时,就会占用其中一项。描述符表的大小是从0到255号。
创建进程以后,标准输入连接到键盘,标准输出和标准错误连接到屏幕。它会保持这样的连接,直到有人把它们重定向到了其他地方。
重定向就是替换数据流
标准输入/输出/错误在描述符表中的位置是固定的,但它们指向的数据流是可以改变的。例如想重定向标准输出,只需要修改表中1号描述符对应的数据流就OK了。
所有向标准输出发送数据的函数会先查看描述符表,看1号描述符指向哪条数据流,然后再把数据写到这条数据流中,printf()函数就是这样。
进程可以重定向自己
在命令行中可以用“>“和”<"运算符重定向程序。进程也能重定向它们自己,只需修改描述符表。只需要两步就可以实现:
1.fileno()返回文件描述符号
每打开一个文件,操作系统都会在描述符表中新注册一项。假设我们打开了log.txt文件:
FILE *my_file = fopen("log.txt","w");
1
操作系统会打开log.txt文件,然后返回一个指向它的指针,操作系统还会遍历描述符表找空项,把新文件注册在其中。
int descriptor = fileno(my_file);
1
在失败时不返回-1的函数很少,fileno()就是其中之一。只要你把打开文件的文件指针传给fileno(),它就一定会返回描述符编号。
2.dup2()复制数据流
每次打开文件都会使用描述符表中新的一项。但如果你想修改某个已经注册过的数据流,比如让1号文件描述符重新指向其他数据流,就可以用dup2()函数来实现,dup2()可以复制数据流,假设我们在3号文件描述符中注册了log.txt文件指针,下面代码就可以同时把文件指针连接到1号描述符:
dup2(3,1);
1
虽然log.txt文件只有一个,与它相连的数据流也只有一个,但是数据流(FILE *)同时注册在文件描述符1和3中。所以标准输出都会被重定向到文件log.txt中。
我们看一个完整的实例:
#include
1
2
3
4
5
6
7
8
9
10
11
12
13
14
编译运行:
~/Desktop/MyC$ gcc test4.c -o test4 ~/Desktop/MyC$ ./test4 ~/Desktop/MyC$ tail -f log.txt Hello world,I love you!
1
2
3
4
用管道连接输入与输出,符号“|”表示管道(pipe),它能连接一个进程的标准输出与另一个进程的标准输入。
如:
~/Desktop/MyC$ ls /usr/include | grep stdio stdio_ext.h stdio.h
1
2
3
ls程序的标准输出会连接到grep程序的标准输入。
谢谢阅读!
任务调度
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。