代码之家  ›  专栏  ›  技术社区  ›  DynamicApproach

提取exec函数的参数

  •  0
  • DynamicApproach  · 技术社区  · 3 年前

    我正试图为学校设计一个项目,我已经很接近了。目标是使用终端进行仿真,基本上是用管道输入一系列命令,并让它们正确执行。

    下面列出了我当前的代码和输出,但主要的要点是,到目前为止,我已经能够分离命令和参数,但是当试图在第83行使用strcat时,我感觉到出现了分段错误。

    我试图添加的行是:

        strcat (allargs, print);
    }
    printf("\n %s -- ALLARGS\n ", allargs);
    

    提取所有参数字符串的最佳方法是什么?由于我希望使用execvp或execlp,有没有更好的方法来实现这一点?

    谢谢

        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
        #include <ctype.h>
        #include <wait.h>
        #include <sys/types.h>
        #include <unistd.h>
        
        // count number of "|" in string
        int count_cmds(char *str)
        {
            int count = 1; // always will be 1 cmd
            for (int i = 0; i < strlen(str); i++)
            {
                if (str[i] == '|')
                {
                    count++;
                }
            }
            return count;
        }
        
        char *get_token_at(char *command, size_t n, char *delimiter)
        {
            size_t position = 0;
            char *copy = strdup(command);
            char *token = strtok(copy, delimiter);
            char *output = NULL;
            while (token && position < n)
            {
                token = strtok(NULL, delimiter);
                position++;
            }
            if (token && position == n)
                output = strdup(token);
            free(copy);
            return output;
        }
        
        // trim whitespace
        char *trimwhitespace(char *str)
        {
            char *end;
            while (isspace(*str))
                str++;
            if (*str == 0)
                return str;
            end = str + strlen(str) - 1;
            while (end > str && isspace(*end))
                end--;
            // new end of string
            *(end + 1) = 0;
            return str;
        }
        // count spaces in a string
        int count_spaces(char *str)
        {
            int count = 0;
            for (int i = 0; i < strlen(str); i++)
            {
                if (str[i] == ' ')
                {
                    count++;
                }
            }
            return count;
        }
        
        int fd[2];
        int x;
        int execc(char *command, int i)
        {
        
            printf("--- NEW CALL TO EXECC ---------------- COMMAND PASSED: %s \t\t\t\t\t\t ---- NUMBER PASSED: %d\n", command, i);
        
            char *text = trimwhitespace((get_token_at(command, i - 1, "|")));
            char *textargs = text;
            char *allargs = " ";
            for (int k = 0; k < count_spaces(textargs); k++)
            {
                char *print = trimwhitespace((get_token_at(textargs, k + 1, " ")));
                printf("\n %s -- TEXTARG\n ", print);
            }
            char *cmd_only = get_token_at(text, 0, " ");
            printf("\n %s -- cmd only\n ", cmd_only);
        
            int x = fork();
        
            if (x < 0)
            {
                perror("fork error");
                exit(1);
            }
            // parent
            if (x > 0)
            {
                printf("IN PARTENT -- wait for child\n");
                wait(&x);
                return x;
            }
            // child
            if (x == 0)
            {
                printf("NEW CHILD -- exec or call next \n");
                dup2(fd[0], STDIN_FILENO);
                if (i == 1)
                {
                    dup2(fd[1], STDOUT_FILENO);
                }
        
                close(fd[0]);
                close(fd[1]);
                if (i == 1)
                {
                    char *z1 = trimwhitespace((get_token_at(command, i - 1, "|")));
                    printf(" i=1 ---------------- \n%s\n %s \n %s ", z1, z1, trimwhitespace((get_token_at(command, i - 1, " "), NULL)));
                    // execlp(z1,z1, (trimwhitespace(get_token_at(command, i, " ")), NULL)); // if last command, exec
                }
                else
                {
                    execc(command, --i); // if not last command, recurse
                    char *z2 = trimwhitespace(get_token_at(command, i - 1, "|"));
                    printf("i!=1 --------------------\n%s\n %s \n %s ", z2, z2, trimwhitespace((get_token_at(command, i - 1, " "), NULL)));
                    // execlp(z2,z2, trimwhitespace((get_token_at(command, i, " "), NULL)));
                }
                // char* z3 = trimwhitespace(get_token_at(command, i-1, "|"));
                // printf("%s\n %s \n %s \n",z3,z3, trimwhitespace((get_token_at(command, i-1, " "), NULL)));
                // execlp(z3,z3, trimwhitespace((get_token_at(command, i, " "), NULL)));
            }
        }
        int main(int argc, char *argv[])
        {
            printf(" Enter Command>");
            char cmd[50];
            fgets(cmd, 50, stdin);
            int num_cmds = count_cmds(cmd);
            printf("\n");
            printf("Command count: %d\n", num_cmds);
            execc(cmd, num_cmds);
        
            pipe(fd);
            if (pipe(fd) == -1)
            {
                printf("Error pipe\n");
                exit(1);
            }
        }
    

    /当前输入命令>ls-l | sort-r | grep-h

    命令数:3 ---对EXECC的新调用------------------传递的命令:ls-l | sort-r | grep-h ----通过人数:3

    -h--TEXTARG

    grep--仅在PARTENT NEW CHILD中使用cmd ---对EXECC的新调用------------------传递的命令:ls-l | sort-r | grep-h ----通过人数:2

    -r--TEXTARG

    sort——仅在PARTENT NEW CHILD中使用cmd ---对EXECC的新调用------------------传递的命令:ls-l | sort-r | grep-h ----通过人数:1

    -l--TEXTARG

    ls--cmd仅在PARTENT NEW CHILD中使用

    1 回复  |  直到 3 年前
        1
  •  1
  •   dulngix    3 年前

    应该定义 allargs 作为字符数组,而不是指针,

    这样地:

    char allargs[64] = {0};