【问题标题】:use exec with a command typed from keyboard将 exec 与从键盘键入的命令一起使用
【发布时间】:2015-06-26 15:39:14
【问题描述】:

我创建了一个字符串数组来为命令添加属性(例如ls -l),但exec 命令需要一个字符数组,我该如何解决?这段代码应该创建一个执行输入选择的命令的子进程。当pid != 0 时,我什至对wait() 有一些问题。你能帮我完成它吗?非常感谢。

int main(void) {

        char array[100];
        char character;
        int i = 0;
        char* point;
        int j = 0;

        printf ("Digit a string");
        printf ("\n");
        do {
            character = getchar();
            array[i] = character;
            i++;
        }
        while (character != '\n');
        array[i-1] = '\0';
        i = 0;

        char* string[100];

        char *word = strtok(array, " .");
        while (word != NULL) {
            printf("%s\n", word);
            string[j] = word;
            word = strtok(NULL, " .");

        }

        printf ("\n");  

    pid_t  pid;
    pid = fork();

        if (pid == -1) {

        perror("");

    }else if (pid == 0) {

        if (execlp(string, NULL) < 0) {     /* execute the command  */

                    exit(1);
            }
      else {

        //.. wait until the child ends
        wait(pid);



      }
   }
    return;
}

【问题讨论】:

  • 您为什么不尝试阅读wait() 的联机帮助页?这应该很容易回答您的部分问题。

标签: c exec system-calls pid


【解决方案1】:

您的大问题是您没有正确使用execlpexeclp 接受可变数量的参数,这些参数是传递给程序的参数。预计会这样工作:

execlp("ls", "ls", "-l", NULL);

您拥有的是一组参数,因此您想使用 exec 的 v 变体之一。您可以找到所有变体here。所以你想要做的更像是这样的:

execvp(string[0], string);

请注意,命令本身是两个示例中的参数之一。您的程序的另一个问题是您没有在使用strtok 的循环中增加j。另请注意,对于execvp,数组的最后一个元素应该是NULL,因此 exec 知道它找到了最后一个参数。最后一件事是您不必检查任何exec 函数的返回值。如果exec 返回,则表示有错误,否则永远不会返回。 errnoexec 失败时设置,因此您可以检查它。为完整起见,请参阅以下带有 cmets 的更正代码部分:

char *word = strtok(array, " .");
j = 0;
while (word != NULL) {
  printf("%s\n", word);
  string[j++] = word; // Increment j
  word = strtok(NULL, " .");
}
string[j] = NULL; // Make sure the array is NULL terminated

你打电话给exec

execvp(string[0], string); // You most likely want execvp, execv would work as 
                           // well but that takes an entire path and not a filename
fprintf(stderr, "Failed to exec"); // If the program reached this point we know exec failed
exit(1);

让我更详细地解释他在execvp 的评论。名称中带有pexec 变体采用文件名而不是路径。这些变体将模仿 shell 的工作方式并使用PATH 环境变量来查找二进制文件。因此,如果您执行execlp("ls", "ls", "-l", NULL); 之类的操作,假设您在PATH 指定的文件夹之一中有ls,它将起作用。如果您执行execl("ls", "ls", "-l", NULL);(不是缺少p),它将失败,因为"ls" 不是有效路径;它必须是类似"/usr/bin/ls" 的东西。您想要哪个版本,采用文件名或文件路径,取决于您的应用程序。

【讨论】:

  • 非常感谢 esm!现在代码完美运行!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多