使用execve的新路径来运行ls命令

时间:2011-10-03 02:19:20

标签: c path exec execve

我正在尝试使用execve来运行ls命令。目前我正在使用以下参数运行它:

execve(args[0], args, env_args)
//args looks like {"ls", "-l", "-a", NULL}
//env_args looks like {"PATH=/bin", "USER=me", NULL}

我期望这样做是使用我的新env_args运行ls命令,这意味着它会在我的PATH中查找ls。但是,这段代码实际上没有做任何事情,当我运行代码时,它只返回我的命令提示符而没有输出。

使用相同的args []我使用execvp并且ls工作并搜索我当前的路径。

你能告诉我我做错了吗?

我想要做的是编写我自己的shell程序,在那里我可以创建和导出我自己的环境,并让exec使用我在char **中定义的环境。本质上我正在编写自己的函数来操作env_args来添加和删除变量,当我调用exec时我希望能够在{“ls”,“ - l”,NULL}上调用exec并让它看不起我的新环境名为ls的有效程序的路径变量。我希望这能解释我的工作做得更好。在这种情况下,我不认为extern environ var对我有用。

1 个答案:

答案 0 :(得分:10)

execve()不看PATH;为此,您需要execvp()。您的程序未能执行ls,显然您没有报告在execve()之后执行程序失败。请注意,exec*()函数族的成员仅在出错时返回。

如果您使用/bin作为当前目录运行程序(因为./ls - 又名ls - 将存在),您将得到预期的结果(或多或少)

在使用适当的PATH设置找到可执行文件后,需要在execve()的第一个参数中提供可执行文件的路径名。

或继续使用execvp(),但将变量environ设置为新环境。请注意environ现在(POSIX 2008)在<unistd.h>中声明,但以前未在任何地方声明。

extern char **environ;

environ = env_args;
execvp(args[0], &args[0]);

您无需保存旧值并将其恢复;你在子进程中并且切换它的环境不会影响主程序(shell)。


这似乎与我期望的一样 - 并且证明原始代码的行为与我期望的一样。

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

extern char **environ;

int main(void)
{
    char *args[]     = { "ls", "-l", "-a", NULL };
    char *env_args[] = { "PATH=/bin", "USER=me", NULL };

    execve(args[0], args, env_args);
    fprintf(stderr, "Oops!\n");

    environ = env_args;
    execvp(args[0], &args[0]);
    fprintf(stderr, "Oops again!\n");

    return -1;
}

我得到'糟糕!'然后列出我的目录。当我在当前目录中创建可执行文件ls时:

#!/bin/sh
echo "Haha!"

然后我没有得到'哎呀!'并得到'哈哈!'。