簡體   English   中英

在C中制作shell

[英]making shell in C

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>

void exec(char **args){
    pid_t  pid;
    int status;
    if ((pid = fork()) < 0) {    
        printf("*** ERROR: forking child process failed\n");
        exit(1);
    }
    else if (pid == 0) {      
        if(execvp(args[0],args)<0)//{
            //printf("argv[0]=%s argv[1]=%s",args[0],args[1]);
            printf("**error in exec\n");
    }
    else {                                  
        while (wait(&status) != pid);
    }
}

void exec2(char **args, char *file){
    printf("file =%s\n",file);
    int fd;
    pid_t pid;
    int status;
    if ((pid = fork()) < 0) {    
        printf("*** ERROR: forking child process failed\n");
        exit(1);
    }

    else if (pid == 0) {   
        fd = open(file, O_RDWR | O_CREAT, (mode_t)0600);
        close(1);
        dup2(fd, 1);
        if(execvp(args[0],args)<0){
            printf("**error in exec");
        }

        else {  
            printf("\nhere\n");
            close(fd);                                
            while (wait(&status) != pid){
                fflush(stdout) ;
            }
    }
}
    close (fd);
}


void main(){
    char *command;
    char inp[512];
    char *filepath;
    size_t size=0;
    char *substr;
    char *args[512];
    command = (char *) malloc(sizeof(char *) * 512);
    int flag=0;
    int redirect=0;
    int i=0;
    while (1){
        printf("$ ");
        command = fgets(inp, 512/*sizeof(char *)*/, stdin);

        command[strlen(command)-1]='\0';

        if (strchr(command,'>')){
            redirect=1;
            strtok_r(command,">",&filepath);
        }

        size_t siz=4;
        //printf("command=%s\n",command);
        int i=0;
        while(1){
            //printf("i=%d\n",i);
            char *tok = strtok_r(command," ",&substr);
            if (tok==NULL){
                break;
            }
            args[i++] = tok;
/*              printf("tok=%s\n",tok);
            printf("len tok = %d\n",(int)strlen(tok));
            printf("command=%s\n",command);
            printf("substr=%s\n",substr);     
*/           command = substr;
    }

    //printf("args[0]=%s",args[0]);
    if (!strncasecmp(args[0],"exit",siz) || !strncasecmp(args[0],"quit",siz))
    {
        printf("\nBye\n");
        exit(0);
    }

    else if(strcmp(args[0],"cd")==0){
        chdir(args[1]);
        //printf("chdir")   ;
        //system("pwd");
} 

else if (redirect==1){
    exec2(args,filepath);
}

else exec(args);
}
}

好的,這是我的shell代碼。 當我運行它時,我把ls和它給出正確的輸出。 然后我把ls -l然后ls再次給它:

ls: cannot access : No such file or directory

另外當我使用cdls不提供輸出,而pwd說:

"ignoring unused arguments"

cat也不起作用。 雖然mkdirpsls -l有效。

我在你的代碼中看到了一些問題,首先你為command分配了超過512的方法,因為你使用了sizeof(char*) ,這很可能是4:

command = (char *) malloc(sizeof(char*) * 512);

相反,使用sizeof(char)並且你不應該轉換malloc的結果,它背后有一些邏輯,但它可能是一個偏好問題,我個人不這樣做:

command = malloc(sizeof(char) * 512);

其次,你沒有正確使用strtok_r ,第一次你調用它傳遞字符串,隨后的時間,你傳遞NULL所以它應該是:

char *tok = strtok_r(command, " ", &substr);
while(tok){
    args[i++] = tok;
    tok = strtok_r(NULL, " ", &substr);
}

最后,這是主要問題,最后一個參數需要為NULL

args[i] = 0;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM