【问题标题】:Issues with execvp() and incomplete multi-argument commandsexecvp() 和不完整的多参数命令的问题
【发布时间】:2019-03-23 16:34:11
【问题描述】:

我正在使用 execvp() 来运行一些系统调用。程序适用于有效命令,对于任何不存在的命令都失败,这是完美的。 该程序是,当我在需要额外参数(如 cat)并且我不提供参数的命令上使用 execvp() 时,程序只是从输入中无限读取。

我不确定如何解决这个问题,因为我不知道如何“判断”命令是否不完整。有什么想法吗?

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

int main(int argc, char* argv[]) {
        char command[1000];


        printf("Enter command: ");
        scanf("%[^\n]s", command);

        char *temp = strtok(command, " ");
        char *commandList[100];
        int index = 0;

        while (temp != NULL) {
                commandList[index] = temp;
                index++;

                temp = strtok(NULL, " ");
        }

        commandList[index] = NULL;

        execvp(commandList[0], commandList);

        printf("Failed");
}

理想的结果是打印“命令不完整”并且进程结束。

【问题讨论】:

  • 如果你启动的程序永远不需要从stdin读取,为什么不在execvp()之前关闭它?
  • 避免命令从stdin读取的常用方法是打开STDIN_FILENO/dev/null
  • @EOF — 不简单关闭标准输入的一个原因是程序有权假定标准输入、标准输出和标准错误已正确打开。重定向标准输入使其来自/dev/null 比简单地关闭标准输入要好得多。
  • 注意cat不需要任何额外的参数;当不带参数调用它时,它会在标准输入上读取到 EOF。它完全按照设计工作。最好在stderr而不是stdout上报告错误;最好在错误消息中包含失败的命令名称(以防用户认为他们输入的不是);最好用换行符 (fprintf(stderr, "Failed (%s)\n", commandList[0]);) 结束错误消息。
  • 哦,当程序失败时,它应该退出或返回一个非零退出代码(EXIT_FAILURE 来自&lt;stdlib.h&gt;,或者通常是1)。这让调用代码(shell 或其他)知道它没有成功。

标签: c exec system-calls


【解决方案1】:

评论中的一个想法完全回答了我的问题(满足我的确切需求)。不过,不知道如何在此表扬他。

解决方案是在我使用 execvp() 之前简单地关闭标准输入。如果第一次scanf没有完成命令,程序会抛出错误,完美。 由于我正在运行我在循环中使用它的主程序,我可以使用 dup 和 dup2 稍后保存和重新加载标准输入。

我用来测试它是否可以工作的代码:

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

int main(int argc, char* argv[]) {
        char command[1000];

        int stdinput = dup(STDIN_FILENO);

        close(STDIN_FILENO);

        dup2(stdinput, STDIN_FILENO);


        printf("Enter command: ");
        scanf("%[^\n]s", command);


        printf("%s\n", command);
}

【讨论】:

    猜你喜欢
    • 2014-03-20
    • 2014-10-23
    • 2021-11-26
    • 2020-12-30
    • 2021-03-16
    • 1970-01-01
    • 1970-01-01
    • 2019-06-21
    • 2021-01-02
    相关资源
    最近更新 更多