我一直在阅读Linux中的环境变量。我可以理解如何设置/读取它们。
我想问的是概念上为什么环境变量被添加到Linux?没有它们,是否存在无法实现的系统要求?
在我看来,由于某种原因,似乎需要一个额外的配置层,这与实际的流程功能分离。我想知道更有经验的开发人员的意见。
答案 0 :(得分:2)
环境变量[此处: env ]满足不能[方便]以其他方式处理的需求。
所以,我们问一个问题:程序如何获得每次调用时可能发生变化的配置数据?
我们可以将所有内容作为程序参数传递:pgmA PATH=... DISPLAY=...
但程序必须解析它。并且,当pgmA调用pgmB时,它必须将这些数据作为参数传递。换句话说,每个程序都必须知道每个变量,即使它对变量本身没用。
我们可以将所有内容放在配置文件中,但是每次调用我们都需要一个不同的文件。在哪里放置这些文件,如何保证它们具有唯一的名称,如何在不再需要时删除它们[即使面对中止的程序],也变得难以处理。
使用env变量,它们驻留在程序中,在程序执行时内核创建的特殊内存部分和std execvp
等。人。 (有一些内核帮助)会愉快地传递这个环境,而大多数程序都不需要做任何事情。
然而,pgmA在fork
之后,在execvp
之前的孩子中为pgmB更改某些内容(例如,向PATH
添加额外的目录)是自由的。换句话说,env在父母和孩子之间是等级的(例如,改变孩子不改变父母 - 一件好事)
env还允许传递低阶程序所需的东西。考虑pgmA fork/exec
s pgmB反过来fork/exec
s pgmC。 pgmA / pgmB只是普通的程序[并且不要使用任何 env变量本身]。但是pgmC是xterm
,需要知道输出的X11显示。它来自DISPLAY
env var。
考虑我们在窗口终端程序中从主GUI控制台运行上述内容。 DISPLAY
[可能]会:0
。 xterm
显示在本地屏幕上。现在考虑我们从ssh登录做同样的事情。此处DISPLAY
将为w.x.y.z:0
,xterm
将在本地计算机上执行,但会在远程系统的屏幕上显示。
环境的另一个主要用途是为没有[{1}}或配置文件[合法]访问权限的内容提供配置。即,共享库[argv
s]。以下是两个例子:
当内核执行ELF程序时,它会将可执行文件映射到内存中。然后它在“ELF加载器”的特殊部分中查找,在Linux下是(例如).so
。内核将加载程序映射到应用程序内存中,并将程序的控制权转交给加载程序。反过来,加载器解析对程序所需的共享库的引用和加载,然后将控制转移到程序的 start 函数。
/lib64/ld-linux-x86-64.so.2
程序将打印出给定程序使用的共享库。但是,它实际上并没有这样做。它设置一个env变量,然后执行目标程序。 ELF加载器看到这个变量,而不是执行程序,它只是加载它,打印共享库的名称。 ELF加载器有许多可能影响其操作的环境变量(例如,参见ldd
)。
使用该环境的另一个库是man ld.so
。当glibc
遇到致命错误(例如双重释放指针或堆损坏)时,它将打印错误消息。通常,glibc
会将此输出到glibc
。有时,这是不可取的,我们宁愿将错误消息转到/dev/tty
[我们打开错误日志文件的地方]。为了让stderr
符合我们的意愿,我们在调用程序之前将env var glibc
设置为LIBC_FATAL_STDERR_
。
此配置文件可以由类似WinX注册表的接口处理,并且数据可以驻留在每进程内核内存中。但是,对于内核和程序而言,这很麻烦。内核不希望在[珍贵的]内核地址空间中携带这个可变大小的信息。应用程序不希望使用系统调用来获取它的开销。
大多数C程序员将1
函数写为main
,但实际传递的内容可以[更恰当地]写为int main(int argc,char **argv)
。 int main(int argc,char **argv,char **envp)
实际上指向了一个定义:
envp
libc函数char *environ[] = {
"DISPLAY=:0",
"PATH=/usr/bin:/bin",
...
NULL
};
,getenv
,setenv
在全局上运行。但是,当将指针传递给putenv
时,您可以完全指定不同的 env数组,并填充您想要的任何内容。因此,您可以直接操作数组[以及环境]。
历史脚注:环境变量并非特定于Linux。他们没有添加 - 他们一直在那里[在Linux]。并且,环境已经成为任何类似unix的系统的一部分,不变(!),因为最早的化身,就像execvpe
一样。这可以追溯到[至少]贝尔实验室的Unix V7 [可能更早]。
答案 1 :(得分:0)
变量用于编写脚本和程序管理。例如,您可以编写脚本问候语并在其中指示变量$ USER,它将显示当前用户的名称。程序可以访问变量,变量可以在他们的工作中使用。例如,在Linux上的GUI中运行的程序,您可以指定X服务器,用于显示其数据。
答案 2 :(得分:0)
环境变量对于在Linux上运行程序非常有用。我们通常需要在程序中读取一些系统配置,环境变量是允许我们访问这些配置的好地方。