C 了解Exeve和设置环境变量的要求

C 了解Exeve和设置环境变量的要求,c,path,exec,execve,C,Path,Exec,Execve,我们在翻译老师时遇到了很多困难。我们要求澄清,并从他那里得到了以下信息 对于execve,将使用导出变量设置的环境发送给它,并创建一个内置命令来生成/bin/bash的子shell,这样您就可以使用env查看导出的变量 (他正在谈论创建我们自己的环境变量。) 是的,创造你自己的。您可以在shell启动时复制environ并只添加导出的变量 这与我的以下关于堆栈溢出的文章有关(阅读另一篇文章将帮助您理解我的意图): 我们只是对此感到非常困惑。我再解释一次我们现在要做什么。与LinuxShel

我们在翻译老师时遇到了很多困难。我们要求澄清,并从他那里得到了以下信息

  • 对于execve,将使用导出变量设置的环境发送给它,并创建一个内置命令来生成/bin/bash的子shell,这样您就可以使用env查看导出的变量

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

  • 是的,创造你自己的。您可以在shell启动时复制environ并只添加导出的变量

  • 这与我的以下关于堆栈溢出的文章有关(阅读另一篇文章将帮助您理解我的意图):

    我们只是对此感到非常困惑。我再解释一次我们现在要做什么。与LinuxShell类似,我们需要编写自己的程序,可以设置环境变量,如PATH和USER,以及用户想要定义的任何其他变量

    您将如何调用它的一个示例是(在程序的提示符下):

    这将创建一个看起来像“dog=spike”的环境变量


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

    这实际上非常简单。您已经知道,您的参数是由
    char*
    组成的列表,以空指针结尾。类似地,环境只是一个
    char*
    列表,由空指针终止。按照惯例,列表中的值采用
    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;
    }
    
    shell已将环境变量
    SHLVL
    \u
    PWD
    添加到我在
    execve()
    调用中显式设置的变量中


    您还可以做一些更有趣的事情,比如从真实环境中复制一些其他环境变量,这些变量不会与您想要显式设置的变量冲突。您还可以玩一些游戏,比如在环境中为一个变量设置两个值——哪一个会生效?您可以使用包含空格的变量名(shell不太喜欢)或与“varname=value”符号完全不匹配的条目(没有等号)玩游戏。

    Jonathan Leffler的代码非常有效,除非您想更改
    PWD
    (工作目录)变量

    为了更改工作目录,我所做的是在
    execve(…)
    之前放置一个
    chdir(…)
    ,并调用:

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

    我在这里参加聚会有点晚了,但是如果您想保留旧的环境变量并创建自己的环境变量,请使用
    setenv
    ,然后将
    environ
    传递给
    execve()

    environ
    是在
    unistd.h
    中声明的变量,它在运行过程中跟踪环境变量


    setenv()
    putenv()
    修改
    environ
    ,因此当您将其传递给
    execve()
    时,环境变量将与您预期的一样。

    您真的为我清除了所有这些。我已经把所有东西都交上来了,但是谢谢!我现在明白了。
    USER=beelzebub
    PATH=/bin:/usr/bin
    PWD=/Users/jleffler/tmp/soq
    TZ=UTC0
    SHLVL=1
    HOME=/
    LOGNAME=tarzan
    _=/usr/bin/env
    
    chdir("/foo/bar"); 
    execve(argv[0], &argv[0], envp);
    
        setenv("dog", "spike", 1);
        extern char** environ;
        execve(argv[0], argv, environ);