设为首页 加入收藏

TOP

用C实现的一个Bash脚本
2014-11-24 14:39:11 来源: 作者: 【 】 浏览:7
Tags:实现 一个 Bash 脚本

题目:设当前目录下有三个二进制格式的可执行程序,文件名分别为cmd1,cmd2和cmd3.


(1).在Bash下的下列命令完成什么功能?


./cmd1 2>&1 | ./cmd2 > r.txt; ./cmd3


(2).编写C语言源程序完成与(1)相同的功能


提示:exec系统调用可用execlp("./cmd1","cmd1",(char *)0);


打开文件用 fd = open("r.txt", O_CREAT | O_TRUNC | O_WRONLY,0666);


dup2系统调用法为dup2(src_fd,dst_fd);


创建管道用pipe(int fds[2]);


等待子进程结束用wait(int staloc);



答:首先说明,0,1,2三个文件说明符分别代表stdin, stdout和stderr。


2>&1的意思是将cmd1的标准输出流和标准错误流合并到标准输出流中;


接下来通过管道将刚才的结果输出到cmd2的输入中;


cmd2>r.txt将cmd2的输出结果重定向到文件r.txt中;


最后是执行cmd3,这与前面的一切都没有关系。(有一点尚存疑问,那就是cmd3是否和cmd1一样,都将stdout和stderr合体了,由于我没有测试错误的用例,因此这里不是标答。)


(2)这题才是重点。首先说明管道和重定向的一些知识。



【 a. 左边的命令应该有标准输出 | 右边的命令应该接受标准输入


左边的命令应该有标准输出 > 右边只能是文件


左边的命令应该需要标准输入 < 右边只能是文件


b. 管道触发两个子进程执行"|"两边的程序;而重定向是在一个进程内执行。】[1]


做这道题之前我接触这方面比较少,下面这段代码参考了不少东西,但是不知来源,没法列举了。这段代码是在一个同学给我的源文件的基础上修改的,因为之前我基本上不会用管道 ( ̄. ̄)


为了能测试,我把虚无缥缈的三个cmd换成了活生生的grep,wc和who ( ̄0  ̄)y


为防止以后忘记,我把这张图[2]放在下面,也为后来者提供一些方便,这张图很清晰地讲解了dup,dup2以及管道的一些知识。想了解更详细的相关知识可以参考文章末尾的参考列表。




FAQ:为啥要再开一个进程来跑grep -v usr /etc/passwd ?父进程不也可以执行吗?


A:啊蚂蚁!在执行了execlp("/bin/grep", "grep", "-v", "usr","/etc/passwd", NULL);后,程序就会exit(0)了,如果是父进程在执行,那么父进程就退出了,因此要在execlp执行完成后继续执行,就必须f**k一个子进程出来,用子进程来运行execlp,好让老爹活着继续生娃。其他地方也是一样的。


FAQ:这段程序有没有考虑僵尸进程活着孤儿进程的情况啊?


A:没有。。 ( ̄ε(# ̄)。。让它们去吧。。。僵尸和孤儿们就交给init老大照看了。。。


PS:必须吐槽一下这道题的提示。给出exec的用法还不如告诉execlp的原型;dup2的用法提示还是错的,或者说有误导作用,明明是将第二个参数重定向到第一个参数,结果它的参数的意思是从dst到src,我的英语一般,但是dst是destination,src是source,我还是知道的,提示起到了南辕北辙的作用;等待子进程结束就更加坑爹了,直接告诉做题者用wait(NULL);不就行了。


说白了,这个提示,懂的人不看也懂,不懂的人看了也不懂。


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Android中使用Monkey进行UI或应用.. 下一篇Android开发教程:搜索关键字飞入..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: