tail exec不';t在管道中工作良好(在母工艺模具之前没有输出!) #包括 #包括 #包括 #包括 #包括 #包括 #包括 int-pipFd[1000][2],hasPipe,forked,pipNum=0,pNum=0,bPipe=0,bpipFd[2],stPipe,InpToChld=0; pid_t pid[1000]; void*outip; int内置命令(字符**argv) { 如果(!strcmp(argv[0],“quit”)/*quit命令*/ 出口(0); 如果(!strcmp(argv[0],“&”)/*忽略单例&*/ 返回1; 返回0;/*不是内置命令*/ } int parsecmd(字符*buf,字符**argv) { char*delim;/*指向第一个空格分隔符*/ int argc;/*arg的数量*/ int bg;/*后台作业*/ buf[strlen(buf)-1]='';/*用空格替换尾随的'\n'*/ while(*buf&&(*buf=='')/*忽略前导空格*/ buf++; /*构建argv列表*/ argc=0; 而((delim=strchr(buf.)) { argv[argc++]=buf; *delim='\0'; buf=delim+1; 而(*buf&&(*buf==“”| |*buf==”

tail exec不';t在管道中工作良好(在母工艺模具之前没有输出!) #包括 #包括 #包括 #包括 #包括 #包括 #包括 int-pipFd[1000][2],hasPipe,forked,pipNum=0,pNum=0,bPipe=0,bpipFd[2],stPipe,InpToChld=0; pid_t pid[1000]; void*outip; int内置命令(字符**argv) { 如果(!strcmp(argv[0],“quit”)/*quit命令*/ 出口(0); 如果(!strcmp(argv[0],“&”)/*忽略单例&*/ 返回1; 返回0;/*不是内置命令*/ } int parsecmd(字符*buf,字符**argv) { char*delim;/*指向第一个空格分隔符*/ int argc;/*arg的数量*/ int bg;/*后台作业*/ buf[strlen(buf)-1]='';/*用空格替换尾随的'\n'*/ while(*buf&&(*buf=='')/*忽略前导空格*/ buf++; /*构建argv列表*/ argc=0; 而((delim=strchr(buf.)) { argv[argc++]=buf; *delim='\0'; buf=delim+1; 而(*buf&&(*buf==“”| |*buf==”,c,linux,unix,io,pipe,C,Linux,Unix,Io,Pipe,编写一个小shell的步骤: 句柄SIGCHLD 如有必要,处理重定向 如有必要,处理管道 以下code无法工作,无法处理内置命令: #include <sys/types.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <string.h> #include <signal.h>

编写一个小shell的步骤:

  • 句柄
    SIGCHLD
  • 如有必要,处理
    重定向
  • 如有必要,处理管道
  • 以下
    code
    无法工作,无法处理内置命令:

    #include <sys/types.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <string.h>
    #include <signal.h>
    
    int pipFd[1000][2], hasPipe, forked, pipNum = 0, pNum = 0, bPipe = 0, bpipFd[2], stPipe, InpToChld = 0;
    pid_t pid[1000];
    void * outInp;
    
    int builtin_command(char **argv)
    {
        if (!strcmp(argv[0], "quit")) /* quit command */
            exit(0);
        if (!strcmp(argv[0], "&")) /* Ignore singleton & */
            return 1;
        return 0; /* Not a builtin command */
    }
    int parsecmd(char *buf, char **argv)
    {
        char *delim;                  /* Points to first space delimiter */
        int argc;                     /* Number of args */
        int bg;                       /* Background job? */
        buf[strlen(buf) - 1] = ' ';   /* Replace trailing '\n' with space */
        while (*buf && (*buf == ' ')) /* Ignore leading spaces */
            buf++;
    
        /* Build the argv list */
        argc = 0;
        while ((delim = strchr(buf, ' ')))
        {
            argv[argc++] = buf;
            *delim = '\0';
            buf = delim + 1;
            while (*buf && (*buf == ' ' || *buf == '<')) /* Ignore spaces */
                buf++;
        }
        argv[argc] = NULL;
    
        if (argc == 0) /* Ignore blank line */
            return 1;
    
        /* Should the job run in the background? */
        if ((bg = (*argv[argc - 1] == '&')) != 0)
            argv[--argc] = NULL;
    
        return argc;
    }
    
    void myExec(char **argv, char *buf)
    {
        // if ((pid[pNum] = fork()) == 0)
        // {
            strcpy(buf, "/bin/");
            buf[5] = 0;
            strcat(buf, argv[0]);
            //printf("%s\n", buf);
            if (execv(buf, argv) < 0)
            {
                memset(buf, 0, 255);
                strcpy(buf, "/usr/bin/");
                strcat(buf, argv[0]);
    
                if (execv(buf, argv) < 0)
                {
                    printf("exec failed\n");
                    exit(-1);
                }
            }
            exit(0);
        // }
        // else
        //     wait(NULL);
    }
    
    int splitPipe(char **cmdLine)
    {
        static char *svBuftok;
    
        if (!hasPipe)
            *cmdLine = strtok_r(*cmdLine, "|", &svBuftok);
        else{
        //printf("--------%s\n", svBuftok);
            *cmdLine = strtok_r(svBuftok, "|", &svBuftok);
        }
        //printf(".......................%s %s\n", svBuftok, *cmdLine);
        return strlen(svBuftok);
    }
    
    int isDigit(char * strings){
        int i, tmp = strlen(strings);
        for(i = 0; i < tmp; i++){
            if(strings[i] < '0' || strings[i] > '9') return 0;
        }
        return 1;
    }
    
    
    void handler(int sig)
    {
        if (sig == SIGINT && forked) exit(0);
    }
    
    static char *getcmd()
    {
        static char buf[256];
    
        //fputs("> ", stdout);
        //printf("asdfasdfasdf\n");
        fflush(stdin);
        fflush(stdout);
        if (fgets(buf, sizeof(buf), stdin) == NULL)
            return NULL;
    
        if (buf[strlen(buf)] == '\n')
            buf[strlen(buf)] = 0;
    
        return buf;
    }
    
    int main()
    {
    
        char *cmdline;
        char *argv[12000];
        char c, dir[256], buf[256], rdBuf[100000], pipBuf[100000];
        int status, fd, rfd, dest, argc;
        pid_t tmpPid;
        getcwd(dir, 256);
        signal(SIGINT, handler);
        signal(SIGTSTP, handler);
        signal(SIGCHLD, handler);
        signal(30, handler);
        //outInp = &&Outinp;
    //printf("gd\n");
        while (cmdline = getcmd())
        {
    ret:
            do
            {
                rfd = 0;
                hasPipe = splitPipe(&cmdline);
                //printf(":::::::::::::::%s %d\n", cmdline, hasPipe);
                if (strlen(cmdline) <= 1)
                    continue;
                argc = parsecmd(cmdline, argv);
                if (!builtin_command(argv))
                {
                    if(!strcmp(argv[0], "exit")) exit(0);
                    {
                        if(hasPipe) pipe(pipFd[pNum]);
                        if(!bPipe) pipe(bpipFd);
                        fflush(NULL);
                        if((pid[pNum] = fork()) == 0){
                            int ofd, svStdout = dup(1), svStin = dup(0);
                            forked = 1;
                            close(pipFd[pNum][0]);
                            //printf("%s %d\n",argv[0], getpid());
                            //fflush(stdout);
                            //printf("\n");
                            if(bPipe) {
                                close(pipFd[pNum - 1][1]);
                                dup2(pipFd[pNum - 1][0], STDIN_FILENO); 
                            }
                            else{
                                close(bpipFd[1]);
                                dup2(bpipFd[0], STDIN_FILENO);
                            }
    
                            //addArgv(pipBuf, &argc, argv);
                            if(hasPipe) dup2(pipFd[pNum][1], 1);
    
                            if(!strcmp(argv[argc - 2], ">")){
                                //printf("chked %s\n", argv[argc - 1]);
                                remove(argv[argc - 1]);
                                ofd = open(argv[argc - 1], O_WRONLY | O_CREAT, 0755);
                                dup2(ofd, 1);
                                argc -= 2;
                                argv[argc] = NULL;
                            }
                            else if(!strcmp(argv[argc - 2], ">>")){
                                //printf("chked %s\n", argv[argc - 1]);
                                ofd = open(argv[argc - 1], O_WRONLY);
                                dup2(ofd, 1);
                                argc -= 2;
                                argv[argc] = NULL;
                            }
    
                            fflush(stdout);
                                myExec(argv, buf);
    
                            close(pipFd[pNum][1]);
    
                            if(bPipe) {
                                close(pipFd[pNum - 1][0]);
                            }
                            else{
                                close(bpipFd[0]);
                            }
                            dup2(svStin, 0);
                            dup2(svStdout, 1);
                            if(!strcmp(argv[argc - 2], ">")) close(ofd);
                            exit(0);
                        }
                        else{
                            if(!bPipe) {
                                close(bpipFd[0]);
                                stPipe = pid[pNum];
                                InpToChld = 1;
                            }
                            pNum++;
    
                        }
                    }
    
                    bPipe = hasPipe;
                }
            }while (hasPipe);
            while(InpToChld){
                memset(rdBuf, 0, sizeof(rdBuf)); int i;
                fflush(NULL);
                //printf("Inp~~\n");
                if(read(0, rdBuf, sizeof(rdBuf)) == 0){
                    write(bpipFd[1], "\0", 1);
                    InpToChld = 0;
                    break;
                }
    
                if(write(bpipFd[1], rdBuf, strlen(rdBuf)) < 0){
                    cmdline = rdBuf;
                    InpToChld = 0;
                    goto ret;
                }
                fflush(NULL);
                    //fflush(stdout);
            }
        }
    }
    
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    无效信号信号手柄(内部信号){
    while(waitpid(-1,NULL,WNOHANG)>0)
    ;
    }
    int main()
    {
    char-buf[256];
    while(fgets(buf,sizeof(buf),stdin)!=NULL){
    如果(fork()>0){//parent
    等待(空);
    继续;
    }
    //孩子
    //手柄信号
    结构动作法;
    act.sa_handler=信号_信号_handle;
    sigemptyset(和act.sa_面具);
    act.sa_flags=sa_重启;
    sigaction(SIGCHLD,&act,NULL);
    如果(buf[strlen(buf)]='\n')
    buf[strlen(buf)]='\0';
    for(char*next_cmd=strtok(buf,“|”);next_cmd!=NULL;){
    char*current\u cmd=next\u cmd;
    next_cmd=strtok(NULL,“|”);
    char*argv[10];
    int argv_指数=0;
    int new_argv=1;
    对于(;;){
    如果(*current_cmd=='\0'){
    argv[argv_index]=NULL;
    打破
    }
    如果(isspace(*当前命令)){
    *当前_cmd++='\0';
    新的_argv=1;
    继续;
    }
    如果(*当前命令==''){
    int add=0;
    如果(*++current_cmd=='>'){
    加法=1;
    ++当前命令;
    }
    while(isspace(*当前命令))
    ++当前命令;
    如果(*current_cmd=='\0'){
    printf(add==0?“请使用cmd>文件名”:“请使用cmd>>文件名”);
    返回-1;
    }
    char*filename=current\u cmd;
    而(!isspace(*current_cmd)&&*current_cmd!='\0')
    ++当前命令;
    如果(*current_cmd!='\0')
    *当前_cmd++='\0';
    int fd=open(文件名,add==0?(O_WRONLY | O|u CREAT):(O_WRONLY | O|u CREAT | O|u APPEND),0644);
    如果(fd<0){
    perror(add==0?“>”:“>>”;
    返回-1;
    }
    dup2(fd,1);
    关闭(fd);
    继续;
    }
    if(new_argv==1){
    新的_argv=0;
    argv[argv_index++]=current_cmd;
    }
    ++当前命令;
    }
    如果(argv_索引==0)
    继续;
    if(next_cmd!=NULL){
    int pipe_fd[2];
    管道(管道);;
    如果(fork()==0){
    关闭(管道_fd[0]);
    dup2(管道fd[1],标准文件号);
    关闭(管道[1]);
    execvp(argv[0],argv);
    返回-1;
    }
    关闭(管道[1]);
    dup2(管道fd[0],标准文件号);
    关闭(管道[1]);
    继续;
    }
    execvp(argv[0],argv);
    }
    }
    返回0;
    }
    
    如果不是重复的话,也与之相关。这个问题也是我的问题。我的问题没有解决,我写这篇文章是因为我得到了更详细的问题。感谢您的关注!缺少。您应该显示一个我们(您问题的读者)可以看到的最小代码可以在我们的计算机上编译您可能忘了在某个地方关闭文件描述符。tail怎么知道在父级结束之前的最后一行是什么?OMG!!!非常感谢!!!在您给出此代码之前,我不知道sigaction结构…如果没有您,我将无法解决此问题…再次非常感谢。。
    #include <ctype.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <unistd.h>
    
    void signal_SIGCHLD_handle(int sig) {
        while (waitpid(-1, NULL, WNOHANG) > 0)
            ;
    }
    
    int main()
    {
        char buf[256];
    
        while (fgets(buf, sizeof(buf), stdin) != NULL) {
            if (fork() > 0) { // parent
                wait(NULL);
                continue;
            }
            //child
            // handle SIGCHLD
            struct sigaction act;
            act.sa_handler = signal_SIGCHLD_handle;
            sigemptyset(&act.sa_mask);
            act.sa_flags = SA_RESTART;
            sigaction(SIGCHLD, &act, NULL);
    
            if (buf[strlen(buf)] == '\n')
                buf[strlen(buf)] = '\0';
    
            for (char* next_cmd = strtok(buf, "|"); next_cmd != NULL; ) {
                char* current_cmd = next_cmd;
                next_cmd = strtok(NULL, "|");
    
                char* argv[10];
                int argv_index = 0;
                int new_argv = 1;
                for (;;) {
                    if(*current_cmd == '\0') {
                        argv[argv_index] = NULL;
                        break;
                    }
                    if (isspace(*current_cmd)) {
                        *current_cmd++ = '\0';
                        new_argv = 1;
                        continue;
                    }
                    if (*current_cmd == '<') {
                        ++current_cmd;
                        while (isspace(*current_cmd))
                            ++current_cmd;
                        if (*current_cmd == '\0') {
                            printf("Please use cmd < file_name");
                            return -1;
                        }
                        char* filename = current_cmd;
                        while (!isspace(*current_cmd) && *current_cmd != '\0')
                            ++current_cmd;
                        if (*current_cmd != '\0')
                            *current_cmd++ = '\0';
                        int fd = open(filename, O_RDONLY);
                        if (fd < 0) {
                            perror("<");
                            return -1;
                        }
                        dup2(fd, 0);
                        close(fd);
                        continue;
                    }
                    if (*current_cmd == '>') {
                        int add = 0;
                        if (*++current_cmd == '>') {
                            add = 1;
                            ++current_cmd;
                        }
                        while (isspace(*current_cmd))
                            ++current_cmd;
                        if (*current_cmd == '\0') {
                            printf(add == 0 ? "Please use cmd > file_name" : "Please use cmd >> file_name");
                            return -1;
                        }
                        char* filename = current_cmd;
                        while (!isspace(*current_cmd) && *current_cmd != '\0')
                            ++current_cmd;
                        if (*current_cmd != '\0')
                            *current_cmd++ = '\0';
                        int fd = open(filename, add == 0 ? (O_WRONLY|O_CREAT) : (O_WRONLY|O_CREAT|O_APPEND), 0644);
                        if (fd < 0) {
                            perror(add == 0 ? ">" : ">>");
                            return -1;
                        }
                        dup2(fd, 1);
                        close(fd);
                        continue;
                    }
                    if (new_argv == 1) {
                        new_argv = 0;
                        argv[argv_index++] = current_cmd;
                    }
                    ++current_cmd;
                }
                if (argv_index == 0)
                    continue;
                if (next_cmd != NULL) {
                    int pipe_fd[2];
                    pipe(pipe_fd);
                    if (fork() == 0) {
                        close(pipe_fd[0]);
                        dup2(pipe_fd[1], STDOUT_FILENO);
                        close(pipe_fd[1]);
                        execvp(argv[0], argv);
                        return -1;
                    }
                    close(pipe_fd[1]);
                    dup2(pipe_fd[0], STDIN_FILENO);
                    close(pipe_fd[1]);
                    continue;
                }
                execvp(argv[0], argv);
            }
        }
        return 0;
    }