c - 尝试在 C 中将 execvp() 与 unix 中的用户输入一起使用

标签 c unix segmentation-fault execvp

我正在尝试编写一个程序来提示用户输入命令,然后使用 exec 来执行该命令。

例如,如果他们给我“ls -la”,我将不得不执行该命令。我尝试了以下代码:

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

int main()
{

    int ret, num_args;

    printf("Enter number of arguments (Example: \"ls -la\" has 1 argument): ");
    scanf("%d", &num_args);

    char *cmd[num_args];

    printf("Enter command name: ");
    scanf("%s", &cmd[0]);

    int i;
    for (i = 0; i < num_args; i++)
    {
            printf("Enter parameter: ");
            scanf("%s", &cmd[i]);
    }

    execvp(cmd[0], cmd);
}

但是,当我尝试以下运行时,它给了我一个“段错误”

$ ./a.out 
Enter number of arguments (Example: "ls -la" has 1 argument): 2
Enter command name: ls
Enter parameter: -la
Enter parameter: .
Segmentation fault
$

有什么想法吗?

最佳答案

如果您的实现支持它,您应该使用更安全的 getline() 而不是 scanf()fgets()getline() 将安全地处理长行和 NULL 字符。它将分配足够的内存来容纳整行。 getline() 可以分配内存,因此您稍后必须自己释放它。

这是 glibc getline() documentation .

这里是一个使用 getline 的快速修改(它仍然需要工作,错误检查,我还没有完全检查它的正确性):

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

int main()
{

    printf("Enter number of arguments (Example: \"ls -la\" has 1 argument): \n");

    char *num = NULL;
    size_t sz = 0;
    getline(&num, &sz, stdin);

    int num_args;
    sscanf(num, "%d", &num_args);

    char *cmd[num_args+2];
    memset(cmd, 0, sizeof(char*) * (num_args+2));

    printf("Enter command name: \n");


    int len = getline(&cmd[0], &sz, stdin); 

    cmd[0][len-1] = '\0';

    int i;
    for (i = 1; i < num_args+1; i++)
    {
        printf("Enter parameter: \n");
        sz = 0;
        len = getline(&cmd[i], &sz, stdin);
        cmd[i][len-1] = '\0';
    }

    return execvp(cmd[0], cmd);

}

关于c - 尝试在 C 中将 execvp() 与 unix 中的用户输入一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1319964/

相关文章:

将二维数组 C 代码转换为 malloc

linux - unix格式化输出变量

c - 使用+2.000.000.000长数组时,我的代码崩溃。如何解决此段错误?

c - 段错误(核心转储)

c++ - 在预处理器语句中使用 C 函数

c - 在 LLVM 上引导语言

linux - CSV 文件 bash 脚本中的平均值

c - 段错误检查月份

c - 设置 printf 中提到的文本的宽度

bash - 使用 tr 删除特定字符串