我从几个网站了解到这getenv
是一个系统调用。但我找不到任何参考资料sys_getenv
。
我试图了解“环境变量”到底是什么。它们是内核的一部分还是 shell 的机制?深入挖掘后,我发现它getenv
是标准 C 库的一部分。不幸的是,这无助于我回答我最初的问题。
答案1
你理解参数列表吗?例如,如果你输入ls -l foo bar
,shell 将/bin/ls
使用由四个字符串组成的参数列表执行:
ls -l foo bar
然而,如果你输入ls -l "foo bar"
(或ls -l 'foo bar'
或ls -l foo\ bar
),shell 将/bin/ls
使用由三个字符串组成的参数列表执行:
ls -l foo bar
可能ls -l *
会得到类似这样的结果:
ls -l ant bat cat dog etc
…即当前目录中的任何文件。
出色地,
环境基本上只是第二个参数列表。
也许这样说会更好:“环境是第二个字符串列表,其结构与参数列表完全相同,但处理方式不同。”如果你看一下执行(2),您会看到execve
系统调用接受三个参数:
- char *文件名, (要执行的程序;例如,
/bin/ls
) - 字符 *argv[],
- 字符 *envp[]
每当任何程序执行任何其他程序时,它基本上都在使用execve
(可能通过某些更高级的函数,例如execl
),因此它会传递一个参数列表和一个环境列表。环境列表看起来很像 的输出env
;例如,
HOME=/home/fred USERNAME=fred PATH=/bin:/usr/bin:… TERM=xterm SHELL=/bin/bash PWD=/home/fred/Super_User_files
ETC…
执行的程序可以对环境列表做任何它想做的事情 — 查看它(例如,使用getenv
)、修改它或忽略它 — 它可以对参数列表做同样的事情。当一个程序使用一个更高级别的执行函数(例如 )执行另一个程序时,execl
它会自动使用传递execve
给该程序的相同环境列表进行调用。这就是 90% 执行其他程序的程序中发生的情况。但是 shell 允许您修改环境,然后它们execve
直接使用 将最新的用户指定环境传递给它运行的每个程序。
总结
每个进程都在内存中包含其环境列表,就像它包含其参数列表和普通变量一样。环境通过该exec
机制在程序之间传递。库函数使程序可以轻松地将其自己的环境传递给它运行的任何其他程序。(当然,环境会在 中保存(复制)fork
,就像所有其他本地内存一样。)内核实际上对环境一无所知,除了它提供了一种通过 传递环境的方法execve
。
答案2
环境变量属于谁?
每个进程都有自己的环境变量。
笔记:
每个进程都有一个环境块,其中包含一组环境变量及其值。
环境变量从父进程继承,是父块的副本。
默认情况下,子进程继承其父进程的环境变量。
进程可以选择将不同的环境传递给子进程,方法是创建一个新的环境块并在创建时将其传递给子进程。
任何进程都不可能改变任何其他进程的环境变量。
getenv 是什么
getenv
是标准 C 库中的函数。
姓名
getenv, secure_getenv - 获取环境变量概要
#include <stdlib.h> char *getenv(const char *name); char *secure_getenv(const char *name);
glibc 的功能测试宏要求(参见 feature_test_macros(7)):
secure_getenv(): _GNU_SOURCE
描述
getenv() 函数搜索环境列表以查找环境变量名,并返回指向相应值字符串的指针。
GNU 特定的 secure_getenv() 函数与 getenv() 类似,只是在需要“安全执行”的情况下它会返回 NULL。
...
进一步阅读
“我试图了解‘环境变量’到底是什么。”
查看答案https://superuser.com/a/932191/337631经过斯科特从编码角度进行详细解释。
答案3
getenv
是标准 C 库的一部分。因此,在 C 中,您需要包含stdlib.h
。