For the complete documentation index, see llms.txt. This page is also available as Markdown.

env(1)

env — 设置环境并执行命令,或打印环境

名称

env

概要

env [-0iv] [-L | -U user[/class]] [-u name] [name=value ...]

env [-iv] [-C altwd] [-L | -U user[/class]] [-P altpath] [-S string] [-u name] [name=value ...] utility [argument ...]

描述

env 实用程序在按命令行指定修改环境后执行另一个 utility。每个 name=value 选项指定环境变量 name 的设置,值为 value。所有此类环境变量都在执行 utility 之前设置。

选项如下:

-0 每行输出以 NUL 结尾,而非换行。

-i 仅使用由 name=value 选项指定的环境变量执行 utilityenv 继承的环境被完全忽略。

-C altwd 在执行指定的 utility 程序之前切换到指定的备用工作目录。

-L | -U user[/class] 在处理任何 -i-u 选项之后、处理任何 name=value 选项之前,将指定用户和登录类的 login.conf(5) 中的环境变量定义添加到环境中。如果使用 -L,仅读取系统范围的 /etc/login.conf.db 文件;如果使用 -U,还会读取指定用户的 ~/.login_conf。用户可以按名称或 uid 指定。如果给定的用户名为“-”,则不进行用户查找,登录类默认为“default”(如果未显式给出),并且不对值进行任何替换。

-P altpath 搜索由 altpath 指定的目录集合来定位指定的 utility 程序,而不是使用 PATH 环境变量的值。

-S string 将给定的 string 拆分为多个字符串,并将每个结果字符串作为 env 实用程序的单独参数处理。-S 选项识别一些特殊字符转义序列,还支持环境变量替换,如下所述。

-u name 如果环境变量 name 在环境中,则在处理剩余选项之前将其移除。这类似于 sh(1) 中的 unset 命令。name 的值不得包含 = 字符。

-v 打印 env 实用程序执行的每个处理步骤的详细信息。如果多次指定 -v,将打印附加信息。

上述选项仅在任何 name=value 选项之前指定时才被识别。

如果未指定 utilityenv 打印环境中变量的名称和值。除非指定了 -0,每个名称/值对以换行符分隔;指定 -0 时,名称/值对以 NUL 分隔。-0utility 不能同时指定。

env 实用程序不处理名称中带有等号(=)的 utility 值,原因显而易见。这可以通过插入 command(1) 实用程序来轻松解决,该实用程序只是执行其参数;参见下文的实例。

-S(split-string)处理的细节

-S 选项的处理会根据 string 中找到的任何空格或 字符将给定的 string 拆分为单独的参数。然后,每个新参数被视为如同在原始 env 命令上作为单独参数指定一样。

空格和制表符可以通过使用单引号(“'”)或双引号(")或反斜杠(\)嵌入到其中一个新参数中。单引号会转义所有非单引号字符,直到匹配的单引号。双引号会转义所有非双引号字符,直到匹配的双引号。如果在匹配引号字符之前到达 string 末尾,则为错误。

如果 -S 会创建一个以 # 字符开头的新参数,则该参数和 string 的其余部分将被忽略。当你希望新参数以 # 字符开头而不导致 string 的其余部分被跳过时,可以使用 \# 序列。

在处理 string 值时,-S 处理会将某些字符组合视为表示要采取的操作的转义序列。字符转义序列采用反斜杠表示法。字符及其含义如下:

\c 忽略 string 中的剩余字符。这不得出现在双引号字符串内。

\f 替换为 <换页> 字符。

\n 替换为 <换行> 字符。

\r 替换为 <回车> 字符。

\t 替换为 <制表符> 字符。

\v 替换为 <垂直制表符> 字符。

\# 替换为 # 字符。当你需要 # 作为通过拆分给定 string 创建的某个参数的第一个字符时很有用。

\$ 替换为 $ 字符。

\_ 如果在双引号字符串内找到,则替换为单个空格。如果在引号字符串外找到,则将其视为原始 string 中新参数之间的分隔符。

\" 替换为 <双引号> 字符。

\' 替换为 <单引号> 字符。

\\ 替换为反斜杠字符。

<单引号> 和反斜杠的序列是仅在单引号字符串内识别的序列。其他序列在单引号字符串内没有特殊含义。所有转义序列都在双引号字符串内被识别。如果单个 \ 字符后跟的不是上述列出的字符之一,则为错误。

-S 的处理还支持从环境变量中替换值。为此,环境变量的名称必须在 ${} 内,例如:${SOMEVAR}。不支持常见的 shell 语法 $SOMEVAR。所有替换的值将是 env 实用程序最初调用时环境变量的值。这些值不会被检查上述任何转义序列。并且任何 name=value 的设置都不会影响 -S 处理中用于替换的值。

此外,-S 处理不能引用大多数 shell 定义的特殊参数的值。例如,如果 $*$@$#$?$$ 出现在给定的 string 内,-S 无法识别它们。

在 shell 脚本中使用

env 实用程序经常用作解释脚本第一行的 interpreter,如 execve(2) 中所述。

注意,内核解析解释脚本的 #!(第一行)的方式自 FreeBSD 6.0 起已改变。在此之前,FreeBSD 内核会根据该行中找到的任何空白字符(空格或 字符)将该第一行拆分为单独的参数。因此,如果一个名为 /usr/local/bin/someport 的脚本的第一行为:

那么 /usr/local/bin/php 程序将以以下参数启动:

加上用户执行 someport 时指定的任何参数。然而,#! 行上的这种多选项处理并非任何其他操作系统解析解释脚本第一行的方式。因此,在 FreeBSD 6.0 版本中做出更改后,该脚本将导致 /usr/local/bin/php 以以下参数启动:

加上用户指定的任何参数。这导致少数脚本的行为发生了重大变化。对于上述脚本,要使其在 FreeBSD 6.0 下的行为与早期版本相同,第一行应更改为:

env 实用程序将以整行作为单个参数启动:

然后 -S 处理会在执行 /usr/local/bin/php 之前将该行拆分为单独的参数。

环境变量

env 实用程序使用 PATH 环境变量来定位请求的 utility(如果名称不包含 / 字符),除非已指定 -P 选项。

退出状态

env 实用程序成功时退出 0,发生错误时退出 >0。

退出状态 126 表示找到了 utility 但无法执行。退出状态 127 表示无法找到 utility

实例

由于 env 实用程序经常用作解释脚本第一行的一部分,以下示例展示了 env 实用程序在脚本中的一些有用方式。

解释脚本的内和处理不允许脚本直接将其他脚本作为其自身的解释器引用。作为一种变通方法,以下两者之间的主要区别

在于后者即使 /usr/local/bin/foo 本身是解释脚本也能工作。

env 可能最常见的用途是在解释器可能位于不同系统的不同目录中时,为脚本找到正确的解释器。以下示例将通过搜索 PATH 指定的目录来找到 perl 解释器。

该示例的一个限制是它假设用户的 PATH 值设置为能找到你要执行的解释器。可以使用 -P 选项来确保搜索 utility 时使用特定的目录列表。注意,此示例还需要 -S 选项才能正常工作。

上述命令仅在 perl 位于 /usr/local/bin/usr/bin 中时才找到它。这可以与 PATH 的当前值结合,以提供更大的灵活性。注意,-S-P 选项之间不需要空格:

执行名称中带有等号的实用程序:

兼容性

env 实用程序接受 - 选项作为 -i 的同义词。

参见

printenv(1), sh(1), execvp(3), login.conf(5), environ(7)

标准

env 实用程序符合 IEEE Std 1003.1-2001 ("POSIX.1")。-0-C-L-P-S-U-u-v 选项是 FreeBSD 支持的非标准扩展,但在其他操作系统上可能不可用。

历史

env 命令出现于 4.4BSD。-P-S-v 选项在 FreeBSD 6.0 中添加。-0-L-U 选项在 FreeBSD 13.0 中添加。-C 选项在 FreeBSD 14.2 中添加。

缺陷

env 实用程序在处理 -S 选项时不考虑多字节字符,这可能导致某些语言环境中的结果不正确。

最后更新于

这有帮助吗?