linux c實現簡單shell

來源:互聯網
上載者:User
/*簡單的類比shell,可以執行帶一個輸入重新導向(或輸出重新導向或管道)命令,程式存在不完善之處,基本能用*/#include<stdio.h>#include<stdlib.h>#include<ctype.h>#include<string.h>#include<unistd.h>#include<fcntl.h>#include<sys/types.h>#include<sys/wait.h>#include<dirent.h>char command[100]; /*存放命令*/char argv[50][50]; /*存放分解後的命令*/int count;         /*命令分解後的個數*//*枚舉類型,依次表示一般命令,帶輸出重新導向命令,帶輸入重新導向命令,帶管道命令*/enum specify{NORMAL,OUT_REDIRECT,IN_REDIRECT,PIPE};/*函式宣告*/int analysis_command();int do_command();int find_command(char *command);/*主函數*/int main(){    while(1){        printf("$my_shell:");command[0]=0;        gets(command);        if(!analysis_command())   continue; do_command();    }    return 0;}/*解析命令*/int analysis_command(){    char *s=command;    int i=0,j=0,state=0;    strcat(command," ");    /*按空格為分隔字元將命令分隔開來,存放在argv中*/    while(*s){switch(state){           case 0:       if(!isspace(*s))   state=1;       else   s++;       break;   case 1:       if(isspace(*s)){   argv[i][j]='\0';   i++;   j=0;   state=0;       }else{   argv[i][j]=*s;   j++;       }       s++;       break;}    }    count=i;    if(count==0)return 0;    if(strcmp(argv[0],"logout")==0 || strcmp(argv[0],"exit")==0)exit(0);    /*判斷命令是否存在*/    if(!find_command(argv[0])){puts("error:can't find command");return 0;    }    return 1;   }/*執行命令*/int do_command(){    int i,j;    char* file;    char* arg[50];    char* arg2[50];    int f=0,back_run=0;    int fd,pid,fd2,pid2;    enum specify type=NORMAL;    for(i=0;i<count;i++){arg[i]=argv[i];    }    arg[i]=NULL;    if(strcmp(arg[count-1],"<")==0 || strcmp(arg[count-1],">")==0 || strcmp(arg[count-1],"|")==0){printf("error:command error\n");return 0;    }        for(i=0;i<count;i++){if(strcmp(arg[i],"<")==0){            f++;    file=arg[i+1];    arg[i]=NULL;    type=IN_REDIRECT;}else if(strcmp(arg[i],">")==0){    f++;    file=arg[i+1];    arg[i]=NULL;    type=OUT_REDIRECT;}else if(strcmp(arg[i],"|")==0){    f++;    type=PIPE;    arg[i]=NULL;    for(j=i+1;j<count;j++){arg2[j-i-1]=arg[j];    }    arg2[j-i-1]=NULL;    if(!find_command(arg2[0])){printf("error:can't find command\n");return 0;    }}    }    if(strcmp(arg[count-1],"&")==0){back_run=1;arg[count-1]=NULL;    }    if(f>1){printf("error:don't identify the command");return 0;    }    pid=fork();    if(pid<0){perror("fork error");        exit(0);    }else if(pid==0){/*在子進程裡*/        switch(type){            case NORMAL:execvp(arg[0],arg);        break;    case IN_REDIRECT:fd=open(file,O_RDONLY);dup2(fd,STDIN_FILENO);                execvp(arg[0],arg);break;    case OUT_REDIRECT:fd=open(file,O_WRONLY|O_CREAT|O_TRUNC,0666);dup2(fd,STDOUT_FILENO);execvp(arg[0],arg);break;    case PIPE:pid2=fork();if(pid2==0){    fd2=open("tempfile",O_WRONLY|O_CREAT|O_TRUNC,0600);    dup2(fd2,STDOUT_FILENO);    execvp(arg[0],arg);}else{    waitpid(pid2,NULL,0);    fd=open("tempfile",O_RDONLY);    dup2(fd,STDIN_FILENO);    execvp(arg2[0],arg2);}break;        }    }else{       if(!back_run)           waitpid(pid,NULL,0);    }    return 1;}/*尋找命令*/int find_command(char *command){    DIR *d;    struct dirent *ptr;    char temp[100];    char *dir;    /*獲得環境變數*/    char *path=getenv("PATH");    /*分隔環境變數,且依次尋找各個目錄看命令是否存在*/    strcpy(temp,path);    dir=strtok(temp,":");    while(dir){        d=opendir(dir);        while((ptr=readdir(d)) != NULL)    if(strcmp(ptr->d_name,command) == 0){closedir(d);return 1;    }closedir(d);dir=strtok(NULL,":");    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.