sh.1

SH(1)

SH(1)

FreeBSD General Commands Manual

SH(1)

sh

命令解释器(外壳)

sh [-/+abCEefhIimnPpTuVvx] [-/+o longname] [script [arg ...]] sh [-/+abCEefhIimnPpTuVvx] [-/+o longname] -c string [name [arg ...]] sh [-/+abCEefhIimnPpTuVvx] [-/+o longname] -s [arg ...]

sh 实用程序是系统的标准命令解释器。当前版本 sh 接近外壳的 IEEE Std 1003.1 (“POSIX.1”) 规范。它仅支持 POSIX 指定的功能,以及一些 Berkeley 扩展。本手册页既不是教程也不是 shell 的完整规范。

shell 是一个从文件或终端读取行、解释它们并通常执行其他命令的命令。它是用户登录系统时启动的程序,尽管用户可以使用 chsh(1) 命令选择不同的 shell。shell 实现了一种具有流控制结构的语言,一种宏工具,除了数据存储之外还提供各种功能,以及内置的历史记录和行编辑功能。它结合了许多特性来帮助交互使用,并且具有解释性语言对交互和非交互使用(shell 脚本)通用的优点。也就是说,命令可以直接输入到正在运行的 shell 中,也可以放入一个文件中,该文件可以由 shell 直接执行。

如果不存在任何参数并且 shell 的标准输入连接到终端(或者如果 -i 设置了选项),则 shell 被认为是交互式 shell。交互式 shell 通常会在每个命令之前提示并以不同方式处理编程和命令错误(如下所述)。首次启动时,shell 检查参数 0,如果它以破折号 (‘-’)- 开头,则 shell 也被视为登录 shell。这通常在用户首次登录时由系统自动完成。登录 shell 首先从文件 /etc/profile 读取命令,然后 读取用户主目录中的 .profile (如果存在)。如果环境变量 ENV 是在进入 shell 时设置的,或者在 .profile 中设置对于登录 shell,shell 然后将其值进行参数扩展和算术扩展,并从命名文件中读取命令。因此,用户应该将仅在登录时执行的命令放在 .profile 文件中,以及为 ENV 文件中的每个 shell 执行的命令。用户可以 ENV 通过将以下行放在主目录中的文件 .profile 中,将 .shrc 替换为所需的文件名,从而将变量设置为某个文件:

ENV=$HOME/.shrc; export ENV

命令行中指定的第一个非选项参数将被视为从中读取命令的文件的名称(shell 脚本),其余参数设置为 shell 的位置参数 ($1, $2, 等)。 否则,shell 从其标准输入读取命令。

与旧版本 shENV 脚本不同,它仅源自交互式 shell 的调用。这关闭一个众所周知的、有时很容易被利用的与考虑不周的 ENV 脚本相关的安全漏洞。

sh 的所有单字母选项都有一个对应的长名称,除了 -c-/+o -。 这些长名称在以下描述中的单字母选项旁边提供。 选项的长名称可以指定为 sh-/+o 选项的参数。 一旦 shell 运行,选项的长名称可以指定为 set 内置命令的 -/+o 选项的参数 (稍后在 Built-in Commands 一节中描述)。 使用破折号 (‘-’) 会启用该选项,而使用加号 (‘+’) 会禁用该选项。 一个 “--” 或简单的 ‘-’ 将停止选项处理并强制将命令行上的剩余单词视为参数。 -/+o-c 选项没有很长的名称。 它们接受参数,并在单个字母选项之后进行描述。

-a allexport

对变量进行分配时标记要导出的变量。

-b notify

启用后台作业完成的异步通知。(未实现)

-C noclobber

不要用 ‘>’ 覆盖现有文件。

-E emacs

启用内置的 emacs(1) 命令行编辑器(如果设置了 -V 选项,则禁用该选项; 在终端上交互时自动设置)。

-e errexit

如果任何未经测试的命令在非交互模式下失败,则立即退出。 如果命令是用于控制 if, elif, while, 或 until 的列表的一部分,则认为该命令的退出状态是显式测试;如果该命令是 “&&” 或 “||” 操作符的左操作数;或者,如果该命令是一个在 ! 关键字。 如果一个 shell 函数被执行并且它的退出状态被显式地测试过,那么这个函数的所有命令也被认为是被测试过的。

建议显式地检查失败,而不是依赖 -e ,因为它倾向于以意想不到的方式行事,特别是在较大的脚本中。

-f noglob

禁用路径名扩展。

-h trackall

POSIX遵从性的“不做任何事”选项。

-I ignoreeof

在交互模式下忽略输入中的 EOF

-i interactive

强制 shell 以交互方式运行。

-m monitor

打开作业控制(交互时自动设置)。为每个管道创建一个新的进程组(称为作业)。可以暂停作业或让它们在前台或后台运行。在非交互式 shell 中,即使没有可用的终端,也可以设置此选项,并且对于将进程放置在单独的进程组中很有用。

-n noexec

如果不是交互式的,请阅读命令但不执行它们。这对于检查 shell 脚本的语法很有用。

-P physical

cdpwd 命令的默认值从 -L (逻辑目录布局)修改为 -P (物理目录布局)。

-p privileged

开启特权模式。如果有效用户或组 ID 不等于实际用户或组 ID,则在启动时启用此模式。关闭此模式会将有效用户和组 ID 设置为真实用户和组 ID。当为交互式 shell 启用此模式时,在获取 /etc/profile 之后,将获取文件 /etc/suid_profile 而不是 ~/.profile ,并且忽略 ENV 变量的内容 。

-s stdin

从标准输入读取命令(如果不存在文件参数,则自动设置)。在 shell 已经开始运行后设置此选项无效(即,使用 set 命令设置时)。

-T trapsasync

当等待一个子程序时,立即执行陷阱。如果没有设置此选项,则在子程序退出后执行陷阱,如 IEEE Std 1003.2 (“POSIX.2”) 中所规定的那样。这个非标准选项对于在屏蔽信号的子对象周围设置保护外壳非常有用。周围的 shell 可能会杀死子程序,或者它可能只是把控制权返回给 tty,让子程序独处,就像这样:

sh -T -c "trap 'exit 1' 2 ; some-blocking-program"

-u nounset

当试图展开一个变量,一个位置参数或特殊参数'时,向标准错误写入一条消息 ! ,如果 shell 不是交互式的,则立即退出。

-V vi

启用内置的 vi(1) 命令行编辑器(禁用 -E ,如果它已经设置)。

-v verbose

shell 在读取时将其输入写入标准错误。对调试很有用。

-x xtrace

在执行之前将每个命令(前面是经过参数展开和算术展开的 PS4 变量的值)写入标准错误。对调试很有用。

nolog

POSIX 合规性的另一个无所事事选项。它只有一个很长的名字。

pipefail

将管道的退出状态更改为管道中任何命令的最后一个非零退出状态(如果有)。 由于 SIGPIPE 导致的退出被视为非零退出状态,如果管道中的命令(比如 head(1) )以状态0终止,而没有完全读取其输入,那么这个选项可能会导致成功的管道出现非零退出状态。此选项只有一个长名称。

-c 选项导致从 string 操作数而不是标准输入读取命令。 请记住,此选项仅接受单个字符串作为其参数,因此必须引用多字字符串。

-/+o 选项的唯一参数是要启用或禁用的选项的长名称。例如,以下两次 sh 调用都启用了内置的 emacs(1) 命令行编辑器:

set -E set -o emacs

如果不带参数使用, -o 选项以人类可读的格式显示当前选项设置。如果 +o 不带参数使用,则当前选项设置以适合重新输入到 shell 的格式输出。

shell 根据文件的行读取输入,并将其分解为空格(空格和制表符)处的单词,以及称为 “运算符” 的某些字符序列,这些字符对 shell 来说是特殊的。有两种类型的运算符:控制运算符和重定向运算符(它们的含义将在后面讨论)。以下是有效运算符的列表:

控制运算符:

&

&&

[(](#()

))

;;

;&

;

|

||

重定向运算符:

<

>

<<

>>

<>

<&

>&

<<-

>|

如果在单词的开头使用字符 ‘#’ ,则会引入注释。以 ‘#’ 开头的单词和该行的其余部分将被忽略。

shell 输入中不允许使用 ASCII NUL 字符(字符代码 0)。

引用用于删除某些字符或单词对 shell 的特殊含义,例如运算符、空格、关键字或别名。

有四种类型的引用:匹配的单引号、美元单引号、匹配的双引号和反斜杠。

单引号

将字符括在单引号中可以保留所有字符的字面含义(单引号除外,因此无法将单引号放在单引号字符串中)。

美元单引号

$'' 之间的封闭字符保留除反斜杠和单引号之外的所有字符的字面含义。反斜杠引入了 C 风格的转义序列:

\a

警报(敲响终端铃声)

\b

退格

\cc

stty(1) 中由 ^c 表示的控制字符。如果 c 是反斜杠,则必须加倍。

\e

ESC 字符(ASCII 0x1b)

\f

换页

新行

回车

水平制表符

\v

垂直制表符

\\

文字反斜杠

\'

字面单引号

\"

字面双引号

\nnn

八进制值为 nnn (一到三位)的字节

\xnn

十六进制值为 nn 的字节(一位或多位仅使用最后两位)

\unnnn

Unicode 代码点 nnnn (四个十六进制数字)

\Unnnnnnnn

Unicode 代码点 nnnnnnnn (八位十六进制数字)

Unicode 代码点的序列目前仅适用于 UTF-8 语言环境。他们拒绝代码点 0 和 UTF-16 代理。

如果转义序列将生成值为 0 的字节,则忽略该字节和字符串的其余部分,直到匹配的单引号。

任何其他以反斜杠开头的字符串都是错误的。

双引号

将字符括在双引号中会保留除美元符号 (‘$’) 、反引号 (‘`’) 和反斜杠 (‘\’). 之外的所有字符的字面含义。 双引号内的反斜杠在历史上很奇怪。除非它在以下字符之前,否则它仍然是字面的,它用于引用:

$

`

"

\

反斜杠

反斜杠保留后面字符的字面含义,但换行符 (‘’) 除外。换行符之前的反斜杠被视为续行。

关键字或保留字是对 shell 具有特殊含义的字,并且在行首和控制运算符之后被识别。以下是关键字:

!

{

}

case

do

done

elif

else

esac

fi

for

if

then

until

while

别名是使用 alias 内置命令设置的名称和相应的值。 一个简单命令的命令词可能出现在任何地方,并且在检查关键字是否可能出现关键字之后,shell 检查该词以查看它是否与别名匹配。如果是这样,它将在输入流中用它的值替换它。例如,如果有一个名为 “lf” 的别名,其值为 “ls -F” ,那么输入

lf foobar

会成为

ls -F foobar

在值以空格或制表符结尾的别名之后,也可以识别别名。例如,如果还有一个名为 且值为 “nohup ” 的别名,则输入

nohup lf foobar

会成为

nohup ls -F foobar

别名为天真的用户提供了一种方便的方式来创建命令的简写,而无需学习如何创建带参数的函数。不鼓励在脚本中使用别名,因为定义它们的命令必须在解析使用它们的代码之前执行。这是脆弱的,不便携。

别名可以在命令行中转义,这样它就不会被其别名值替换,方法是在别名内或附近使用引号字符。这通常通过在别名名称前加上反斜杠来执行具有相同名称的函数、内置程序或普通程序来完成。请参阅 引用 小节。

shell 根据一种语言解释它读取的单词,其规范超出了本手册页的范围(请参阅 IEEE Std 1003.2 (“POSIX.2”) 文档中的 BNF)。但本质上,读取一行并且如果该行的第一个单词(或在控制运算符之后)不是关键字,那么 shell 已经识别出一个简单的命令。否则,可能会识别出复杂的命令或其他一些特殊构造。

如果已识别出一个简单的命令,shell 将执行以下操作:

  1. name=value” 形式的前导词被剥离并分配给简单命令的环境(它们不影响扩展)。重定向运算符及其参数(如下所述)被剥离并保存以供处理。

  2. 剩余的单词按照 Word Expansions 部分中的描述进行扩展,剩余的第一个单词被认为是命令名称和命令所在的位置。剩余的单词被认为是命令的参数。如果没有产生命令名称,那么在 1) 中识别的 “name=value” 变量分配会影响当前 shell。

  3. 重定向将按照下一节中的说明执行。

重定向用于更改命令读取其输入或发送其输出的位置。通常,重定向会打开、关闭或复制对文件的现有引用。用于重定向的总体格式是:

[n] redir-op file

redir-op 是前面提到的重定向运算符之一。下面给出了如何使用这些运算符的一些示例。请注意,stdin 和 stdout 分别是标准输入和标准输出的常用缩写。

[n]> file

将标准输出(或文件描述符 n )重定向到 file

[n]>| file

和上面一样,但是重写 -C 选项

[n]>> file

将标准输出(或文件描述符 n )追加到 file

[n]< file

从 file 重定向标准输入(或文件描述符 n )

[n]<> file

重定向标准输入(或文件描述符 n )到和从 file

[n1]<&n2

从文件描述符 n2 复制标准输入(或文件描述符 n1 )

[n]<&-

关闭标准输入(或文件描述符 n )

[n1]>&n2

将标准输出(或文件描述符 n1) )复制到文件描述符 n2

[n]>&-

关闭标准输出(或文件描述符 n )

以下重定向通常称为 “here-document”.

[n ] << delimiter here-doc-text ... delimiter

连续行上直到分隔符的所有文本都被保存起来,并可供标准输入上的命令使用,或者文件描述符 n (如果已指定)。如果在首行指定的 delimiter 被引用,则 here-doc-text 将按字面意思处理,否则文本将进行参数扩展、命令替换和算术扩展(如 Word Expansions 部分所述)。如果操作符是 “<<-” 而不是 “<<” ,那么 here-doc-text 中的前导制表符将被剥离。

命令分为三种类型:shell 函数、内置命令和普通程序。按该顺序(按名称)搜索该命令。这三种类型的命令都以不同的方式执行。

当一个 shell 函数被执行时,所有的 shell 位置参数(除了 $0 ,它保持不变)都被设置为 shell 函数的参数。显式放置在命令环境中的变量(通过在函数名之前对它们进行赋值)被设为函数的本地变量并设置为给定的值。然后执行函数定义中给出的命令。命令完成后,位置参数将恢复为其原始值。这一切都发生在当前 shell 中。

Shell 内置命令在 shell 内部执行,不会产生新进程。有两种内置命令:常规和特殊。特殊内置函数之前的赋值在完成执行后仍然存在,赋值错误、重定向错误和某些操作数错误会导致脚本中止。特殊的内置函数不能被函数覆盖。常规和特殊的内置函数都可以以普通程序无法影响的方式影响 shell。

否则,如果命令名称与函数或内置命令不匹配,则将该命令作为文件系统中的普通程序进行搜索(如下一节所述)。当执行普通程序时,shell 运行程序,将参数和环境传递给程序。如果程序不是一个普通的可执行文件(即,如果它不以 ASCII 表示为 “#!” 的 “magic number” 开头,从而导致 execve(2) 的 ENOEXEC 返回值)但看起来是一个文本文件,shell 将运行一个新的 sh 实例来解释它。

请注意,本文档的先前版本和源代码本身会误导性地偶尔将没有幻数的 shell 脚本称为 “shell 过程 。”

定位命令时,shell 首先查看它是否具有该名称的 shell 函数。然后它会查找该名称的内置命令。如果未找到内置命令,则会发生以下两种情况之一:

  1. 包含斜杠的命令名称会被简单地执行而不执行任何搜索。

  2. shell 依次搜索 PATH 变量中的每个条目以查找命令。 PATH 变量的值应该是一系列用冒号分隔的条目。每个条目都包含一个目录名称。当前目录可以由一个空目录名称隐式指示,也可以由一个句点显式指示。

每个命令都有一个退出状态,可以影响其他 shell 命令的行为。范例是命令以零表示正常或成功退出,非零表示失败、错误或错误指示。每个命令的手册页应说明各种退出代码及其含义。此外,内置命令会返回退出代码,执行的 shell 函数也是如此。

如果命令被信号终止,则其退出状态大于 128。可以通过将退出状态传递给 kill -l 来找到信号名称。

如果没有命令字,则退出状态是最后执行的命令替换的退出状态,如果命令不包含任何命令替换,则为零。

复合命令是简单命令与控制运算符或关键字的组合,共同创建一个更大的复杂命令。更一般地说,命令是以下之一:

  • 简单命令

  • 管道

  • 列表或复合列表

  • 复合命令

  • 函数定义

除非另有说明,否则命令的退出状态是该命令执行的最后一个简单命令的状态,如果没有执行简单命令,则为零。

管道是由控制运算符 ‘|’ 分隔的一个或多个命令的序列。除了最后一个命令之外,所有命令的标准输出都连接到下一个命令的标准输入。像往常一样,最后一个命令的标准输出是从 shell 继承的。

管道的格式是:

[!] command1 [| command2 ...]

command1 的标准输出连接到 command2 的标准输入。在作为命令的一部分的重定向运算符指定的任何重定向之前,一个命令的标准输入、标准输出或两者都被认为是由管道分配的。

请注意,与其他一些 shell 不同, sh 在子 shell 环境中使用多个命令执行管道中的每个进程,并且作为 sh 进程的子进程。

如果管道不在后台(稍后讨论),shell 将等待所有命令完成。

如果关键字 ! 不先于管道,如果未设置 pipefail 选项或所有命令返回零,则退出状态是管道中指定的最后一个命令的退出状态,否则是管道中任何命令的最后一个非零退出状态。 否则,退出状态是该退出状态的逻辑非。也就是说,如果该状态为零,则退出状态为 1;如果该状态大于零,则退出状态为零。

因为标准输入或标准输出或两者的管道分配发生在重定向之前,它可以通过重定向来修改。例如:

command1 2>&1 | command2

将 command1 的标准输出和标准错误发送到 command2 的标准输入。

一种 ‘;’ 或换行符终止符导致前面的 AND-OR-list(在下面称为 Short-Circuit List Operators 的部分中描述)按顺序执行; ‘&’ 导致前面的 AND-OR-list 异步执行。

如果命令被控制运算符 (‘&’) 终止,则 shell 在子 shell 环境中异步执行命令(请参阅下面的将命令组合在一起);在执行下一个命令之前,shell 不会等待命令完成。

在后台运行命令的格式是:

command1 & [command2 & ...]

如果 shell 不是交互式的,则异步命令的标准输入设置为 /dev/null 。

退出状态为零。

列表是由换行符、分号或 & 号分隔的零个或多个命令的序列,并且可选地由这三个字符之一终止。列表中的命令按照它们写入的顺序执行。如果 command 后跟一个 & 符号,shell 将启动该命令并立即执行下一个命令;否则,它会等待命令终止,然后再继续执行下一个命令。

&&” 和 “||” 是 AND-OR 列表运算符。 “&&” 执行第一个命令,如果第一个命令的退出状态为零,则执行第二个命令。 “||” 类似,但如果第一个命令的退出状态为非零,则执行第二个命令。 “&&” 和 “||” 两者具有相同的优先级。

if 命令的语法是:

if

退出状态为所选 thenelse 列表的退出状态,如果没有选择列表则为0。

while 命令的语法是:

while

这两个列表在第一个列表的退出状态为零时重复执行。 until 命令类似,但用 until 代替 while, 这会导致它重复,直到第一个列表的退出状态为零。

退出状态是第二个列表最后一次执行的状态,如果从未执行过,则退出状态为零。

for 命令的语法是:

for

如果省略 in 和后面的单词,则使用 in "$@" 代替。单词被扩展,然后列表被重复执行,变量依次设置为每个单词。 dodone 命令可以用 ‘{’ 和 ‘}’ 代替。

breakcontinue 命令的语法是:

break [num]

continue [num]

break 命令终止最里面的 num 个 forwhile 循环。 continue 命令继续最内层循环的下一次迭代。这些被实现为特殊的内置命令。

case 命令的语法是:

case

模式实际上可以是一个或多个模式(参见后面描述的 Shell Patterns 模式),用 ‘|’ 分隔字符。 波浪号扩展、参数扩展、命令替换、算术扩展和引号删除应用于单词。 然后,使用波浪号扩展、参数扩展、命令替换和算术扩展依次扩展每个模式,并对照它检查单词的扩展形式。如果找到匹配项,则执行相应的列表。如果选定的列表被控制操作符 ‘;&’ 而不是 ‘;;’ 终止,则继续执行下一个列表,直到列表以 ‘;;’ 终止或 case 命令的结尾。

命令可以通过编写来分组

(list )

or

{ list ; }

第一种形式在子 shell 环境中执行命令。子 shell 环境有自己的副本:

  1. cd 设置的当前工作目录。

  2. umask 设置的文件创建掩码。

  3. ulimit 设置的资源限制。

  4. 对打开文件的引用。

  5. trap 设置的陷阱。

  6. 已知的工作。

  7. 位置参数和变量。

  8. Shell 选项。

  9. Shell 函数。

  10. Shell 别名。

这些是从父 shell 环境复制的,除了将捕获(但不忽略)信号重置为默认操作并清除已知作业。任何更改都不会影响父 shell 环境。

子外壳环境可以实现为子进程或以其他方式实现。如果在交互式 shell 中启用了作业控制,则括号中的命令可以暂停并作为一个单元继续执行。

为了与其他 shell 兼容,顺序的两个开括号应该用空格分隔。

第二种形式从不分叉另一个 shell,因此它的效率略高。以这种方式将命令组合在一起允许用户重定向他们的输出,就好像它们是一个程序一样:

{ echo -n "hello"; echo " world"; } > greeting

函数定义的语法是

name ( ) command

函数定义是一个可执行语句;执行时,它会安装一个名为 name 的函数并返回退出状态为零。该 command 通常是一个包含在 ‘{’ 和 ‘}’ 之间的列表。

可以使用 local 命令将变量声明为函数的局部变量。这应该作为函数的第一条语句出现,语法为:

local [variable ...] [-]

local 命令被实现为内置命令。除非命令不在函数中或变量名无效,否则退出状态为零。

当一个变量成为本地变量时,它会继承初始值,并从周围范围内具有相同名称的变量中导出和只读标志(如果有的话)。否则,该变量最初是未设置的。shell 使用动态作用域,因此如果变量 x 是函数 f 的局部变量,然后函数 f 调用函数 g ,对 g 内部的变量 x 的引用将指向 f 内部声明的变量 x ,而不是名为 x 的全局变量。

唯一可以本地化的特殊参数是 ‘- 。’ 将 ‘-’ 设为本地会导致通过函数内部的 set 命令更改的任何 shell 选项(包括只有长名称的选项)在函数返回时恢复为其原始值。

return 命令的语法是

return [exitstatus]

它终止当前的执行范围,从最近的嵌套函数或源脚本返回;如果没有函数或源脚本正在执行,它会退出 shell 实例。 return 命令被实现为一个特殊的内置命令。

shell 维护一组参数。由名称表示的参数(仅由字母、数字和下划线组成,并以字母或下划线开头)称为变量。启动时,shell 将所有具有有效名称的环境变量转换为 shell 变量。可以使用表格设置新变量

name=value

参数也可以用数字或特殊字符表示,如下所述。

分配的扩展与其他词不同:波浪号扩展也在等号之后以及任何冒号之后执行,用户名也以冒号结尾,并且不执行字段拆分和路径名扩展。

这种特殊的扩展不仅适用于自己形成简单命令或在命令字之前的赋值,而且也适用于传递给具有这种形式的 export, localreadonly 内置命令。 为此,内置的名称必须是文字(不是扩展的结果),并且可以选择在一个或多个不带选项的 command 的文字实例。

位置参数是由大于零的数字表示的参数。shell 最初将这些设置为其命令行参数的值,这些参数遵循 shell 脚本的名称。 set 内置命令也可用于设置或重置它们。

特殊参数是由单个特殊字符或数字零表示的参数。它们显示在以下列表中,与用户输入的输入或 shell 脚本源中的显示完全相同。

$*

扩展到位置参数,从一个开始。当扩展发生在双引号字符串中时,它会扩展为单个字段,每个参数的值由 IFS 变量的第一个字符分隔,如果 IFS 未设置,则由空格分隔。

$@

扩展到位置参数,从一个开始。当扩展发生在双引号内时,每个位置参数都扩展为一个单独的参数。如果没有位置参数, @ 的扩展会生成零参数,即使 @ 是双引号。这基本上意味着,例如,如果 $1 是 “abc” 而 $2 是 “def ghi”, 那么 "$@" 会扩展为两个参数:

"abc" "def ghi"

$#

扩展到位置参数的数量。

$?

扩展到最新管道的退出状态。

$-

(连字符)扩展为调用时指定的当前选项标志(连接成字符串的单字母选项名称),由 set 内置命令或由 shell 隐式指定。

$$

展开为被调用 shell 的进程 ID。子 shell 保留与其父 shell 相同的 $ 值。

$!

扩展为从当前 shell 执行的最新后台命令的进程 ID。对于管道,进程 ID 是管道中最后一个命令的 ID。如果引用此参数,shell 将记住进程 ID 及其退出状态,直到 wait 内置命令报告进程完成。

$0

(0)如果在命令行上传递,则展开为shell脚本的名称,如果给出了 name 操作数(带有 -c) ,或者传递给shell的参数为0。

以下变量由 shell 设置或对其具有特殊含义:

CDPATH

内置 cd 使用的搜索路径。

EDITOR

与内置 fc 一起使用的后备编辑器。如果未设置,则默认编辑器为 ed(1) 。

FCEDIT

与内置 fc 一起使用的默认编辑器。

HISTSIZE

可访问的先前命令的数量。

HOME

用户的主目录,用于波浪号扩展并作为 cd 内置的默认目录。

IFS

输入字段分隔符。它在启动时按顺序初始化为 ⟨space⟩, ⟨tab⟩ 和 ⟨newline⟩ 。如果 IFS 未设置,此值也适用,但如果设置为空字符串则不适用。有关更多详细信息,请参阅 White Space Splitting 部分。

LINENO

脚本或函数中的当前行号。

MAIL

邮件文件的名称,将检查新邮件的到达。被 MAILPATH 覆盖。

MAILPATH

以冒号 (‘:’) 分隔的文件名列表,供 shell 检查传入邮件。此变量会覆盖 MAIL 设置。一次最多可以监控 10 个邮箱。

OPTIND

getopts 处理的下一个参数的索引。这在启动时被初始化为 1。

PATH

可执行文件的默认搜索路径。有关详细信息,请参阅 Path Search 部分。

PPID

调用的 shell 的父进程 ID。除非此变量在环境中,否则在启动时设置。不反映父进程 ID 的后续更改。子 shell 保留相同的 PPID 值。

PS1

主要提示字符串,默认为 “$ ” ,除非您是超级用户,在这种情况下它默认为 “# 。” PS1 可能包含以下任何格式序列,这些格式序列将替换为给定信息:

\H

此系统的完全限定主机名 (FQDN)。

\h

此系统的主机名。

\u

用户名。

\W

当前工作目录的最后一个组件。

\w

当前工作目录的完整路径。

\$

超级用户状态。 “$” 代表普通用户, “#” 代表超级用户。

\\

文字反斜杠。

PS2

辅助提示字符串,默认为 “> 。” PS2- 可能包含来自 PS1 的任何格式化序列。

PS4

跟踪输出的前缀(如果 -x 处于活动状态)。默认为 “+ 。

本节描述了对单词执行的各种扩展。并非对每个单词都执行所有扩展,如后面所述。

发生在单个单词中的波浪号扩展、参数扩展、命令替换、算术扩展和引号删除扩展为单个字段。只有字段拆分或路径名扩展才能从单个单词创建多个字段。该规则的唯一例外是特殊参数 @ 在双引号内的扩展,如上所述。

词扩展顺序为:

  1. 波浪号扩展、参数扩展、命令替换、算术扩展(这些都同时发生)。

  2. 除非 IFS 变量为空,否则对步骤 (1) 生成的字段执行字段拆分。

  3. 路径名扩展(除非 -f 选项有效)。

  4. 引用删除。

$’ 字符用于引入参数扩展、命令替换或算术扩展。

以不带引号的波浪号字符 (‘~’) 开头的单词会进行波浪号扩展。直到斜杠 (‘/’) 或单词结尾的所有字符都被视为用户名,并替换为用户的主目录。如果缺少用户名(如 ~/foobar ),波浪号将替换为 HOME 变量的值(当前用户的主目录)。

参数扩展格式如下:

${expression}

其中 expression 由匹配 ‘}’ 之前的所有字符组成。任何被反斜杠转义的 ‘}’ 或在单引号或双引号字符串中的任何 ‘}’ ,以及嵌入式算术扩展、命令替换和变量扩展中的字符,都不会在确定匹配的 ‘}’ 时进行检查。如果变体带有 ‘+ 、’ ‘- 、’ ‘=’ 或 ‘?’ 出现在双引号字符串中,作为扩展,可能有未引用的部分(通过扩展内的双引号);在确定匹配的 ‘}’ 时,也不会检查这些部分中的 ‘} 。

参数扩展的最简单形式是:

${parameter}

parameter 的值(如果有)将被替换。

参数名称或符号可以用大括号括起来,这是可选的,除了具有多于一位的位置参数或当参数后跟一个可以解释为名称一部分的字符时。如果双引号内出现参数扩展:

  1. 除了特殊参数 @ 外,不会对展开的结果进行字段拆分。

  2. 不会对扩展结果执行路径名扩展。

此外,可以使用以下格式之一来修改参数扩展。

${parameter:-word}

使用默认值。如果 parameter 未设置或为空,则替换 word 的扩展;否则, parameter 的值被替换。

${parameter:=word}

分配默认值。如果 parameter 未设置或为空,则将 word 的扩展分配给 parameter 。 在所有情况下, parameter 的最终值都会被替换。在 word 内引用不会阻止字段拆分或路径名扩展。只能以这种方式分配变量,而不是位置参数或特殊参数。

${parameter:?[word]}

如果为 Null 或未设置,则指示错误。如果 parameter 未设置或为空,则将 word 的扩展(或如果省略 word 则指示未设置的消息)写入标准错误,并且 shell 以非零退出状态退出。否则, parameter 的值被替换。交互式 shell 不需要退出。

${parameter:+word}

使用替代值。如果 parameter 未设置或为空,则替换为空;否则,替换 word 的扩展。

在前面显示的参数扩展中,在格式中使用冒号会导致测试未设置或为空的参数;省略冒号会导致测试仅未设置的参数。

这个 word 继承了周围引号的类型(非引号、双引号或 heredocument ),但在删除引号时,引号后括号的反斜杠会被删除。

${#parameter}

字符串长度。 parameter 值的字符长度。

以下四种参数扩展提供了子字符串处理。在每种情况下,模式匹配表示法(请参阅 Shell 模式)) 而不是正则表达式表示法用于评估模式。如果 parameter 是特殊参数 * 或 @ 之一,则扩展的结果是未指定的。将完整的参数扩展字符串括在双引号中不会导致以下四种模式字符被引用,而在大括号内引用字符具有此效果。

${parameter%word}

删除最小后缀模式。这个 word 参数扩展的结果是 parameter ,删除模式所附加的后缀中最小的部分。

${parameter%%word}

删除最大后缀模式。这个 word 被扩展以产生一个模式。参数扩展的结果是 parameter ,与模式匹配的后缀的最大部分被删除。

${parameter#word}

删除最小前缀模式。这个 word 被扩展以产生一个模式。参数扩展的结果是 parameter ,模式匹配的前缀中最小的部分被删除。

${parameter##word}

删除最大前缀模式。这个 word 被扩展以产生一个模式。参数扩展的结果是 parameter ,模式匹配的前缀的最大部分被删除。

命令替换允许替换命令的输出来代替命令名称本身。当命令包含以下内容时,会发生命令替换:

$(command)

或反引号版本:

`command`

shell 通过执行命令并用命令的标准输出替换命令替换来扩展命令替换,在替换结束时删除一个或多个换行符的序列。输出结束前嵌入的换行符不会被移除;但是,在字段拆分期间,它们可能会根据 IFS 的值和有效的引用转换为空格。该命令在子 shell 环境中执行,除了内置命令 jobid, jobstrap 返回父 shell 环境的信息,如果它们是命令替换中唯一的命令,则 times 返回关于同一进程的信息。

如果 $( 形式的命令替换以子 shell 开头,则 $(( 必须用空格分隔以避免算术扩展的歧义。

算术扩展提供了一种计算算术表达式并代入其值的机制。算术展开的格式如下:

$((expression))

expression 被视为在双引号中,但表达式中的双引号没有被特殊处理。shell 扩展 expression 中的所有标记以进行参数扩展、命令替换、算术扩展和引号删除。

允许的表达式是 C 表达式的子集,总结如下。

数值

所有值都是 intmax_t 类型。

常数

十进制、八进制(以 0 开头)和十六进制(以 0x 开头)整数常量。

变量

Shell 变量可以读写,并且包含整数常量。

一元运算符

! ~ + -

二元运算符

* / % + - << >> < <= > >= == != & ^ | && ||

赋值运算符

= += -= *= /= %= <<= >>= &= ^= |=

条件运算符

? :

表达式的结果以十进制替换。

在某些情况下,在参数扩展、命令替换和算术扩展之后,shell 会扫描未出现在双引号中的扩展和替换结果以进行字段拆分,并且可能会导致多个字段。

IFS 中的空白字符 (⟨space 、⟩ ⟨tab⟩ 和 ⟨newline⟩) 的处理方式与 IFS 中的其他字符不同。

IFS 中单词开头或结尾的空格将被丢弃。

随后,一个字段由以下任一分隔

  1. IFS 中的非空白字符,其周围有 IFS 中的任何空白,或

  2. IFS 中的一个或多个空白字符。

如果单词在 IFS 中以非空白字符结尾,则该字符后没有空字段。

如果没有分隔字段,则丢弃该单词。特别是,如果一个词仅由一个不带引号的替换组成并且替换的结果为空,则即使 IFS 为空,它也会通过字段拆分被删除。

除非设置了 -f 选项,否则在分词完成后执行文件名生成。每个单词都被视为一系列模式,由斜线分隔。扩展过程将单词替换为所有现有文件的名称,这些文件的名称可以通过将每个模式替换为与指定模式匹配的字符串来形成。对此有两个限制:首先,模式不能匹配包含斜杠的字符串,其次,模式不能匹配以句点开头的字符串,除非模式的第一个字符是句点。下一节将描述用于路径名扩展的模式、用于子字符串处理的四种参数扩展和 case 命令。

模式由匹配自身的普通字符和元字符组成。元字符是 ‘* 、’ ‘?’ 和 ‘[ 。’ 如果引用这些字符,它们将失去其特殊含义。当执行命令或变量替换并且美元符号或反引号没有双引号时,将扫描变量的值或命令的输出以查找这些字符并将它们转换为元字符。

星号 (‘*’) 匹配任何字符串。问号 (‘?’) 匹配任何单个字符。左括号 (‘[’) 引入了一个字符类。字符类的结尾用 ‘]’ 表示;如果 ‘]’ 缺失,则 ‘[’ 匹配 ‘[’ 而不是引入字符类。字符类匹配方括号之间的任何字符。可以使用减号指定与语言环境相关的字符范围。一个命名的字符类(参见 wctype(3) )可以通过用 ‘[:’ 和 ‘:]’ 包围名称来指定。例如, ‘[[:alpha:]]’ 是一个匹配单个字母的 shell 模式。可以通过将感叹号 (‘!’) 作为字符类的第一个字符来补充字符类。插入符号 (‘^’) 具有相同的效果,但不是标准的。

要在字符类中包含 ‘]’ ,请将其设为列出的第一个字符(在 ‘!’ 或 ‘^’ 之后,如果有的话)。要包含 ‘-’ ,请将其设为列出的第一个或最后一个字符。

本节列出了内置命令。

:

返回 0 (true) 退出值的空命令。

. file

指定文件中的命令由 shell 读取和执行。 return 命令可用于返回 . 命令的调用者。如果文件包含任何 ‘/’ 字符,则按原样使用。否则,shell 会在 PATH 中搜索该文件。如果在 PATH 中找不到它,则在当前工作目录中查找它。

[

test(1) 的内置等效项。

alias [name[=string] ...]

如果指定 name=string ,shell将别名 name 定义为值 string 。 如果只指定 name ,则打印别名 name 的值。在没有参数的情况下, alias 内置命令会打印所有已定义别名的名称和值(请参阅 unalias )。别名值用适当的引号写入,以便它们适合重新输入到 shell。另请参阅 别名 小节。

bg [job ...]

在后台继续指定的作业(如果没有给出作业,则继续当前作业)。

bind [-aeklrsv] [key [command]]

列出或更改行编辑器的键绑定。此命令记录在 editrc(5) 中。

break [num]

请参阅 流控制结构 小节。

builtin cmd [arg ...]

执行指定的内置命令 cmd 。当用户希望覆盖与内置命令同名的 shell 函数时,这很有用。

cd [-L | -P] [-e] [directory]

cd -

切换到指定 directory, 如果没有指定 directory ,则切换到 HOME 环境变量中指定的目录;如果 directory 为 - ,则切换到 OLDPWD 环境变量中指定的目录。如果 directory 不以 /, . 或 .. 开头,则将在 CDPATH 变量中列出的目录中搜索指定 directory 。如果未设置 CDPATH ,则搜索当前目录。 CDPATH 的格式与 PATH 的格式相同。在交互式 shell 中,如果使用 CDPATH 机制或 directory 为 -cd 命令将打印出它实际切换到的目录的名称。

如果指定 -P 选项,则在处理 .. 组件之前对 .. 进行物理处理并解析符号链接。如果指定 -L 选项,则按逻辑处理 .. 。这是默认设置。

如果新目录的完整路径名无法可靠地确定或根本无法确定,则 -e 选项会导致 cd 返回退出状态 1。通常这不会被视为错误,尽管会打印警告。

如果更改目录失败,则退出状态大于 1。如果更改目录,则退出状态为 0,如果给出 -e ,则退出状态为 1。

chdir

cd 内置命令的同义词。

command [-p] [utility [argument ...]]

command [-p] -v utility

command [-p] -V utility

第一种调用形式执行指定的 utility, 忽略搜索中的 shell 函数。如果 utility 是一个特殊的内置函数,它会像普通的内置函数一样执行。

如果指定 -p 选项,则使用保证找到所有标准实用程序的默认值 PATH that 执行命令搜索。

如果指定 -v 选项,则不执行 utility ,但会打印 shell 对其解释的描述。对于普通命令,输出是路径名;对于 shell 内置命令、shell 函数和关键字,仅写入名称。别名打印为 “alias name=value 。”

除了输出之外, -V 选项与 -v 相同。它打印 “utility is description” ,其中 description 是 utility 的路径名、特殊的 shell 内置函数、shell 内置函数、shell 函数、shell 关键字或 value 的别名。

continue [num]

请参阅 流控制结构 小节。

echo [-e | -n] [string ...]

将空格分隔的参数列表打印到标准输出并附加换行符。

-n

抑制尾随换行符的输出。

-e

处理 C 风格的反斜杠转义序列。 echo 命令理解以下字符转义:

\a

警报(敲响终端铃声)

\b

退格

\c

抑制尾随换行符(如果它不是最后一个字符,这具有截断行的副作用)

\e

ESC 字符(ASCII 0x1b)

\f

换页

换行

回车

水平制表符

\v

垂直制表符

\\

文字反斜杠

\0nnn

(零)八进制值为 nnn 的字符

如果 string 没有用引号括起来,那么反斜杠本身必须用反斜杠转义以保护它免受 shell 程序的影响。例如

$ echo -e "a\vb" a b $ echo -e a\\vb a b $ echo -e "a\\b" a\b $ echo -e a\\\\b a\b

只能指定 -e-n 选项之一。

eval string ...

用空格连接所有参数。然后重新解析并执行命令。

exec [command [arg ...]]

除非 command 被省略,否则 shell 进程被替换为指定的程序(必须是真实的程序,而不是 shell 内置的命令或函数)。 exec 命令上的任何重定向都被标记为永久的,因此当 exec 命令完成时它们不会被撤消。

exit [exitstatus]

终止 shell 进程。如果给出 exitstatus ,它将用作 shell 的退出状态。否则,如果 shell 正在执行 EXIT 陷阱,则使用陷阱之前的最后一个命令的退出状态;如果 shell 程序正在执行信号陷阱, shell 程序会通过将信号重新发送给自身来退出。否则,使用前面命令的退出状态。退出状态应该是 0 到 255 之间的整数。

export name ...

export [-p]

导出指定的名称,以便它们出现在后续命令的环境中。取消导出变量的唯一方法是 unset 它。shell 允许在通过写入导出变量的同时设置变量的值

export name=value

不带参数的 export 命令列出所有导出变量的名称。如果指定 -p 选项,则导出的变量将打印为 “export name=value” 行,适合重新输入到 shell。

false

返回非零 (false) 退出值的空命令。

fc [-e editor] [first [last]]

fc -l [-nr] [first [last]]

fc -s [old=new] [first]

fc 内置命令列出或编辑和重新执行以前输入到交互式 shell 的命令。

-e editor

使用 editor 命名的编辑器来编辑命令。 editor 字符串是一个命令名称,可以通过 PATH 变量进行搜索。当未指定 -e 时, FCEDIT 变量中的值用作默认值。如果 FCEDIT 为 null 或未设置,则使用 EDITOR 变量的值。如果 EDITOR 为 null 或未设置,则使用 ed(1) 作为编辑器。

-l (ell)

列出命令而不是在它们上调用编辑器。命令按 first 和 last 操作数指示的顺序写入,受 -r 影响,每个命令前面都有命令编号。

-n

使用 -l 列出时禁止显示命令编号。

-r

逆序列出(使用 -l )或编辑(既不使用 -l 也不使用 -s )的命令的顺序。

-s

在不调用编辑器的情况下重新执行命令。

first

last

选择要列出或编辑的命令。可以访问的先前命令的数量由 HISTSIZE 变量的值决定。 first 或 last 或两者的值是以下之一:

[+]num

一个正数代表一个命令号;可以使用 -l 选项显示命令编号。

-num

一个负十进制数,表示先前执行的命令 num 个命令。例如, -1 是前一个命令。

string

一个字符串,表示以该字符串开头的最近输入的命令。如果 old=new 操作数也未使用 -s 指定,则第一个操作数的字符串形式不能包含嵌入的等号。

以下变量影响 fc 的执行:

FCEDIT

用于历史编辑的编辑器的名称。

HISTSIZE

可访问的先前命令的数量。

fg [job]

将指定 job 或当前 job 移至前台。

getopts optstring var

POSIX getopts 命令。 getopts 命令不推荐使用旧的 getopt(1) 命令。第一个参数应该是一系列字母,每个字母可能后跟一个冒号,表示该选项需要一个参数。指定的变量设置为 parsed 选项。下一个参数的索引被放入 shell 变量 OPTIND 。如果一个选项有一个参数,它会被放入 shell 变量 OPTARG 。如果遇到无效选项,则将 var 设置为 ‘?’ 。当它遇到选项的结尾时,它会返回一个假值 (1)。可以通过分配 OPTIND=1 来解析一组新的参数。

hash [-rv] [command ...]

shell 维护一个哈希表,它记住命令的位置。没有任何参数 hash 命令打印出这个表的内容。

使用参数, hash 命令从散列表中删除每个指定的 command (除非它们是函数),然后定位它。使用 -v 选项, hash 在找到命令时打印它们的位置。 -r 选项使 hash 命令删除散列表中除函数之外的所有条目。

jobid [job]

打印指定 job 中进程的进程 ID。如果省略 job 参数,则使用当前作业。

jobs [-lps] [job ...]

如果没有给出 job 参数,则打印有关指定作业或所有作业的信息。打印的信息包括作业 ID、状态和命令名称。

如果指定 -l 选项,还会打印每个作业的 PID。如果指定 -p 选项,则只打印进程组领导者的进程 ID,每行一个。如果指定 -s 选项,则仅打印作业命令的 PID,每行一个。

kill

kill(1) 的内置等效项,还支持向作业发送信号。

local [variable ...] [-]

请参阅 函数 小节。

printf

printf(1) 的内置等效项。

pwd [-L | -P]

打印当前目录的路径。内置命令可能与同名程序不同,因为内置命令会记住当前目录是什么,而不是每次都重新计算。这使它更快。但是,如果当前目录被重命名, pwd(1)- 的内置版本将继续打印该目录的旧名称。

如果指定 -P 选项,则解析符号链接。如果指定 -L 选项,则打印 shell 的当前目录概念(不解析符号链接)。这是默认设置。

read [-p prompt] [-t timeout] [-er] variable ...

如果指定 -p 选项并且标准输入是终端,则会打印 prompt 。然后从标准输入中读取一行。 从行中删除末尾的换行符,并按照上面的 空格分割(字段分割) 小节中描述的那样分割行符,并将这些片段按顺序分配给变量。 如果片段多于变量,则剩余片段(连同 IFS 中分隔它们的字符)分配给最后一个变量。 如果变量多于片段,则为剩余变量分配空字符串。

反斜杠被特殊处理,除非指定 -r 选项。如果反斜杠后跟换行符,则反斜杠和换行符将被删除。如果反斜杠后跟任何其他字符,则反斜杠将被删除,并且后面的字符将被视为不在 IFS 中,即使它是。

如果指定 -t 选项并且在提供完整的输入行之前 timeout 已经过去,则 read 命令将返回退出状态,就好像被 SIGALRM 终止而不分配任何值一样。 timeout 值可以可选地后跟 ‘s’, ‘m’ 或 ‘h’ 之一,以明确指定秒、分钟或小时。如果没有提供,则假定为 ‘s’ 。

-e 选项的存在只是为了向后兼容旧脚本。

退出状态为 0 表示成功,1 表示文件结束,如果发生错误,退出状态介于 2 和 128 之间,如果捕获信号中断 read ,则退出状态大于 128。

readonly [-p] [name ...]

每个指定的 name 都被标记为只读,因此以后不能对其进行修改或取消设置。shell 允许使用以下形式在将变量标记为只读的同时设置变量的值:

readonly name=value

不带参数的 readonly 命令列出所有只读变量的名称。如果指定 -p 选项,只读变量将打印为 “readonly name=value” 行,适合重新输入到 shell。

return [exitstatus]

请参阅 函数 小节。

set [-/+abCEefIimnpTuVvx] [-/+o longname] [-- arg ...]

set 命令执行三个不同的功能:

  • 没有参数,它列出所有 shell 变量的值。

  • 如果以短形式或使用 “-/+o longname” 形式给出选项,它会设置或清除指定的选项,如 参数列表处理 一节中所述。

  • 如果指定 “--” 选项, set 将用后续参数替换 shell 的位置参数。如果 “--” 选项后面没有参数,则所有位置参数都将被清除,相当于执行命令 “shift $#” 。在指定要用作位置替换参数的参数时,可以省略 “--” 标志。不建议这样做,因为第一个参数可能以破折号 (‘-’) 或加号 (‘+’) 开头, set 命令会将其解释为启用或禁用选项的请求。

setvar variable value

将指定的 value 赋给指定的 variable 。 setvar 命令旨在用于将值分配给名称作为参数传递的变量的函数中。一般来说,最好写 “variable=value” 而不是使用 setvar 。

shift [n]

移动位置参数 n 次,如果 n 未指定,则移动一次。移位将 $1 的值设置为 $2, 的值,将 $2 的值设置为 $3, 的值,依此类推,将 $# 的值减一。为了便携性,如果位置参数为零,则应避免移动,因为 shell 可能会中止。

test

test(1) 的内置等效项。

times

打印执行 shell 进程及其子进程所花费的时间。第一个输出行显示 shell 进程本身的用户和系统时间,第二个输出包含子进程的用户和系统时间。

trap [action] signal ...

trap -l

当接收到任何指定的 signal 时,使 shell 解析并执行 action 。 信号由名称或编号指定。此外,伪信号 EXIT 可以用来指定 shell 终止时执行的 action 。 action 可以是空字符串或破折号 (‘-’); 前者导致指定的信号被忽略,后者导致采取默认操作。 省略 action 并仅使用信号编号是请求默认操作的另一种方式。 在子shell 或实用程序环境中,shell 将捕获的(但不忽略)信号重置为默认操作。 trap 命令对进入 shell 时被忽略的信号没有影响。

选项 -l 使 trap 命令显示有效信号名称的列表。

true

返回 0 (true) 退出值的空命令。

type [name ...]

将每个 name 解释为命令并打印命令搜索的分辨率。可能的解决方案是:shell 关键字、别名、特殊的内置 shell、shell 内置、命令、跟踪的别名和未找到。对于别名,打印别名扩展;对于命令和跟踪别名,将打印命令的完整路径名。

ulimit [-HSabcdfklmnopstuvw] [limit]

设置或显示资源限制(请参阅 getrlimit(2) )。如果指定 limit ,则将设置命名资源;否则将显示当前资源值。

如果指定 -H 将设置或显示硬限制。虽然每个人都可以减少硬限制,但只有超级用户可以增加它。 -S 选项指定软限制。显示限制时,只能给出 -S-H 之一。默认显示软限制,并设置硬限制和软限制。

选项 -a 使 ulimit 命令显示所有资源。在这种模式下参数 limit 是不可接受的。

其余选项指定要显示或修改的资源值。它们是相互排斥的。

-b sbsize

套接字缓冲区使用的最大大小,以字节为单位。

-c coredumpsize

核心转储文件的最大大小,以 512 字节块为单位。将 coredumpsize 设置为 0 可防止创建核心转储文件。

-d datasize

进程数据段的最大大小,以千字节为单位。

-f filesize

文件的最大大小,以 512 字节块为单位。

-k kqueues

此用户 ID 的最大 kqueue 数(请参阅 kqueue(2) )。

-l lockedmem

进程可以锁定的最大内存大小,以千字节为单位。

-m memoryuse

进程的最大驻留集大小,以千字节为单位。

-n nofiles

进程可以打开的最大描述符数。

-o umtxp

此用户 ID 的最大进程共享锁数(请参阅 pthread(3) )。

-p pseudoterminals

此用户 ID 的最大伪终端数。

-s stacksize

堆栈段的最大大小,以千字节为单位。

-t time

每个进程使用的最大 CPU 时间,以秒为单位。

-u userproc

此用户 ID 的最大同时进程数。

-v virtualmem

进程的最大虚拟大小,以千字节为单位。

-w swapuse

为该用户 ID 保留或使用的最大交换空间量,以千字节为单位。

umask [-S] [mask]

设置文件创建掩码(见 umask(2) )为 mask 指定的八进制或符号(见 chmod(1) )值 如果省略参数,则打印当前掩码值。如果指定 -S 选项,则输出为符号,否则输出为八进制。

unalias [-a] [name ...]

删除指定的别名。如果指定 -a ,则删除所有别名。

unset [-fv] name ...

指定的变量或函数未设置且未导出。如果指定 -v 选项或未指定选项,则 name 参数将被视为变量名。如果指定 -f 选项,则 name 参数将被视为函数名称。

wait [job ...]

等待每个指定 job 完成并返回最后一个指定 job 中最后一个进程的退出状态。如果指定的任何 job 对于 shell 来说是未知的,则将其视为以退出状态 127 退出的已知作业。如果没有给出操作数,则等待所有作业完成并返回退出状态为零。

当从终端交互使用 sh 时,可以使用 vi-mode 令行编辑来编辑当前命令和命令历史记录(参见 内置命令 中的 fc )。 此模式使用的命令类似于 vi(1) 手册页中描述的命令的子集。 命令 “set -o vi” (或 “set -V”) 启用 vi-mode 模式编辑并将 sh 置于 vi 插入模式。启用 vi-mode 后, sh 可以通过键入 ⟨ESC⟩ 在插入模式和命令模式之间切换。在命令模式下按 ⟨return⟩ 会将行传递给 shell。

类似地, “set -o emacs” (或 “set -E”) 命令可用于启用 emacs-style 命令行编辑功能的子集。

以下环境变量会影响 sh 的执行:

ENV

交互式 shell 的初始化文件。

LANG, LC_*

区域设置。这些由 shell 的子代继承,并且由 shell 本身以有限的方式使用。

OLDPWD

上一个当前目录。这由 cd 使用和更新。

PWD

当前目录的绝对路径名,可能包含符号链接。这由 shell 使用和更新。

TERM

shell 的默认终端设置。这是由 shell 的子代继承的,用于历史编辑模式。

此外,环境变量在启动时会转换为 shell 变量,这可能会影响 Special Variables 中所述的 shell。

~/.profile

用户的登录配置文件。

/etc/profile

系统登录配置文件。

/etc/shells

Shell 数据库。

/etc/suid_profile

特权 shell 配置文件。

如果找不到 script ,则退出状态为 127;如果由于其他原因无法打开,则退出状态将为 126。shell 检测到的其他错误,例如语法错误,将导致 shell 以非零退出状态退出。如果 shell 不是交互式 shell,则 shell 文件的执行将被中止。否则,shell 将返回最后执行的命令的退出状态,或者如果 exit 内置函数与数字参数一起使用,它将返回该参数。

builtin(1), chsh(1), echo(1), ed(1), emacs(1), kill(1), printf(1), pwd(1), test(1), vi(1), execve(2), getrlimit(2), umask(2), wctype(3), editrc(5), shells(5)

sh 命令,即 Thompson shell,出现在版本 Version 1 AT&T UNIX 中。它在版本 Version 7 AT&T UNIX 中被继承名称 sh 的 Bourne shell 取代。

这个版本的 sh 在 BSD 许可下于 1989 年在 AT&T System V Release 4 UNIX 的 Bourne shell 之后被重写。

这个版本的 sh 最初是由 Kenneth Almquist 编写的。

sh 实用程序不识别 UTF-8 以外的多字节字符。使用 IFS 进行拆分无法识别多字节字符。

July 6, 2020

FreeBSD 13.1-RELEASE

最后更新于

FreeBSD 中文社区