3

我遇到了一些关于 execve 的问题。我正在尝试制作一个可以像 bash shell 一样运行的 shell,但是我在分叉子执行命令时遇到了问题。这是我为孩子准备的。cmd 是带有用户输入的命令的字符 *。但是,当我运行此程序时,我从 perror 收到此错误:

execve error: No such file or directory.

我用一个简单的 ls 尝试了该程序,它应该使 path="/bin/ls" 并执行它(我已经确认这是我的 ls 命令所在的位置)但它仍然抱怨。我究竟做错了什么?谢谢!

if(pid == 0)
{
    // Parse the command
    char * word = strtok(cmd, " ");
    char path[128] = "/bin/";
    strcat(path, word);

    // Execute the process
    char * newenvp[] = { NULL };
    char * newargv[] = { path, NULL };
    ret = execve(path, newargv, newenvp);

    if(ret == -1)
        perror("execve error");

    return EXIT_SUCCESS;
}
4

2 回答 2

4

我要做的第一件事是插入:

printf ("[%s]\n", path);

在调用之前execve。这应该确认可执行文件是您认为的那样。

只要您输入的输入正确并且可执行文件实际可用,您的代码看起来可以了。例如,下面的完整程序在我的 Debian 机器上运行良好:

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

int main (int argc, char *argv[]) {
    if (argc > 1) {
        char * word = strtok (argv[1], " ");
        char path[128] = "/bin/";
        strcat (path, word);

        char * newenvp[] = { NULL };
        char * newargv[] = { path, NULL };
        printf ("[%s]\n", path);
        int ret = execve (path, newargv, newenvp);
        if (ret == -1) {
            perror("execve error");
        }
    }
    return 0;
}

当我运行时./testprog ls,输出类似于:

[/bin/ls]
kidsshares.ods  paxwords    birthdays    homeloantracking.gnumeric
shares2011.ods  backup0.sh  development  lexar
accounts.ods    backup1.sh  photos       testprog.c
testprog
于 2012-04-15T01:17:46.457 回答
1

如果您不想手动遍历文件系统以找到正确的二进制文件,则有execlp(带有额外的p)。从手册页:

如果指定的 文件名不包含斜杠 (/) 字符,则execlp ()、 execvp () 和execvpe () 函数会复制 shell 在搜索可执行文件时的操作。在PATH环境变量中指定的以冒号分隔的目录路径名列表中查找该文件。如果未定义此变量,则路径列表默认为当前目录,后跟 confstr(_CS_PATH) 返回的目录列表。(此 confstr(3) 调用通常返回值“/bin:/usr/bin”。) [...]

于 2012-05-17T14:30:33.807 回答