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

jam*_*mes 12 c path exec execve

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

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

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

  2. 是创建自己的.您可以在shell启动时复制environ并仅添加导出的变量

这与我在Stack Overflow上的以下帖子有关(阅读这篇文章将帮助您理解我想要做的事情):

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

我们对此非常困惑.我将再次解释我们现在要做的事情.与你的Linux shell如何做到这一点,我们需要编写自己的程序,可以设置环境变量,如PATH和USER以及用户想要定义的其他任何变量.

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

mysetenv dog spike
Run Code Online (Sandbox Code Playgroud)

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

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

Jon*_*ler 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;
}
Run Code Online (Sandbox Code Playgroud)

在这个例子中,程序将运行/bin/sh用参数-cenv,这意味着该壳将运行env它的当前PATH找到的节目.此处的环境设置为包含正统格式的5个值.如果更改envdate(或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
Run Code Online (Sandbox Code Playgroud)

shell添加了环境变量SHLVL,_以及PWD我在execve()调用中明确设置的变量.

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


Fre*_*rey 5

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

    setenv("dog", "spike", 1);
    extern char** environ;
    execve(argv[0], argv, environ);
Run Code Online (Sandbox Code Playgroud)

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

setenv()并进行putenv()修改environ,因此当您将其传递过来时execve(),环境变量将与您期望的一样。