了解执行和设置环境变量的要求

时间:2011-10-05 03:56:17

标签: c path exec execve

我们在解释老师方面遇到了很多麻烦。我们要求澄清并从他那里得到以下回复

  1. 对于execve,使用导出的变量向其发送一个环境,并创建一个内置命令来生成/ bin / bash的子shell,这样就可以使用env查看导出的变量。

    (他正在谈论在这里创建我们自己的环境变量。)

  2. 是创建自己的。您可以在shell启动时复制environ并仅添加导出的变量
  3. 这与我在Stack Overflow上的以下帖子有关(阅读这篇文章将帮助您了解我想要做的事情):

    using a new path with execve to run ls command

    我们对此非常困惑。我将再次解释我们现在要做的事情。类似于Linux shell的工作方式,我们需要编写自己的程序,可以设置PATH和USER等环境变量以及用户想要定义的其他变量。

    如何调用它的一个例子是(在程序中提示):

    mysetenv dog spike
    

    会创建一个环境变量,看起来像“dog = spike”

    更重要的是,我们需要能够设置自己的PATH变量并将其发送到exec命令。这是一个令人困惑的部分,因为基于我们所有的问题,我们不明白我们应该做什么。

3 个答案:

答案 0 :(得分:33)

实际上非常简单。您已经知道您的参数是char *的列表,由NULL指针终止。类似地,环境只是char *的列表,由NULL指针终止。通常,列表中的值采用VARNAME=var-value形式,但如果您愿意,也可以传递其他格式。

所以,举一个简单的案例:

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

int main(void)
{
    char *argv[] = { "/bin/sh", "-c", "env", 0 };
    char *envp[] =
    {
        "HOME=/",
        "PATH=/bin:/usr/bin",
        "TZ=UTC0",
        "USER=beelzebub",
        "LOGNAME=tarzan",
        0
    };
    execve(argv[0], &argv[0], envp);
    fprintf(stderr, "Oops!\n");
    return -1;
}

在此示例中,程序将使用参数/bin/sh-c运行env,这意味着shell将运行在其当前PATH上找到的env程序。此处的环境设置为包含正统格式的5个值。如果您将env更改为date(或env; date),您会看到TZ设置的效果。当我在MacOS X机器上运行时,输出为:

USER=beelzebub
PATH=/bin:/usr/bin
PWD=/Users/jleffler/tmp/soq
TZ=UTC0
SHLVL=1
HOME=/
LOGNAME=tarzan
_=/usr/bin/env

shell已将环境变量SHLVL_PWD添加到我在execve()调用中明确设置的变量。

您还可以执行更高级的操作,例如从真实环境中复制某些其他环境变量,这些环境变量与您要显式设置的环境变量不冲突。你也可以玩游戏,比如在环境中为一个变量设置两个值 - 哪一个生效?你可以玩包含空格的变量名称的游戏(shell不喜欢那么多),或者根本不匹配'varname = value'符号的条目(没有等号)。

答案 1 :(得分:4)

我在这里参加聚会的时间已经很晚,但是如果您想要保留旧的环境变量以及创建自己的环境变量,请使用setenv,然后将environ传递给{{ 1}}。

execve()

setenv("dog", "spike", 1); extern char** environ; execve(argv[0], argv, environ); environ中声明的变量,它在此运行过程中跟踪环境变量。

unistd.hsetenv()修改putenv(),因此当您将其传递给environ时,环境变量将与您期望的一样。

答案 2 :(得分:1)

来自 Jonathan Leffler 的代码效果很好,除非您想要更改PWD(工作目录)变量。

为了更改工作目录,我所做的是在chdir(..)之前加execve(..)并致电:

chdir("/foo/bar"); 
execve(argv[0], &argv[0], envp);