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

发布于 2024-12-08 09:19:15 字数 759 浏览 5 评论 0原文

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

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

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

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

这与我在 Stack Overflow 上的以下帖子相关(阅读其他帖子将帮助您了解我想要做什么):

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

我们对此感到非常困惑。我将再一次解释我们现在正在尝试做的事情。与 Linux shell 的执行方式类似,我们需要编写自己的程序来设置 PATH 和 USER 等环境变量以及用户想要定义的任何其他变量。

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

mysetenv dog spike

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

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

We are having a lot of trouble interpreting our teacher. We asked for clarification and got the following back from him

  1. For execve, send it a environment you setup with your exported variables and create a builtin command to spawn a subshell of /bin/bash, that way you can see your exported variables using env.

    (He is talking about creating our own environment vars here.)

  2. Yes create your own. You can start by copying environ when your shell starts and add only exported variables

This is related to the following post on Stack Overflow by me (reading this other post will help you understand what I am trying to do):

using a new path with execve to run ls command

We are just very confused about this. One more time I will explain what we are trying to do now. Similar to how your Linux shell does this, we need to write our own program that can set environment variables like PATH and USER and whatever other vars the user wants to define.

An example of how you would call this would be (inside your program at its prompt):

mysetenv dog spike

which would create an environment variable looking like "dog=spike"

More importantly, we need to be able to set our own PATH variable and send it to an exec command. This is the confusing part because, based on all of our questions, we don't understand what we are supposed to do.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

奢欲 2024-12-15 09:19:15

其实很简单。您已经知道您的参数是一个 char * 列表,以 NULL 指针结尾。类似地,环境只是一个由 NULL 指针终止的 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;
}

在这个例子中,程序将运行带有参数 -cenv/bin/sh,这意味着shell 将运行在其当前路径中找到的 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”符号的条目(没有等号)来玩游戏。

It is actually very simple. You already know that your arguments are a list of char *, terminated by a NULL pointer. Similarly, the environment is simply a list of char *, terminated by a NULL pointer. Conventionally, the values in the list take the form VARNAME=var-value, though you can pass other formats if you wish.

So, to take a simple case:

#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;
}

In this example, the program will run /bin/sh with arguments -c and env, which means that the shell will run the env program found on its current PATH. The environment here is set to contain 5 values in the orthodox format. If you change env to date (or env; date), you will see the effect of the TZ setting, for example. When I run that on my MacOS X machine, the output is:

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

The shell has added environment variables SHLVL, _ and PWD to the ones I set explicitly in the execve() call.

You can also do fancier things, such as copy in some of the other environment variables from your genuine environment where they do not conflict with the ones you want to set explicitly. You can also play games like having two values for a single variable in the environment - which one takes effect? And you can play games with variable names that contain spaces (the shell doesn't like that much), or entries that do not match the 'varname=value' notation at all (no equals sign).

软糖 2024-12-15 09:19:15

我来晚了一点,但是如果您想保留旧的环境变量并创建自己的环境变量,请使用 setenv,然后将 environ 传递给execve()

    setenv("dog", "spike", 1);
    extern char** environ;
    execve(argv[0], argv, environ);

environ 是一个变量定义 单一 Unix 规范,它保留跟踪运行过程中的环境变量。

setenv()putenv() 修改 environ,因此当您将其传递给 execve() 时,环境变量将如您所期望的那样。

I'm a little late to the party here, but if you want to preserve the old environment variables as well as creating your own, use setenv, and then pass environ to execve().

    setenv("dog", "spike", 1);
    extern char** environ;
    execve(argv[0], argv, environ);

environ is a variable defined by the Single Unix Specification, which keeps track of the environment variables during this running process.

setenv() and putenv() modify environ, so when you pass it over execve(), the environment variables will be just as you'd expect.

提赋 2024-12-15 09:19:15

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

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

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

The code from Jonathan Leffler works great, except if you want to change the PWD (working directory) variable.

What I did, in order to change the working directory, was to put a chdir(..) before execve(..) and call:

chdir("/foo/bar"); 
execve(argv[0], &argv[0], envp);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文