手册页部分 1: 用户命令

退出打印视图

更新时间: 2014 年 7 月
 
 

jsh(1)

名称

sh , jsh - 标准及作业控制 shell 和命令解释程序

用法概要

/usr/sunos/bin/sh  [-acefhiknprstuvx] [argument]...
/usr/xpg4/bin/sh  [± abCefhikmnoprstuvx]
     [± o option]... [-c string] [arg]...
/usr/sunos/bin/jsh  [-acefhiknprstuvx] [argument]...

描述

/usr/sunos/bin/sh 实用程序是一种命令编程语言,用于执行从终端或文件读取的命令。

/usr/xpg4/bin/sh 实用程序是一个符合标准的 shell。除了 ksh88(1) 中讨论的存在行为差异的情况以外,此实用程序可提供 ksh88(1) 的全部功能。

jsh 实用程序是 shell 的一个接口,提供 sh 的所有功能,并能实现作业控制(请参见下文的“作业控制”部分)。


注 - /usr/bin/sh/usr/bin/jsh 是指向 ksh93 的链接。请参见 ksh93(1)

在下文的“调用”部分列出了 shell 的参数。

定义

空白字符是指制表符或空格。名称是以字母或下划线开头的一系列 ASCII 字母、数字或下划线。参数可以是名称、数字或以下任意字符:*@#?$!

用法

命令

简单命令是以空白字符分隔的一系列非空白。第一个指定要执行的命令的名称。除非下文中特别指定,否则其余的都将作为参数传递到调用的命令。命令名称作为参数 0 传递(请参见 exec(2))。简单命令在命令正常终止时为退出状态,在命令异常终止时为(八进制)200+状态。有关状态值的列表,请参见 signal.h(3HEAD)

管道是由一个或多个以 | 分隔的命令组成的序列。每个命令(最后一个除外)的标准输出都通过 pipe(2) 连接到下一命令的标准输入。每个命令都作为单独的进程运行。shell 会等待最后一个命令终止。管道的退出状态是管道中最后一个命令的退出状态。

列表是由一个或多个以 ;&&&| | 分隔的管道组成的序列,该序列可以选择性地以 ;& 结束。在这四个符号中,;& 的优先级相同,均低于 &&| | 的优先级。同时,符号 &&| | 也具有相同的优先级。可使用分号 (;) 来按顺序执行前面的管道,也就是,shell 会等到管道完成之后再执行分号后面的命令。和符号 (&) 导致异步执行前面的管道,也即,shell 会等待该管道完成。仅当符号 && ( | |) 前面的管道返回零(非零)退出状态时,该符号才会执行它后面的列表列表中可以显示任意数量的换行符,用来代替分号对命令进行分隔。

命令可以是简单命令或下述命令之一。除非另有说明,命令返回的值就是在该命令中执行的最后一个简单命令所返回的值。

for name [ in word . . . ] do list done

每次执行 for 命令时,name 都会设置为从 in word 列表获取的下一个。如果省略了 in word . . .,for 命令将针对每个已设置的位置参数执行一次 do list(请参见下面的“参数替换”部分)。当此列表中没有任何其他单词时,执行随即结束。

case word in [ pattern [ | pattern ] ) list ; ; ] . . . esac

case 命令执行与 word 匹配的第一个 pattern 的关联 list。模式的格式与用于生成文件名的格式相同(请参见“文件名生成”部分),但斜杠、前导点或紧跟斜杠之后的点不需要明确匹配。

if list ; then list elif list ; then list ; ] . . . [ else list ; ] fi

执行 if 后面的 list,并且如果返回零退出状态,则执行第一个 then 后面的 list。否则执行 elif 后面的 list,如果其值为零,则执行下一个 then 后面的 list。如果失败,则执行 else list。如果未执行 else listthen listif 命令将返回零退出状态。

while list do list done

while 命令反复执行 while list,并且如果此列表中最后一个命令的退出状态为零,则会执行 do list,否则将终止循环。如果未执行 do list 中的命令,while 命令将返回零退出状态,并且可使用 until 替换 while,以便对循环终止测试求反。

(list)

在子 shell 中执行 list

{ list;}

在当前的 shell(即父 shell)中执行 list{ 后面必须跟有空格。

name ( ) { list;}

定义 name 引用的函数。函数主体是 {} 之间的命令的 list{ 后面必须跟有空格。下文介绍了函数的执行过程(请参见“执行”部分)。如果函数主体是上文所述的一个命令(请参见“命令”部分),则不需要使用 {}

以下词只有在不带引号时可识别为命令的第一个词:

if then else elif fi case esac for while until do done { }

注释行

词以 # 开头时,将忽略该词以及后面直至换行符之前的所有字符。

命令替换

shell 将读取两个重音符 (``) 之间的字符串中的命令,这些命令的标准输出可用作单词的一部分或整个单词。标准输出中尾随的换行符将被删除。

除了删除用于转义其他字符的反斜杠 (\),读取字符串之前不会对字符串进行任何解释。反斜杠可用于转义重音符 (`) 或其他反斜杠 (\),并将在读取命令字符串之前被删除。通过对重音符进行转义,可以替换嵌套的命令。如果命令替换位于一对双引号 (" . . . ` . . . ` . . .  ") 内,则用于转义双引号 (\") 的反斜杠将被删除。否则,它将保持原样。

如果使用反斜杠对换行符 (\newline) 进行转义,反斜杠和换行符将同时被删除(请参见后面的“引用”部分)。此外,用于转义美元符号 (\$) 的反斜杠也将被删除。因为在读取命令字符串之前未对其执行参数替换,所以插入用于转义美元字符的反斜杠将不起作用。读取命令字符串时,位于除 \`"newline$ 以外的字符之前的反斜杠将保持原样。

参数替换

字符 $ 用于引入可替换的参数。有两种类型的参数:位置参数和关键字参数。如果参数是一个数字,则为位置参数。位置参数可通过 set 进行赋值。关键字参数(也称为变量)可通过写入以下内容进行赋值:

name=value [ name=value ] . . .

将不会对 value 执行模式匹配。函数和变量不能使用相同的 name

${parameter}

该参数的值(如果有)将被替换。只有在 parameter 后跟有不会被解释为其名称的一部分的字母、数字或下划线时,才需要使用大括号。如果 parameter* @,则替换所有以 $1 开头的位置参数(以空格分隔)。当调用 shell 时,参数 $0 从参数零开始设置。

${parameter:−word}

使用缺省值。如果 parameter 未设置或为 Null,则替换 word 的展开形式;否则,替换 parameter 的值。

${parameter:=word}

分配缺省值。如果 parameter 未设置或为 Null,word 的扩展将分配给 parameter。在所有情况下,都会替换为 parameter 的最终值。采用这种方式只能为变量赋值,不能为位置参数或特殊参数赋值。

${parameter:?word}

如果 parameter 已设置且不为 Null,则替换其值;否则,输出 word 并从 shell 退出。如果省略了 word,则输出 “parameter null or not set” 消息。

${parameter:+word}

如果 parameter 已设置且不为 Null,则替换 word;否则不替换任何内容。

在上述示例中,除非将 word 用作被替换的字符串,否则不会对它求值,因此,在下述示例中,仅当 d 未设置或为 Null 时才会执行 pwd

echo  ${d:−`pwd`}

如果上述表达式中省略了冒号 (:),此 shell 仅检查是否设置了 parameter

shell 自动设置下列参数。

#

位置参数的数目(以十进制表示)。

在调用时或通过 set 命令向 shell 提供的标志。

?

同步执行的最后一个命令所返回的十进制值。

$

此 shell 的进程数。

!

调用的最后一个后台命令的进程编号。

shell 使用下列参数。本部分中的参数也称为环境变量。

HOME

cd 命令的缺省参数(起始目录),由 login(1) 通过口令文件将其设置为用户登录目录(请参见 passwd(4))。

PATH

命令的搜索路径(请参见下面的“执行”部分)。

CDPATH

cd 命令的搜索路径。

MAIL

如果此参数设置为邮件文件的名称,未设置 MAILPATH 参数,则 shell 会在邮件到达指定文件时通知用户。

MAILCHECK

此参数指定 shell 对在 MAILPATHMAIL 参数指定的文件中是否接收到邮件进行检查的频率(以秒为单位)。缺省值是 600 秒(10 分钟)。如果该值设置为 0,shell 会在发出每个提示前进行检查。

MAILPATH

以冒号分隔的文件名列表。如果设置了此参数,shell 会在邮件到达任何指定的文件时通知用户。每个文件名后都可以带有 % 以及修改时间发生更改时输出的消息。缺省消息为:you have mail

PS1

主提示字符串,缺省情况下为 “ $  ”。

PS2

辅助提示字符串,缺省情况下为 “ >  ”。

IFS

内部字段分隔符,通常情况下为 spacetabnewline(请参见“空白解释”部分)。

SHACCT

如果此参数设置为用户可写文件的名称,则 shell 会在文件中写入每个所执行的 shell 过程的记帐记录。

SHELL

当调用 shell 时,它将在环境(请参见下面的“环境”部分)中扫描此名称。

有关影响 sh 执行的环境变量 LC_CTYPE 和 LC_MESSAGES 的描述,请参见 environ(5)

shell 将对 PATH、PS1、PS2、MAILCHECK 和 IFS 赋予缺省值。HOME 和 MAIL 的缺省值由 login(1) 设置。

对空白的解释

执行参数和命令替换之后,将扫描替换结果中的内部字段分隔符(即位于 IFS 中的字段分隔符),并在找到此类字符的位置将结果分隔为不同参数。系统将保留显式 Null 参数(""'')。删除隐式 Null 参数(这些参数是由没有任何值的 parameter 生成的)。

输入/输出重定向

使用由 shell 解释的特殊表示法可以重定向命令的输入和输出。以下内容可显示在简单命令的任意位置,也可以位于命令之前或之后,并且会作为参数传递给调用的命令。注意:在使用 worddigit 之前,将先执行参数和命令替换。

<word

使用文件 word 作为标准输入(文件描述符 0)。

>word

使用文件 word 作为标准输出(文件描述符 1)。如果文件不存在,则会创建一个文件;否则会将其截断为零长度。

>>word

使用文件 word 作为标准输出。如果文件存在,则会将输出附加到此文件(通过首先查找到 EOF)。否则会创建文件。

< >word

打开文件 word 以便作为标准输入读取和写入。

<<[]word

word 执行完参数和命令替换之后,将读取到 shell 输入中与所生成的 word 在字面上相匹配的第一行,或者读取到 EOF。但是,如果将连字符 () 附加到 <<,则:

  1. 在读取 shell 输入之前(但在对 word 执行完参数和命令替换之后),从 word 删除前导制表符;

  2. 在读取 shell 输入之后以及将每行与 word 进行比较之前,从 shell 输入删除前导制表符;

  3. 读取到 shell 输入中与所生成的 word 在字面上相匹配的第一行,或者读取到 EOF。

如果引用了 word 的任一字符(请参见下文的“引用”部分),则不对 shell 输入作任何其他处理。如果未引用 word 的任何字符,则:

  1. 执行参数和命令替换;

  2. 删除(转义的)\newline

  3. 必须使用 \ 来引用字符 \$`

所生成的文档将成为标准输入。

<&digit

使用与文件描述符 digit 相关联的文件作为标准输入。类似地,对于标准输出,请使用 >&digit

<&−

关闭标准输入。类似地,对于标准输出,请使用 >&−

如果上述任一内容的前面带有一个数字,则与文件相关联的文件描述符为通过该数字(并非缺省值 01)指定的描述符。例如:

... 2>&1

将文件描述符 2 与文件描述符 1 的当前关联文件相关联。

重定向的指定顺序至关重要。shell 将按从左至右的顺序对重定向求值。例如:

... 1>xxx 2>&1

首先将文件描述符 1 与文件 xxx 关联。然后,它将文件描述符 2 与文件描述符 1 的关联文件(即 xxx)相关联。如果颠倒重定向顺序,文件描述符 2 将与终端关联(假定文件描述符 1 已与此终端关联),文件描述符 1 将与文件 xxx 关联。

按照第一页上(请参见“命令”部分)介绍的术语,如果一个命令包含多个简单命令,则在对每个简单命令的重定向求值之前,将先对整个命令的重定向求值。也就是说,shell 将按照以下顺序对重定向求值:整个列表列表中的每个管道、每个管道中的每个命令、每个命令中的每个列表

如果命令后跟有 &,则该命令的缺省标准输入为空文件 /dev/null。否则,命令执行环境包含调用根据输入/输出规范修改的 shell 的文件描述符。

文件名生成

在执行命令之前,会对每个命令进行扫描,以确认是否存在 *?[ 字符。如果出现其中的某个字符,则将该词视为一个模式。该词将替换为按字母顺序排序且与模式匹配的文件名称。如果未找到与该模式相匹配的文件名,该词将保持不变。位于文件名开头或紧跟 / 之后的字符 . 以及 / 本身必须明确匹配。

*

匹配任何字符串,包括空字符串。

?

匹配任何单个字符。

[. . .]

匹配其中包围的任意一个字符。使用 分隔的一对字符将在词汇上匹配这对字符之间的任何字符,包括这对字符。如果左 [ 后面的第一个字符为 !,则匹配任何不包括的字符。

请注意,文件名中所有已引用的字符(请参见下文)均必须明确匹配。

引用

以下字符对 shell 具有特殊含义,并且会导致词终止(除非被引用):

; & ( ) | ^ < > newline space tab

通过在字符前面添加一个反斜杠 (\),或将其插入一对引号( ' '"")之间,可以引用一个字符(即,使字符代表其本身)。在处理期间,shell 可以引用部分字符,从而使其不具备特殊含义。在执行命令之前,用来引用单个字符的反斜杠将从词中删除。在执行命令和参数替换之前,\newline 对将从词中删除。

shell 将引用所有包含在一对单引号 ( ' ') 之内的字符(单引号除外)。一对单引号内的反斜杠无特殊含义。可以在一对双引号中引用单引号(如 " '"),但不能在一对单引号中引用单引号。

字符包含在一对双引号 ("") 内时,将执行参数和命令替换,并且 shell 将引用结果,以避免出现空白解释和生成文件名。如果 $* 包含在一对双引号内,位置参数将被替换和引用,各参数之间以带引号的空格分隔 ("$1  $2  . . .")。但是,如果 $@ 包含在一对双引号内,位置参数将被替换和引用,各参数之间以不带引号的空格分隔 ("$1" "$2"   . . .)。\ 引用字符 \`,(逗号)和 $。在执行参数和命令替换之前,\newline 对将被删除。如果在除 \`,(逗号)、$ 和换行符以外的字符前面添加一个反斜杠,则 shell 将引用该反斜杠本身。

提示

在交互使用时,shell 会先通过 PS1 的值进行提示,然后再读取命令。如果在任何时间键入了换行符,并且需要进行更多输入才能完成命令,则会发出辅助提示(即 PS2 的值)。

环境

环境(请参见 environ(5))是按照标准参数列表的相同传递方式传递给执行程序的名称-值对列表。shell 采用多种方式与环境交互。在调用时,shell 会对环境进行扫描,并为找到的每个名称创建一个参数,同时为参数指定对应的值。如果用户修改任何这些参数的值,或者创建新的参数,修改后或新创建的参数将不会对环境产生影响,除非使用 export 命令将 shell 的参数绑定到环境(另请参见 set –a)。可以使用 unset 命令将参数从环境中删除。因此,通过任何已执行的命令显示的环境由 shell 最初继承的所有未修改名称-值对(unset 所删除的名称-值对除外)以及必须在 export 命令中说明的所有修改或添加内容组成。

通过在简单命令的前面添加一个或多个参数赋值作为前缀,可以扩展简单命令的环境。因此:

TERM=450  command

(export TERM; TERM=450;   command

command 执行方面是等效的(在 command 不是特殊命令的情况下)。如果 command 是一个特殊命令,则会

TERM=450   command

修改当前 shell 中的 TERM 变量。

如果设置了 –k 标志,则会将所有关键字参数都会放在环境中,即使这些关键字参数出现在命令名称之后也是如此。以下示例首先输出 a=b c,然后输出 c

echo a=b  c

a=b  c

set  −k

echo a=b  c

c

信号

如果调用的命令后跟有 &,则会忽略该命令的 INTERRUPT 和 QUIT 信号。否则,信号具有 shell 从父 shell 继承的值,信号 11 除外(另请参见下面的 trap 命令)。

执行

每次执行命令时,都会执行上面所述的命令替换、参数替换、空白解释、输入/输出重定向和文件名生成。如果命令名称与定义函数的名称相匹配,则会在 shell 进程中执行此函数(请注意它与执行需使用子 shell 进行调用的 shell 脚本文件的区别)。如果命令名称与定义函数的名称不匹配,但与下面“特殊命令”部分中列出的任一命令相匹配,也会在 shell 进程中执行该函数。

将位置参数 $1$2、. . . 设置为该函数的参数。如果命令名称既不与“特殊命令”部分中的任意命令相匹配,也不与定义函数的名称相匹配,则会创建一个新进程,并尝试通过 exec(2) 执行命令。

shell 参数 PATH 定义此命令所在的目录的搜索路径。备用路径名称使用冒号 (:) 分隔。sh 的路径为 /usr/sunos/bin。当前目录是通过空路径名指定的,可以直接显示在等号之后,也可以显示在路径列表中任何位置处的两个冒号分隔符之间或路径列表的末尾。如果命令名称包含 (/),则不会使用搜索路径。否则,将在路径中的每个目录中搜索可执行文件。如果此文件具有执行权限,但不是 a.out 文件,则假定此文件是含有 shell 命令的文件。系统会派生一个子 shell 来读取此文件。带有括号的命令同样必须在子 shell 中执行。

shell 将记住命令在搜索路径中所处的位置(以免以后执行不必要的操作)。如果命令存在于相对目录中,则其位置必须在每次更改当前目录时重新进行确定。每当更改 PATH 变量或执行 hash –r 命令时,shell 都会忘记所有已记住的位置(请参见下文)。

特殊命令

允许对这些命令执行输入/输出重定向。文件描述符 1 是缺省输出位置。启用作业控制后,将向 shell 的环境添加其他特殊命令(参见下面的“作业控制”部分)。

:

无影响;命令不执行任何操作。返回零退出代码。

.  filename

读取和执行 filename 中的命令并返回。PATH 指定的搜索路径用于查找包含 filename 的目录。

bg [%jobid . . .]

启用作业控制后,将向用户环境添加 bg 命令以操纵作业。继续执行后台中停止的作业。如果省略了 %jobid,则采用当前作业。(有关更多详细信息,请参见下面的“作业控制”部分。)

break [ n ]

从封闭的 forwhile 循环中(如果有)中退出。如果指定了 n,则 break n 个级别。

cd [ argument ]

将当前目录更改为 argument。shell 参数 HOME 是缺省的 argument。shell 参数 CDPATH 定义包含 argument 的目录的搜索路径。备用路径名称使用冒号 (:) 分隔。缺省路径是 <null>(指定当前目录)。注意:当前目录是通过空路径名指定的,可以直接显示在等号之后或显示在路径列表中任何其他位置的冒号分隔符之间。如果 argument/ 开头,则不使用搜索路径。否则,将搜索路径中每个目录的 argument

chdir [ dir ]

chdir 将 shell 的工作目录更改为目录 dir。如果未指定参数,则更改为用户的起始目录。如果当前目录中不存在 dir 这一相对路径名称,则检查 CDPATH 变量中列出的目录内是否存在该名称。如果 dir 是其值以 / 开头的 shell 变量的名称,则更改为该值指定的目录。

continue [ n ]

继续执行封闭的 forwhile 循环的下一次重复。如果指定了 n,则从第 n 次封闭式循环继续执行。

echo [ arguments . . . ]

arguments 中的词将写入 shell 的标准输出(以空格字符分隔)。请参见 echo(1) 了解详细的用法和说明。

eval [ argument . . . ]

将这些参数作为输入读取到 shell 并执行生成的命令。

exec [ argument . . . ]

将执行这些参数指定的命令而不是执行此 shell,同时不创建新进程。可以显示输入/输出参数,并可通过这些参数来修改 shell 输入/输出(如果未指定其他参数)。

exit [ n ]

导致调用 shell 或 shell 脚本退出,退出状态由 n 指定。如果省略了 n,则退出状态为最后执行的命令的退出状态(EOF 也会导致 shell 退出)。

export [ name . . . ]

对指定的 name 添加标记,以便自动导出到随后执行的命令的环境。如果未指定任何参数,则列出已标记为在执行当前 shell 期间导出的所有变量名称。(只有当在当前 shell 执行期间再次导出从父 shell 中导出的变量名称时,才会列出从父 shell 中导出的变量名称。)函数名称不会导出。

fg [%jobid . . .]

启用作业控制后,将向用户环境添加 fg 命令以操纵作业。此命令用于继续执行前台中停止的作业,并同时将执行中的后台作业移动至前台。如果省略了 % jobid,则采用当前作业。(有关更多详细信息,请参见下面的“作业控制”部分。)

getopts

使用 shell 内的脚本支持命令语法标准(请参见 Intro(1))。此命令用于解析位置参数和检查合法选项。有关用法和描述,请参见 getoptcvt(1)

hash [ –r ] [ name . . . ]

对于每个 name,shell 都会确定并记录 name 指定的命令搜索路径中的位置。使用 –r 选项时,shell 会清除它记录的所有位置。如果未给定参数,则显示记录的命令的相关信息。Hits 是 shell 进程调用命令的次数。Cost 是找到搜索路径中的命令所需的工作量的衡量方法。如果命令存在于搜索路径内“相对”目录中,则会在切换到该目录中后重新计算该命令的存储位置。完成上述操作的命令由与 hits 信息相邻的星号 (*) 来标明。完成重新计算之后,Cost 将增加。

jobs [–p|–l] [%jobid ...]
jobs –x command [arguments]

报告后台中已停止或正在执行的所有作业。如果省略了 %jobid,则报告后台中已停止或正在运行的所有作业。(有关更多详细信息,请参见下面的“作业控制”部分。)

kill [ sig ] %job . . .
kill –l

向指定作业或进程发送 TERM(终端)信号或指定信号。信号可通过数字或名称来指定(如 signal.h(3HEAD) 中除去前缀 “SIG” 的方式指定,例外是将 SIGCHD 命名为 CHLD)。如果发送的信号是 TERM(终止)或 HUP(挂起),如果作业或进程已停止,则会向其发送 CONT(继续)信号。参数 job 可以是不属于某个活动作业的进程的进程 ID。请参见下面的“作业控制”部分了解 job 格式的说明。如果使用第二种形式,即 kill –l,则会列出信号编号和名称。(请参见 kill(1)。)

login [ argument . . . ]

等效于 `exec login argument. . . .'有关用法和描述,请参见 login(1)

newgrp [ argument ]

等效于 exec newgrp=argument。请参见 newgrp(1) 了解用法和说明。

pwd

输出当前的工作目录。请参见 pwd(1) 了解用法和说明。

read name . . .

从标准输入读取某一行,使用内部字段分隔符 IFS(通常为空格或制表符)限定词边界后,将第一个词分配给第一个 name,将第二个词分配给第二个 name,依次类推,将剩余的词分配给最后一个 name。可使用 \newline 续行。newline 以外的字符可通过在前面加上反斜杠来引用。在将单词分配给 names 之前,这些反斜杠会被删除,而且系统不会解释反斜杠之后的字符。除非遇到 EOF,否则返回代码为 0

readonly [ name . . . ]

将指定 name 标记为 readonly,且不能通过后续赋值更改这些 name 的值。如果未给定参数,则会输出所有 readonly 名称的列表。

return [ n ]

使函数以 n 指定的返回值退出。如果省略 n,则返回状态为最后执行的命令的返回状态。

set [ –aefhkntuvx [ argument . . . ] ]
–a

对所修改或创建的变量添加标记,以便导出。

–e

在某命令以非零退出状态退出时立即退出。

–f

禁用文件名生成。

–h

在定义函数时查找并记住函数命令(函数命令通常会在执行函数时找到)。

–k

将所有关键字参数放在命令的环境中,而不仅仅是命令名称前面的参数。

–n

读取命令,但不执行这些命令。

–t

读取和执行一个命令后退出。

–u

在替换时将 unset 变量视为错误。

–v

在读取 shell 输入行时输出这些行。

–x

在执行命令及其参数时输出这些命令及其参数。

不更改任何标志;在将 $1 设置为 时非常有用。

使用 +(而非 )将导致禁用这些标志。此外,还可以在调用 shell 时使用这些标志。当前标志集可在 $− 中找到。其余的参数都属于位置参数,并将按顺序分配到 $1$2、. . .。如果未指定任何参数,则输出所有名称的值。

shift [ n ]

$n+1 . . . 中的位置参数重命名为 $1 . . .。如果未指定 n,则假定它为 1。

stop pid . . .

停止执行进程号 pid。(请参见 ps(1))。

suspend

停止执行当前 shell(如果是登录 shell,则不停止)。

test

对条件表达式求值。请参见 test(1) 了解用法和说明。

times

针对从 shell 运行的进程输出累计的用户和系统时间。

trap [ argument n [ n2 . . . ]]

当 shell 接收到数字或符号形式的信号 (n) 时,将读取和执行命令 argument。(注意:将在设置完陷阱并获取到陷阱之后对 argument 进行一次扫描。)陷阱命令按照信号编号或对应符号名称的顺序执行。尝试对输入到当前 shell 时忽略的信号设置陷阱将不起作用。尝试对信号 11(内存故障)设置陷阱会生成错误。如果 argument 缺失,则将所有陷阱 n 重置为其初始值。如果 argument 为空字符串,shell 及其调用的命令将忽略此信号。如果 n 为 0,则会在从 shell 退出时执行命令 argument。不带参数的 trap 命令输出与各信号编号关联的命令的列表。

type [ name . . . ]

对于每个 name,此命令指示将其用作命令名称时的解释方式。

ulimit [ [–HS] [–a | –cdfnstv] ]
ulimit [ [–HS] [–c | –d | –f | –n | –s | –t | – v] ] limit

ulimit 将输出或设置硬资源限制或软资源限制。getrlimit(2) 中介绍了这些限制。

如果不存在 limit,则 ulimit 会输出指定的限制。一次可以输出任意数量的限制。–a 选项可输出所有限制。

如果存在 limit,则 ulimit 会将指定的限制设置为 limit。字符串 unlimited 请求删除当前限制(如果有)。所有用户都可以将软限制设置为小于或等于硬限制的任意值。所有用户都可以降低硬限制。只有具有相应特权的用户才可以提高或删除硬限制。请参见 getrlimit(2)

–H 选项指定硬限制。–S 选项指定软限制。如果两个选项均未指定,则 ulimit 将设置这两个限制并输出软限制。

以下选项指定要输出或设置其限制的资源。如果未指定选项,则会输出或设置文件大小限制。

–c

最大核心文件大小(以 512 字节块为单位)

–d

最大数据段或数据堆大小(以千字节为单位)

–f

最大文件大小(以 512 字节块为单位)

–n

最大文件描述符数目加 1

–s

最大栈段大小(以千字节为单位)

–t

最大 CPU 时间(以秒为单位)

–v

最大虚拟内存大小(以千字节为单位)

可以运行 sysdef(1M) 命令来获取适合您的系统的最大可能限制。值采用十六进制格式进行报告,但可使用 bc(1) 实用程序将其转换成十进制数字。请参见 swap(1M)

例如,通过 ulimit 键入以下内容以将核心文件转储的大小限制为 0 兆字节:

ulimit -c 0
umask [ nnn ]

将用户文件创建掩码设置为 nnn(请参见 umask(1))。如果省略了 nnn,则会输出掩码的当前值。

unset [ name . . . ]

对于每个 name,删除对应的变量或函数值。变量 PATH、 PS1、PS2、MAILCHECK 和 IFS 无法取消设置。

wait [ n ]

等待进程 ID 为 n 的后台进程终止,并报告其终止状态。如果省略了 n,则等待 shell 中当前处于活动状态的后台进程终止,并返回代码零。

调用

如果通过 exec(2) 调用 shell,并且参数 0 的第一个字符为 ,则会先从 /etc/profile 读取命令,然后再从 $HOME/.profile 中读取(如果存在此类文件)。其后,将按下述方式读取命令,以 /usr/sunos/bin/sh 的形式调用 shell 时也适用这种方式。以下标志仅在调用时由 shell 进行解释。注意:除非指定了 –c–s 标志,否则会将第一个参数假定为某个命令文件的名称,并将其余参数作为位置参数传递给该命令文件:

–c  string

如果存在 –c 标志,则从 string 读取命令。

–i

如果存在 –i 标志,或者如果 shell 输入和输出附加到终端,则此 shell 为交互式 shell。此种情况下,将忽略 TERMINATE(因此,kill 0 不会中止交互式 shell),并捕获和忽略 INTERRUPT(因此,可以中断 wait)。在所有情况下,shell 将忽略QUIT。

–p

如果存在 –p 标志,则 shell 不会将有效用户和组 ID 设置为实际用户和组 ID。

–r

如果存在 –r 标志,则 shell 为受限 shell(请参见 rsh(1M))。

–s

如果存在 –s 标志,或者如果未保留任何参数,则从标准输入读取命令。其余所有参数将指定位置参数。shell 输出(特殊命令除外)将写入文件描述符 2。

其余标志和参数在上文中的 set 命令下已进行了说明。

作业控制 (jsh)

作为 jsh 调用 shell 时,除了之前所述的适用于 sh 的所有功能外,还会启用作业控制。通常,仅针对交互式 shell 启用作业控制。非交互式 shell 通常无法受益于作业控制提供的附加功能。

启用了作业控制后,用户在终端上输入的每个命令或管道称为一个作业。所有作业会以下列状态之一存在:前台、后台或停止。这些术语的定义如下所述:

  1. 在前台运行的作业具有对控制终端的读写访问权限。

  2. 在后台运行的作业将被拒绝对控制终端进行读取访问,但对控制终端具备有条件的写入访问权限(请参见 stty(1))。

  3. 已停止的作业是指通常由于 SIGTSTP 信号的原因已经置于暂停状态的作业(请参见 signal.h(3HEAD))。

shell 启动的每个作业都分配有一个正整数(称为作业号),该值由 shell 进行跟踪,并作为用来表示特定作业的标识符。此外,shell 还会跟踪当前作业和前一个作业。当前作业是指要启动或重新启动的最新作业。前一个作业是指第一个非当前作业。

可接受的作业标识符的语法为以下形式:

%jobid

其中,jobid 可采用以下任一格式来指定:

%+

用于当前作业。

用于前一个作业。

?<string>

指定命令行唯一地为其包含了 string 的作业。

n

用于作业号 n

pref

其中,pref 是指命令名称的唯一前缀。例如,,如果命令 ls –l name 在后台运行,则可将其称为 %lspref 不能包含空格(除非带引号)。

启用作业控制后,将向用户环境添加以下命令以操纵作业:

bg [%jobid . . .]

继续执行后台中停止的作业。如果省略了 %jobid,则采用当前作业。

fg [%jobid . . .]

继续执行前台中已停止的作业,并同时将执行中的后台作业移动至前台。如果省略了 %jobid,则采用当前作业。

jobs [–p|–l] [%jobid . . .]
jobs –x command [arguments]

报告后台中已停止或正在执行的所有作业。如果省略了 %jobid,则报告后台中已停止或正在运行的所有作业。以下选项用于修改/增强 jobs 的输出:

–l

报告作业的进程组 ID 和工作目录。

–p

仅报告作业的进程组 ID。

–x

用对应的进程组 ID 替换 commandarguments 中存在的 jobid,然后通过传递 arguments 来执行 command

kill [ –signal ] %jobid

内置版本的 kill,可为以 jobid 标识的进程提供 kill 命令的功能。

stop %jobid . . .

停止执行后台作业。

suspend

停止执行当前 shell(如果是登录 shell,则不停止)。

wait [%jobid . . .]

内置的 wait 可接受作业标识符。如果省略了 %jobidwait 将按上述(详见“特殊命令”部分)方式运行。

大型文件行为

有关 shjsh 遇到大于或等于 2 GB(231 字节)文件时行为的说明,请参见 largefile(5)

退出状态

shell 检测到的错误(例如,语法错误)会导致 shell 返回非零退出状态。如果是以非交互方式使用 shell,则放弃执行 shell 文件。否则,shell 将返回执行的最后一个命令的退出状态(另请参见上述 exit 命令)。

仅限 jsh

如果将 shell 作为 jsh 调用,并尝试在有停止的作业时退出 shell,shell 将发出一条警告消息:

There are stopped jobs.

仅会发出这一条消息。如果在有停止的作业的情况下再次尝试退出,则系统会从内核向这些作业发送一个 SIGHUP 信号,然后退出 shell。

文件

$HOME/.profile

/dev/null

/etc/profile

/tmp/sh*

属性

有关下列属性的说明,请参见 attributes(5)

/usr/sunos/bin/sh, /usr/sunos/bin/jsh

属性类型
属性值
可用性
system/core-os
CSI
Enabled(已启用)

/usr/xpg4/bin/sh

属性类型
属性值
可用性
system/core-os
CSI
Enabled(已启用)

另请参见

Intro(1)bc(1)echo(1)getoptcvt(1)kill(1)ksh88(1)ksh93(1)login(1)newgrp(1)pfsh(1)pfexec(1)ps(1)pwd(1)set(1)shell_builtins(1)stty(1)test(1)umask(1)wait(1)rsh(1M)su(1M)swap(1M)sysdef(1M)dup(2)exec(2)fork(2)getrlimit(2)pipe(2)ulimit(2)setlocale(3C)signal.h(3HEAD)passwd(4)profile(4)attributes(5)environ(5)largefile(5)XPG4(5)

警告

强烈建议不要使用 setuid shell 脚本。

附注

输入/输出重定向中用作文件名的词不会解析用于生成文件名(请参见上面的“文件名生成”部分)。例如,cat file1 >a* 创建名为 a* 的文件。

因为管道中的命令是作为单独的进程运行的,因此管道中设置的变量对父 shell 不起任何作用。

如果对 whileuntil 循环的输入或输出进行重定向,循环中的命令会在子 shell 中运行,而且其中设置或更改的变量对父进程不起任何作用:

   lastline=
   while read line
   do

           lastline=$line
   done < /etc/passwd
   echo "lastline=$lastline"       # lastline is empty!

在上述情况下,可使用 exec 对输入或输出进行重定向,具体如下例所示:

   # Save standard input (file descriptor 0) as file
   # descriptor 3, and redirect standard input from the file
   /etc/passwd:

   exec 3<&0               # save standard input as fd 3
   exec </etc/passwd       # redirect input from file

   lastline=
   while read line
   do
           lastline=$line
   done

   exec 0<&3               # restore standard input
   exec 3<&-               # close file descriptor 3
   echo "$lastline"        # lastline

如果收到错误消息 “cannot fork, too many processes”,请尝试使用 wait(1) 命令来清理后台进程。如果上述做法无效,则可能表示系统进程表已满,或者活动的前台进程过多。与登录会话关联的进程 ID 数量以及系统可以跟踪的进程 ID 数量存在一定的限制。

只可以等待管道中的最后一个进程。

如果执行某个命令时在搜索路径中原始命令所在目录之前的目录中发现安装了同名命令,shell 会继续对原始命令应用 exec。使用 hash 命令更正此情况。

Bourne shell 对进程的有效 UID 设有限制。如果此 UID 小于 100(并且不等于进程的实际 UID),则将 UID 重置为进程的实际 UID。

因为 shell 在同一进程组中同时实现前台和后台作业,它们将全部收到相同的信号,这可能导致出现意外行为。因此,建议使用其他作业控制 shell,特别是在交互式环境中。

当 shell 执行的 shell 脚本试图执行不存在的命令解释器时,shell 将返回不正确的诊断消息,指出 shell 脚本文件不存在。