jam*_*mes 12 c path exec execve
我们在解释老师方面遇到了很多麻烦.我们要求澄清并从他那里得到以下回复
对于execve,使用导出的变量向它发送一个环境,并创建一个内置命令来生成/ bin/bash的子shell,这样就可以使用env查看导出的变量.
(他在谈论在这里创建我们自己的环境变量.)
这与我在Stack Overflow上的以下帖子有关(阅读这篇文章将帮助您理解我想要做的事情):
我们对此非常困惑.我将再次解释我们现在要做的事情.与你的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
用参数-c
和env
,这意味着该壳将运行env
它的当前PATH找到的节目.此处的环境设置为包含正统格式的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
Run Code Online (Sandbox Code Playgroud)
shell添加了环境变量SHLVL
,_
以及PWD
我在execve()
调用中明确设置的变量.
您还可以执行更高级的操作,例如从真实环境中复制某些其他环境变量,这些环境变量与您要显式设置的环境变量不冲突.你也可以玩游戏,比如在环境中为一个变量设置两个值 - 哪一个生效?你可以玩包含空格的变量名称的游戏(shell不喜欢那么多),或者根本不匹配'varname = value'符号的条目(没有等号).
我在这里参加聚会有点晚了,但是如果您想保留旧的环境变量并创建自己的环境变量,请使用setenv
,然后将其传递environ
给execve()
。
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()
,环境变量将与您期望的一样。