将数组传递给用户输入的execvp()

cae*_*ean 8 c execvp

我正在尝试将用户输入的参数传递给execvp().

到目前为止,我已经拆分了字符串.如果用户键入ls -a,temp则保存为"ls"和"-a",后跟NULL字符.我不太确定如何恰当地指出这一点execvp.在我看到它使用的例子中execvp(temp[position], temp).我知道我现在尝试这样做的方式是错误的,但我不确定如何正确地做到这一点!目前我遇到了分段错误.

int main(int argc, char *argv[]) 
{
    char line[124];
    int size = 124;
    char *temp = NULL;

    while(fgets(line, size, stdin) != NULL ) {
        if (strcmp(line, "exit\n") == 0) {
            exit(EXIT_SUCCESS);
        }
        temp = strtok(line, " ");
        while (temp != NULL) {
            printf("%s\n", temp);
            temp = strtok(NULL, " ");
        }
        execvp(temp, &temp);    
    }
    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*ler 7

你的问题是它temp是一个单指针,你需要传递一个指针数组execvp().

就像是:

    enum { MAX_ARGS = 64 };
    char *args[MAX_ARGS];
    char **next = args;

    temp = strtok(line, " ");
    while (temp != NULL)
    {
        *next++ = temp;
        printf("%s\n", temp);
        temp = strtok(NULL, " ");
    }
    *next = NULL;
    execvp(args[0], args);
Run Code Online (Sandbox Code Playgroud)

请注意,参数列表已被赋予空指针作为终结符,就像argv[argc] == NULLmain().显然,我已经对错误检查不屑一顾(如果你传递超过63个参数,你将要溢出args数组).但这包含核心思想.


有了这个例子,我似乎无法得到的简单的命令ls来工作,我已经试过mkdirecho,他们似乎很好地工作.传递ls返回-1 execvp().

我不确定问题可能是什么 - 所有这些对我有用:

  • ls
  • ls -l
  • ls -l madump.c(madump.c恰好是我正在测试的目录中的文件)

我使用的代码是:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(void) 
{
    char line[1024];

    while (fgets(line, sizeof(line), stdin) != NULL)
    {
        if (strcmp(line, "exit\n") == 0)
            exit(EXIT_SUCCESS);

        char *args[64];
        char **next = args;
        char *temp = strtok(line, " \n");
        while (temp != NULL)
        {
            *next++ = temp;
            printf("%s\n", temp);
            temp = strtok(NULL, " \n");
        }
        *next = NULL;

        puts("Checking:");
        for (next = args; *next != 0; next++)
            puts(*next);

        execvp(args[0], args);
    }

    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

请注意,在创建名称末尾带有换行符的目录后,我添加\n到了strtok()令牌列表中.适合讨厌的朋友和令人困惑的半受教育的敌人,但从大多数其他角度来看都是令人讨厌的.请注意我是如何execvp()在实际执行之前打印出要传递的数据.通常,我会使用printf("<<%s>>\n", *next);而不仅仅是puts()明确指出参数的开始和结束位置.

运行命令(doit)的输出是:

$ ./doit
ls -l madump.c
ls
-l
madump.c
Checking:
ls
-l
madump.c
-rw-r--r--  1 jleffler  staff  2352 Jul 28  2011 madump.c
$
Run Code Online (Sandbox Code Playgroud)

你从你的版本得到了什么?