其实就是执行两个应用程序,中间用管道传递数据,在shell上面非常常见。之前面试的时候被问到过,知道大概怎么做,但是没有说太清楚,后面自己来做一遍。
发现如果自己没有实现的话,很多细节都是不明白的。
ps:当时要求不能用popen,那么只能自己利用pipe函数来实现大致流程了
先说一下大概流程
1. 生成一组管道fd1[2]
2. fork一个子进程
3. 在子进程将fd1[1] dup到标准输出
这里为何要这么做呢?就是为了父进程要从子进程提取命令产生的结果,就需要利用第1步产生的那组管道,而一般应用程序都是从标准输出返回结果的。
4. 在子进程调用execve簇函数执行需要执行的命令。
5. 在父进程读取fd1[0]的句柄读取从子进程返回的数据
上面是第一条命令的大致流程,而后我们利用第5步的结果继续调用第二个命令,流程都一样,但是这个时候需要多一组管道,用来将第一个程序返回的数据
传递给子程序,也就是在子进程fork之后把标准输入也重定向掉,这样子就能够把数据传递进去了。
虽然看起来简单,当时还是出过几个问题
1. 最初调用execve的时候,没有指定cat命令的绝对路径,导致execve执行失败,需要指定绝对路径
2.execve设置参数的时候,没有把argv[0]设置为程序命令路径,而是直接把a.txt放到argv[0]里面,自然是行不通的。这个问题其实很好理解,我们main函数argu的第一个
元素都是命令本身路径,只是我当时以为linux系统在execve函数会自己做这个事情,呵呵!
3. 在调用第二条命令的时候,需要在父进程通过管道写数据到子进程,但是写完了以后没有关闭管道句柄,导致子进程从重定向后的标准输入read的时候一直卡住,这个其实
很容易理解,linux的read函数如果读取的句柄是管道或者网络句柄的话,如果对端没有关闭,那么是会一直阻塞在那里的
代码就不贴了,因为只是自己玩的代码,里面其实有很多问题,贴上来怕误导别人!