environ(7)

名称
environ - 用户环境

概述
extern char **environ;

描述
变量 environ 指向一个存储指针的数组，这些指针指向被称为“环境（environment）”的字符串。数组中最后一个指针的值为 NULL。该字符串数组在新程序启动时被 execve(2) 调用提供给进程。当子进程被 fork(2) 创建时，它继承其父进程环境的一份副本。

习惯上约定在 environ 中的字符串有类似“名称=值”的形式。其中的名称是大小写敏感的，且不能包含字符“=”。其中的值可以为任何字符串可以表示的文本。名称和值不能包含内嵌的空字节字符（'\0'），以此避免其被误认为字符串终止位置。

环境变量可由 sh(1) 中的 export 命令在 shell 的环境中被设定，或者在使用 csh(1) 时使用 setenv 命令。

对 shell 来说，其初始的环境相关变量可经由多种方式被填充，如在使用了 pam(8) 的系统上，pam_env(8) 会对所有用户在登录时启用 /etc/environment 中的定义。除此之外，许多 shell 初始化脚本，如系统层级的 /etc/profile 脚本和各个用户的初始化脚本，可能包含一些会向 shell 的环境中添加变量的命令；请参考您使用的 shell 的手册页了解详细信息。

Bourne 风格的 shell 支持下面的语法

    名称=值 命令

它可被用来仅在执行 命令 时创建对应的环境变量定义。在 命令 之前，可以存在多个变量定义，其间使用空格进行分隔。

参数还可以在调用 exec(3)时被放置于环境之中。C 程序可以使用诸如 getenv(3), putenv(3), setenv(3) 和 unsetenv(3) 的函数操纵其环境。

本文的下述部分列出了系统上常见的环境变量。这个列表并不完整，且仅包含普通用户在日常使用中常见的变量。特定程序或软件库函数所使用的环境变量通常会在其对应的手册页中的“环境”一节中进行描述。

USER
    已登录用户的名称（被某些 BSD 衍生的程序所使用）。其在登录时被设置，请见下文的备注一节。

LOGNAME
    已登录用户的名称（被某些 System-V 衍生的程序所使用）。其在登录时被设置，请见下文的备注一节。

HOME
    用户登录时的目录。其在登录时被设置，请见下文的备注一节。

LANG
    用于语言和区域设置类别的名称，它在未被 LC_ALL 或更具体的环境变量，如 LC_COLLATE, LC_CTYPE, LC_MESSAGES, LC_MONETARY, LC_NUMERIC 和 LC_TIME 所覆盖时生效（请参见 locale(7) 以了解 LC_* 环境变量的具体细节）。

PATH
    它是一系列目录前缀，可被 sh(1) 和许多其他程序所使用以搜索由简单的文件名（即不含有斜线的路径名）所指定的可执行文件。各个前缀之间被冒号（:）所分隔。整个前缀列表会被从前到后进行搜索，程序会检查给定路径名在附加前缀、斜线和文件名之后的路径是否存在，直到找到一个符合条件的可执行文件为止。

    还存在一个遗留的特性：如果前缀长度为零（即由两个相邻的冒号组成，或者有起始或终止位置的冒号存在），该前缀会被解释为指定当前工作目录。然而，当前已不推荐使用该特性，且 POSIX 认为一个符合标准的应用程序应当使用显式的路径名（如 .）来指定当前工作目录。

    类似 PATH，还存在 CDPATH 会被某些 shell 用来寻找更改目录指令的目标目录，以及被 man(1) 所使用寻找手册页的 MANPATH，等等。

PWD 当前工作目录的绝对路径。它的组成部分必须被规范化（即不可出现 . 或 .. 的路径部分）。

SHELL
    用户登录 shell 的绝对路径名。其在登录时被设置，请见下文的备注一节。

TERM
    输出应当兼容的终端类型。

PAGER
    用户偏好的显示文本文件的实用工具。可被设置为任何 sh -c 命令可接受的命令字符串操作符。如果 PAGER 的值为空或未被设置，则启动分页器的应用程序会默认选择一个程序，如 less(1) 或 more(1)。

EDITOR/VISUAL
    用户偏好使用的编辑文本文件的工具。可被设置为任何 sh -c 命令可接受的命令字符串操作符。

请注意，许多程序和软件库例程的行为都会受到特定环境变量存在与否及其取值的影响。下面给出一些例子：

•   LANG, LANGUAGE, NLSPATH, LOCPATH, LC_ALL, LC_MESSAGES 等等变量会影响语言和区域设置的处理；请参见 catopen(3), gettext(3) 和 locale(7)。

•   TMPDIR 影响由 tempnam(3) 和其他例程创建的路径名称的前缀，以及由 sort(1) 和其他程序所使用的临时目录名。

•   LD_LIBRARY_PATH, LD_PRELOAD 和其他 LD_* 变量会影响动态加载器/链接器的行为。请参见 ld.so(8)。

•   POSIXLY_CORRECT 使得特定的程序和软件库例程遵循 POSIX 所指定的行为。

•   malloc(3) 的行为受到 MALLOC_* 变量的影响。

•   HOSTALIASES 变量给出包含 gethostbyname(3) 将要使用的主机别名的文件的名称。

•   TZ 和 TZDIR 给出 tzset(3) 所使用的时区信息，并涉及诸如 ctime(3), localtime(3), mktime(3), strftime(3) 等函数。另请参见 tzselect(8)。

•   TERMCAP 提供如何处理给定终端的相关信息（或者给出包含这些信息的文件的文件名）

•   COLUMNS 和 LINES 会告知应用程序窗口大小信息，它可能会覆盖实际大小的配置。

•   PRINTER 或 LPDEST 可能指定要使用的打印机。请见 lpr(1)。

备注
历史上以及标准上，environ 必须被用户程序所声明。然而，一个现存的不标准的方便程序员工作的方法是将 environ 声明在 <unistd.h> 头文件中，前提是 _GNU_SOURCE 功能测试宏已被定义（参见 feature_test_macros(7)）。

prctl(2) 中的 PR_SET_MM_ENV_START 和 PR_SET_MM_ENV_END 操作可被用来控制进程环境的位置。

HOME, LOGNAME, SHELL 和 USER 变量会在用户经由会话管理界面被变更时被设置。者通常是经由类似 login(1) 的程序以及用户数据库（例如 passwd(5)）所完成的。（使用 su(1) 切换到 root 用户可能导致混合的环境变量，其中 LOGNAME 和 USER 被保留为旧有用户的值；参见 su(1) 手册页。）

缺陷
很显然，这个机制有安全风险。许多系统命令可被用户指定的不同寻常的 IFS 或 LD_LIBRARY_PATH 的值所欺骗。

还存在命名空间污染的风险。如 make 和 autoconf 等程序允许环境中具有和实用工具相同命名（但全大写）的变量覆盖默认所使用的工具路径。因此，用户可以使用 CC 来选择想要使用的 C 编译器（类似地，还有 MAKE, AR, AS, FC, LD, LEX, RM, YACC 等等）。然而，在某些传统的使用场景中这些环境变量还会被赋值为程序选项而非路径名，例如 MORE 和 LESS。这些用法被认为是错误的，应当在新程序中避免。

参见
bash(1), csh(1), env(1), login(1), printenv(1), sh(1), su(1), tcsh(1), execve(2), clearenv(3), exec(3), getenv(3), putenv(3), setenv(3), unsetenv(3), locale(7), ld.so(8), pam_env(8)