Linux execve - 没有这样的文件或目录?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10158782/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 05:47:24  来源:igfitidea点击:

execve - No such file or directory?

clinuxexecve

提问by theeggman85

I'm having some problems with execve. I'm trying to make a shell that can function just like the bash shell, but I have problems with the forked child executing a command. Here is what I have for the child. cmd is a char * with the command that the user typed in. However, when I run this program, I get this error from perror:

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

execve error: No such file or directory.

I have tried the program with a simple ls, and it should make path="/bin/ls" and execute it (I have confirmed this is where my ls command is) but it still complains. What am I doing wrong? Thanks!

我已经用一个简单的 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;
}

采纳答案by paxdiablo

The firstthing I would do would be to insert:

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

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

before the call to execve. That should confirm that the executable is what you think it is.

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

That code of yours looks okay as long asthe input you're feeding into it is correct and the executable actually isavailable. For example, the following complete program works fine on my Debian box:

只要您输入的输入正确并且可执行文件实际上可用,您的代码看起来可以。例如,以下完整程序在我的 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;
}

outputting, when I run ./testprog ls, something along the lines of:

当我运行时./testprog ls,输出如下内容:

[/bin/ls]
kidsshares.ods  paxwords    birthdays    homeloantracking.gnumeric
shares2011.ods  backup0.sh  development  lexar
accounts.ods    backup1.sh  photos       testprog.c
testprog

回答by iliis

If you don't want to manually travel through the fileystem to find the correct binary, there is execlp(with an additional p). From the manpage:

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

The execlp(), execvp(), and execvpe() functions duplicate the actions of the shell in searching for an executable file if the specified filename does not contain a slash (/) character. The file is sought in the colon-separated list of directory pathnames specified in the PATHenvironment variable. If this variable isn't defined, the path list defaults to the current directory followed by the list of directories returned by confstr(_CS_PATH). (This confstr(3) call typically returns the value "/bin:/usr/bin".) [...]

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