mybash的实现

Posted wyb-1998

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mybash的实现相关的知识,希望对你有一定的参考价值。

mybash的实现

题目要求
1.使用fork,exec,wait实现mybash

2.写出伪代码,产品代码和测试代码

3.发表知识理解,实现过程和问题解决的博客(包含代码托管链接)

fork()

man -k fork命令
技术分享图片

man 2 fork
技术分享图片

fork函数:

#include <sys/types.h>
#include <unistd.h>

pid_t fork(void);

//返回:子进程返回0,父进程返回子进程的PID,如果出错,则返回-1。

一般来说,运行一个C程序直到该程序全部结束,系统只会分配一个PID给这个程序,也就是说,系统里只有一条关于这个程序的进程。但执行了fork函数就不同了。fork()的作用是复制当前进程(包括进程在内存的堆栈数据),然后这个新的进程和旧的进程一起执行下去。而且这两个进程是互不影响的

代码

#include <sys/types.h>
#include <unistd.h>
 int main(){  
        printf("step 1

");  
      
        fork();//创建一个新的进程
      
        printf("after fork()

");  
      
        int i; scanf("%d",&i);//防止程序退出  

        return 0;  
    }  

exec

man -k program | grep execute命令
技术分享图片

man -k execute命令
技术分享图片

exec的参数分成3个部分:执行文件,命令参数,和环境变量。

假如要执行:ls -l /etc

执行文件部分就是:"/usr/bin/ls"
命令参数部分就是:"ls","-l","/etc",NULL
环境变量部分:这是1个数组,最后的元素必须是NULL 例如:char * env[] = {"PATH=/etc", "USER=vivian", "STATUS=testing", NULL};
命名规则如下:

e:参数必须带环境变量部分,环境变量部分参数会成为执行exec函数期间的环境变量;

l:命令参数部分必须以"," 相隔, 最后1个命令参数必须是NULL;

v:命令参数部分必须是1个以NULL结尾的字符串指针数组的头部指针。例如char * pstr就是1个字符串的指针, char * pstr[] 就是数组了, 分别指向各个字符串;

p:执行文件部分可以不带路径, exec函数会在$PATH中找。

代码

#include <unistd.h>  
  
int main()  
{  
        char *argv[] = {"ls", "-l", ".", (char *)0};  
        printf("···Begin to Show ls -l···
");
        execvp("ls", argv);  
        printf("···ls -l is done! ···");
        return 0;  
}

wait()

一个进程可以通过调用wait函数来等待它的子进程终止或者停止。

man -k wait
技术分享图片

man 2 wait
技术分享图片

wait()的使用方法可以用下面的代码表示:

#include <sys/types.h>
#include <unistd.h>

pid_t wait(int *status);

//返回:如果成功,则返回子进程的PID,如果出错,则返回-1。

父进程一旦调用了wait就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。

wait()要与fork()配套出现,如果在使用fork()之前调用wait(),wait()的返回值则为-1,正常情况下wait()的返回值为子进程的PID。

如果先终止父进程,子进程将继续正常进行,只是它将由init进程(PID 1)继承,当子进程终止时,init进程捕获这个状态。

编程实现mybash

伪代码如下

int main(){
读取要执行的命令
使用fork()函数产生子进程进行执行
如果exec函数产生了返回值,表明没有正常执行命令,输出perro()
父进程等待子进程结束,并输出值wait(&rtn) 

}
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>

void main()
{
        
    char *command[3];
    command[0] = "ls";
    command[1] = "-l";
    command[2] = 0;
        
        int s,i=0;
        int rtn; 
        printf( ">" );
    //printf("%s %s %s",command[1],command[2],command[3]);  
    printf("%s",command[0]);
    i=0;    
    s=fork();
    if ( s== 0 ) {
    //printf("%d
",s);
    execvp( command[0], command );
    
    //perror( command );
    
    exit( errno );
     }
     else {
    
    //printf("%d
",s);

    wait ( &rtn );
    
    printf( " child process return %d
", rtn );
    
    }
    
    
    }

技术分享图片











以上是关于mybash的实现的主要内容,如果未能解决你的问题,请参考以下文章

mybash的实现

20165324_mybash的实现

20165322 第七周 mybash 的实现

20165223 《信息安全系统设计基础》 实现mybash

mybash的实现

20165220 mybash