我知道这VARIABLE=value
会创建一个环境变量,并export VARIABLE=value
使其可供当前 shell 创建的进程使用。env
显示当前的环境变量,但它们位于哪里?环境变量(或环境, 对于这个问题)?
答案1
环境并不像看起来那么神奇。 shell 将其存储在内存中并传递给execve()
系统调用。子进程将其继承为一个名为 的数组指针environ
。从execve
联机帮助页:
概要
#include <unistd.h> int execve(const char *filename, char *const argv[], char *const envp[]);
argv
是传递给新程序的参数字符串数组。
按照约定,这些字符串中的第一个应包含与正在执行的文件关联的文件名。envp
是一个字符串数组,通常采用 key=value 的形式,作为环境传递给新程序。
联机environ(7)
帮助页还提供了一些见解:
概要
extern char **environ;
描述
该变量
environ
指向一个名为“环境”的字符串指针数组。该数组中最后一个指针的值为NULL
。 (此变量必须在用户程序中声明,但如果头文件来自 libc4 或 libc5,并且如果它们来自 glibc 并且定义了 _GNU_SOURCE,则在头文件中声明<unistd.h>
。)此字符串数组可用于通过启动该进程的 exec(3) 调用来执行该进程。
这两个 GNU 手册页都与POSIX规范
答案2
你有一点错误:SOME_NAME=value
创建一个 shell 变量(在大多数 shell 中)。export SOME_NAME=value
创建一个环境变量。无论好坏,大多数 Unix/Linux/*BSD shell 在访问环境变量和 shell 变量时都使用相同的语法。
从更大的意义上来说,“环境”只是伴随程序执行的信息。在 C 程序中,您可能会通过调用找到进程 ID getpid()
,在 shell 程序中您将使用变量 access: $$
。进程ID只是程序环境的一部分。我相信“环境”一词来自一些更具理论性的计算机科学主题,例如对程序执行进行建模。程序执行的模型有一个环境“其中包含变量及其值之间的关联”。
后者更强的定义是 Unix/Linux/*BSD shell 的“环境”:名称(“变量”)与其值之间的关联。对于大多数 Unix 风格的 shell,这些值都是字符串,尽管这并不像以前那样严格。如今,Ksh、Zsh 和 Bash 都有类型化变量。甚至可以导出 shell 函数定义。
使用与普通 shell 变量分开的环境涉及fork/exec
启动所有 Unix 都使用的新进程的方法。当您使用export
名称/值对时,该名称/值对将出现在新可执行文件的环境中,由 shell 通过execve(2)
系统调用启动(通常在 后fork(2)
,除非exec
使用 shell 命令)。
在 后面execve()
,main()
new 二进制文件的函数有其命令行参数、环境(存储为以 NULL 结尾的字符串指针数组var=value
,请参阅environ(7)
手册页)。继承的其他状态包括ulimit
设置、当前工作目录以及execve()
调用者未设置 FD_CLOEXEC 的任何打开的文件描述符。 tty 的当前状态(启用回显、原始模式等)也可以被视为新exec
进程继承的执行状态的一部分。
请参阅bash
手册的说明执行环境对于简单命令(内置或 shell 函数除外)。
Unix 环境至少与某些其他操作系统不同:VMS“词汇”可以由子进程更改,并且该更改在父进程中可见。子进程中的VMScd
会影响父进程的工作目录。至少在某些情况下,我的记忆力可能会下降。
一些环境变量是众所周知的,$HOME
,$PATH
,$LD_LIBRARY_PATH
等等。有些是给定编程系统的常规信息,因此父 shell 可以将大量特殊用途的信息传递给某些程序,例如特定的临时目录,或者不显示在ps -ef
.例如,简单的 CGI 程序通过环境变量从 Web 服务器继承大量信息。
答案3
最原始形式的环境变量只是一组名称/值对。如 bash 手册页 ( man 1 bash
) 的 ENVIRONMENT 部分所述:
When a program is invoked it is given an array of strings called the
environment. This is a list of name-value pairs, of the form
name=value.
The shell provides several ways to manipulate the environment. On
invocation, the shell scans its own environment and creates a parameter
for each name found, automatically marking it for export to child pro-
cesses. Executed commands inherit the environment.
实际上,它允许您定义从当前 shell 调用的程序共享或独有的行为。例如,在使用crontab
或时,visudo
您可以定义EDITOR
环境变量来定义系统默认使用的编辑器之外的另一个编辑器。对于诸如man
查看您的PAGER
环境以找出应使用哪个分页程序来显示手册页输出的命令之类的命令也是如此。
很多 unix 命令都会读取环境,并根据设置的内容改变它们的输出/处理/操作。有些是共享的,有些是该程序独有的。大多数手册页都包含有关环境变量如何影响所描述的程序的信息。
其他实用示例适用于在同一平台上安装了多个 Oracle 的系统等情况。通过设置ORACLE_HOME
,整套 oracle 命令(从PATH
环境变量加载)然后从该顶级目录下提取设置、定义、映射和库。对于其他程序(例如 java 及其JAVA_HOME
环境变量)也是如此。
bash 本身有许多环境变量,可以改变一系列事物的行为,包括历史记录(HISTSIZE
等HISTFILE
)、屏幕大小(COLUMNS
)、制表符补全(FIGNORE
, GLOBIGNORE
)区域设置和字符编码/解码(LANG
, LC_*
)、提示(PS1
.. PS4
)和依此类推(再次从 bash 手册页寻求知识)。
您还可以编写使用您自己的自定义环境变量的脚本/程序(以传递设置或更改功能)。
答案4
“环境变量”是一组动态命名值,可以影响正在运行的进程在计算机上的行为方式。
它们是进程运行的操作环境的一部分。例如,正在运行的进程可以查询 TEMP 环境变量的值以发现存储临时文件的合适位置,或者查询 HOME 或 USERPROFILE 变量以查找运行该进程的用户拥有的目录结构。
更多信息请点击这里→http://en.wikipedia.org/wiki/Environment_variable。
关于环境变量你想知道的一切...... ↑