Linux制作之Linux I/O重定向的道理和完成仓酷云
无论图形界面发展到什么水平这个原理是不会变的,Linux命令有许多强大的功能:从简单的磁盘操作、文件存取、到进行复杂的多媒体图象和流媒体文件的制作。在Unix体系中,每一个历程都有STDIN、STDOUT和STDERR这3种尺度I/O,它们是程序最通用的输出输入体例。几近一切言语都有响应的尺度I/O函数,好比,C言语能够经由过程scanf从终端输出字符,经由过程printf向终端输入字符。熟习Shell的伴侣都晓得,我们能够便利地对Shell命令举行I/O重定向,好比find-name"*.java">testfile.txt把以后目次下的Java文件列表重定向到testfile.txt。多半情形下,我们只必要懂得I/O重定向的利用就够了,可是假如要编程完成相似Shell的I/O重定向和管道功效,那末就必要分明它的道理和完成。
上面本文就以Linux体系为详细例子,先容I/O重定向的道理和完成(文中实行情况为Ubuntu12.04,内核版本3.2.0-59)。
文件形貌符表
了解I/O重定向的道理必要从Linux内核为历程所保护的关头数据布局动手。对Linux历程来说,每一个翻开的文件都是经由过程文件形貌符(FileDescriptor)来标识的,内核为每一个历程保护了一个文件形貌符表,这个表以FD为索引,再进一步指向文件的具体信息。在历程创立时,内核为历程默许创立了0、1、2三个特别的FD,这就是STDIN、STDOUT和STDERR,以下图所表示:
<br>
所谓的I/O重定向也就是让已创立的FD指向其他文件。好比,上面是对STDOUT重定向到testfile.txt前后内核文件形貌符表变更的表示图
重定向前:
<br>
重定向后:
<br>
在I/O重定向的过程当中,稳定的是FD0/1/2代表STDIN/STDOUT/STDERR,变更的是文件形貌符表中FD0/1/2对应的详细文件,使用程序只体贴前者。实质上这和接口的道理是相通的,经由过程一个直接层把功效的利用者和供应者解耦。
上面我们经由过程strace命令跟踪一下echo命令的体系挪用:
dagang@ubuntu12:~$straceechohello2>&1>/dev/null|grepwritewrite(1,"hellon",6)=6我们能够看到write(1,"hellon",6)如许一个体系挪用,它的第一个参数1就是代表的STDOUT的FD,这申明关于echo程序,它尽管(经由过程尺度I/O函数从STDOUT)向FD1写进,而不体贴它们FD1究竟对应的是哪一个文件。
Shell恰是经由过程I/O重定向和管道这类特别的文件把多个程序的STDIN和STDOUT串连在一同构成更庞大功效的,上面是Shell中经由过程管道的表示图:
<br>
上面我们用一个实践的例子来体验一下:
dagang@ubuntu12:~$sleep30|sleep40&5584dagang@ubuntu12:~$pgrep-lsleep5583sleep5584sleepdagang@ubuntu12:~$ll/proc/5583/fdtotal0lrwx------1dagangdagang64Feb2713:410->/dev/pts/3l-wx------1dagangdagang64Feb2713:411->pipe:lrwx------1dagangdagang64Feb2713:412->/dev/pts/3dagang@ubuntu12:~$ll/proc/5584/fdtotal0lr-x------1dagangdagang64Feb2713:410->pipe:lrwx------1dagangdagang64Feb2713:411->/dev/pts/3lrwx------1dagangdagang64Feb2713:412->/dev/pts/3下面我们启动了两个历程5583和5584,经由过程检察/proc//fd,我们看到历程5583的STDOUT和5584的STDIN被重定向到了pipe:,如许就到达了毗连两个历程尺度I/O的目标。
dup2()体系挪用
下面先容了文件形貌符表和I/O重定向的道理,那末在Linux体系中怎样经由过程C程序完成I/O重定向呢?次要用到了dup2()这个体系挪用,man中关于dup2是如许说的:
intdup2(intoldfd,intnewfd);
dup2()createacopyofthefiledescriptoroldfd.Afterasuccessfulreturnfromdup()ordup2(),theoldandnewfiledescriptorsmaybeusedinterchangeably.Theyrefertothesameopenfiledescription(seeopen(2))andthussharefileoffsetandfilestatusflags;forexample,ifthefileoffsetismodifiedbyusinglseek(2)ononeofthedescriptors,theoffsetisalsochangedfortheother.这里我们经由过程一个实践的成绩来讲明它的利用办法:
编写一个C程序,经由过程挪用sort这个Shell命令举行排序,请求把in.txt和out.txt分离重定向到sort的STDIN,STDOUT。参考完成:
intmain(){intpid=0;//forkaworkerprocessif(pid=fork()){//waitforcompletionofthechildprocessintstatus;waitpid(pid,&status,0);}else{//openinputandoutputfilesintfd_in=open("in.txt",O_RDONLY);intfd_out=open("out.txt",O_CREAT|O_RDWR,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);if(fd_in>0&&fd_out>0){//redirectSTDIN/STDOUTforthisprocessdup2(fd_in,0);dup2(fd_out,1);//callshellcommandsystem("sort");close(fd_in);close(fd_out);}else{//...errorhandling}}return0;}下面的次要步骤包含:
1.起首fork一个子历程,后续步骤都在子历程中完成,父历程经由过程waitpid()体系挪用守候子历程停止;
2.翻开open()体系挪用翻开in.txt和out.txt,失掉它们的形貌符(在我的测试中,这两个值一般为3和4);
3.经由过程dup2()体系挪用把STDIN重定向到fd_in,把STDOUT重定向到fd_out(注重,重定向的影响局限是全部子历程);
4.经由过程system()体系挪用运转shell命令sort
要明白学好linux不是一件一蹴而就的事,一定要能坚持使用它,特别是在使用初期。 熟悉系统的基本操作,Linux的图形界面直观,操作简便,多加上机练习就可熟悉操作,在Linux下学习办公软件等常用软件。 下面笔者在论坛看到的一个好问题: “安装红旗4.0后,系统紫光输入法自带的双拼方案和我的习惯不一样,如何自定义双拼方案解决?谢谢?”这个问题很简练。 说实话小时候没想过搞IT,也计算机了解也只是一些皮毛,至于什么UNIX,Linux,听过没见过,就更别说用过了。? Linux只是个内核!这点很重要,你必须理解这一点。只有一个内核是不能构成一个操作系统的。 当然你不需搭建所有服务,可以慢慢来。自己多动手,不要非等着别人帮你解决问题。 你需要提供精确有效的信息。Linux这并不是要求你简单的把成吨的出错代码或者数据完全转储摘录到你的提问中。 眼看这个学期的Linux课程已经告一段落了,我觉得有必要写一遍心得体会来总结一下这学期对着门课程的学习。 在系统检测不到与Linux兼容的显卡,那么此次安装就可能不支持图形化界面安装,而只能用文本模式安装等等。 对于英语不是很好的读者红旗 Linux、中标Linux这些中文版本比较适合。现在一些Linux网站有一些Linux版本的免费下载,这里要说的是并不适合Linux初学者。 任何人都可以根据自己的喜好来定制适合自己的操作系统,Linux?是抢占式多任务多用户操作系统. 可以说自己收获很大,基本上完成了老师布置的任务,对于拔高的题目没有去做,因为我了解我的水平,没有时间和精力去做。?
页:
[1]