手册页部分 1: 用户命令

退出打印视图

更新时间: 2014 年 7 月
 
 

rksh88(1)

名称

ksh88 , rksh88 - KornShell 是一种标准的/受限的命令与编程语言

用法概要

/usr/sunos/bin/ksh [± abCefhikmnoprstuvx] [± o option]... 
     [arg]...
/usr/sunos/bin/ksh -c [± abCefhikmnoprstuvx] 
     [± o option]... command_string 
     [command_name [arg...]]
/usr/xpg4/bin/sh [± abCefhikmnoprstuvx] 
     [± o option]... [arg]...
/usr/xpg4/bin/sh -c [± abCefhikmnoprstuvx] 
     [± o option]... command_string 
     [command_name [arg...]]
/usr/sunos/bin/rksh [± abCefhikmnoprstuvx] [± o option]... 
     [arg]...
/usr/sunos/bin/rksh -c [± abCefhikmnoprstuvx] 
     [± o option]... command_string 
     [command_name [arg...]]

描述

/usr/xpg4/bin/sh 实用程序是一个符合标准的 shell。此实用程序提供了 /usr/sunos/bin/ksh 的全部功能,但在某些方面存在行为差异。有关详细信息,请参见“算术展开”部分

/usr/sunos/bin/ksh 是一种执行从终端或文件读取的命令的命令与编程语言。rksh 是命令解释程序 ksh 的受限版本;它用于设置登录名和执行环境,而这类登录名和执行环境下的功能较之标准 shell 更为可控。有关此 shell 的各项参数的含义,请参见“调用”部分。

定义

元字符为以下字符之一:

; & ( ) | < > 换行符 空格 制表符

空白为制表符或空格。标识符是以字母或下划线开头的字母、数字或下划线的序列。标识符用作函数变量的名称。是一个字符序列,由一个或多个不带引号的元字符分隔。

命令是 shell 语言的语法中的字符序列。shell 读取各个命令,并直接执行或通过调用单独的实用程序执行所需操作。特殊命令是由 shell 在不创建单独进程的情况下执行的命令。除了手册页记录的负面影响外,大多数特殊命令都可以实现为单独的实用程序。

命令

简单命令是一个以空格分隔的词序列,其前面可以有一个变量赋值列表。请参见“环境”。第一个单词指定要执行的命令的名称。除非特别指定,否则其余词将作为参数传递给所调用的命令。命令名称作为参数 0 传递(请参见 exec(2))。如果简单命令正常终止,则其是其退出状态。如果简单命令由于收到某个信号而异常终止,则其是信号编号加上 128。有关信号值列表,请参见 signal.h(3HEAD)。显然,正常退出状态值 129 到 255 无法与因收到编号为 1 到 127 的信号而导致的异常退出区分开来。

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

列表是由 ;&&&| | 分隔的一个或多个管道构成的序列,而且该序列还可以由 ;&|& 终止。在这五个符号中,;&|& 的优先级相同,这些符号的优先级又低于 &&| |。同时,符号 &&| | 也具有相同的优先级。分号 (;) 导致按顺序执行前面的管道;和符号 (&) 导致异步执行前面的管道,也就是说,shell 不会等待该管道完成。符号 |& 导致异步执行前面的命令或管道,并建立一个到父 shell 的双向管道。

通过使用“特殊命令”中所述的特殊命令 readprint–p 选项,父 shell 可以写入和读取所派生命令的标准输入和输出。符号 && ( | |) 导致仅当前面的管道返回 0(或非零)值时才会执行该符号后面的列表列表中可以使用任意数量的换行符(而非分号)来分隔命令。

命令可以是简单命令或下述命令之一。除非另行说明,否则命令返回的值即为该命令中执行的最后一个简单命令的值。

for identifier [ in word ... ] ; do list ; done

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

select identifier [ in word ... ] ; do list ; done

select 命令在标准错误(文件描述符 2)中输出一组,其中每个词前面均带有一个编号。如果省略了 in word ...,则会改用位置参数。请参见“参数替换”。输出 PS3 提示,并从标准输入中读取一个行。如果此行包含所列出的某个的编号,则变量 identifier 的值会设置为与该编号对应的。如果此行为空,则会再次输出选择列表。否则,变量 identifier 的值会设置为 NULL。(有关 NULL 的信息,请参见“对空白的解释”)。从标准输入读取的行的内容保存在 shell 变量 REPLY 中。在遇到 break 或 EOF 之前,系统会针对每个选择执行 list。如果通过执行 list 将 REPLY 变量设置为 NULL,则会输出选择列表,然后为下一选择显示 PS3 提示。

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

case 命令执行与 word 匹配的第一个 pattern 的关联 list。模式的格式与用于生成文件名的格式相同。请参见文件名生成

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

执行 if 后面的 list,而且,如果它返回退出状态 0,则执行第一个 then 后面的 list。否则,执行 elif 后面的 list,而且,如果其值为0,则执行下一个 then 后面的 list。如果失败,则执行 else list。如果未执行 else list then list,则 if命令会返回退出状态 0。

while list ; do list ; done
until list ; do list ; done

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

(list)

在单独的环境中执行 list。如果需要两个相邻的左括号以便进行嵌套,必须插入一个空格以免执行算术计算。

{list}

完全执行 list。与元字符不同,() 以及 {}保留字,它们必须出现在行开头或 ; 之后才能识别。

[[expression]]

expression 进行评估,并且当 expression 为 true 时返回退出状态 0。有关 expression 的说明,请参见条件表达式

function identifier { list ;}
identifier( ) { list ;}

定义 identifier 引用的函数。函数主体是 {} 之间的命令的 list。请参见函数

time pipeline

执行 pipeline,并将已用时间以及用户和系统时间输出到标准错误。

下列保留字仅在用作命令的第一个词且未带引号时才可识别:


!          if       then     else    elif    fi      case
esac       for      while    until   do      done    {   }
function   select   time     [[  ]]

注释

如果某个词以 # 开头,将忽略该词以及后面直到换行符之前的所有字符。

别名设置

如果为各个命令的第一个单词定义了别名,则会使用别名文本替换此单词。别名由任意数目的字符组成,其中不包括元字符、引号字符、文件扩展字符、参数和命令替换字符以及 =。替换字符串可包含任何有效的 shell 脚本,其中包括上面列出的元字符。除正在替换的所有文本以外,将对被替换文本中的各个命令的第一个词的别名进行测试。如果别名值的最后一个字符为空白,还会检查此别名后的词以便进行别名替换。别名可用来重新定义特殊的内置命令,但不能用来重新定义上面列出的保留字。可以使用 alias 命令创建、列出以及导出别名,可以使用 unalias 命令删除别名。导出的别名对通过名称调用的脚本依然有效,但必须重新初始化才能用于单独的 shell 调用。请参见“调用”。为防止别名递归导致无限循环,如果 shell 当前未处理同一名称的别名,则会使用别名值替换该词,否则不会替换。

别名设置在读取脚本时执行,而不是在执行脚本时执行。因此,为使别名生效,必须在读取引用该别名的命令之前执行 alias 定义命令。

别名常常用作全路径名的速记名称。使用别名功能的一个选项可以将别名值自动设为对应命令的完整路径名。这些别名称为被跟踪别名。被跟踪别名的值是在首次查找相应的命令时定义的,并且在 PATH 变量每次重置时变成未定义状态。这些别名会持续被跟踪,以便下一个后续引用重新定义该值。有几个被跟踪别名已被编译到 shell 中。set 命令的 –h 选项可以使所引用的每个命令名称成为被跟踪别名。

下列导出的别名已编译到(并且内置到)shell 中,但是可以取消设置或重新定义:



autoload='typeset −fu'
functions='typeset −f'
history='fc −l'
integer='typeset −i'
nohup='nohup '
r='fc −e −'

下面是一个有关结尾空白字符和保留字的示例。如果用户键入:

$ alias foo="/bin/ls "
$ alias while="/"

并且执行以下语句:

$ while true
> do
> echo "Hello, World"
> done

则结果是屏幕上将显示一个永不结束的 Hello, World 字符串序列。然而,如果用户键入:

$ foo while

则结果是 /ls 列表。因为 foo 的别名替换以空格字符结尾,所以会检查下一个词以便进行别名替换。由于下一个词 while 也设置了别名,因此也会对其进行别名替换。由于它未作为命令词出现在适当的位置,因此不会将其识别为保留字。

如果用户键入:

$ foo; while

while 保留了其正常的保留字属性。

波浪号替换

执行别名替换后,系统将检查每个单词,查看此单词是否以不带引号的 ~ 开头。如果满足此条件,则会检查 / 前的单词,确定它是否与用户名相匹配。如果找到匹配项,~ 及匹配的登录名将替换为匹配用户的登录目录。这称为波浪号替换。如果未找到匹配项,原始文本将保留不变。单独的 ~ 或位于 / 之前的 ~ 替换为 $HOME。后跟 +~ 将分别被 $PWD$OLDPWD 替换。

此外,当变量赋值的值以 ~ 开头时会尝试进行波浪号替换。

波浪号展开

波浪号前缀包括一个位于词开头的不带引号的波浪号字符,以及该字符之后、词中第一个不带引号的斜杠之前的所有字符组成,如果没有斜杠,则为词中的所有字符。在赋值中可以使用多个波浪号前缀:在词开头(即,跟在赋值的等号后面)、在任何不带引号的冒号的后面或同时在这两处。赋值中的波浪号前缀由第一个不带引号的冒号或斜杠终止。如果波浪号前缀中的字符都不带引号,波浪号前缀中位于波浪号后面的字符则被视为可能来自用户数据库的登录名。

可移植登录名不能包含 LOGNAME 环境变量描述中指定的字符集之外的字符。如果登录名为空(即,波浪号前缀仅包含波浪号),则会使用变量 HOME 的值替换波浪号前缀。如果未设置 HOME,则结果不确定。否则,将使用与通过 getpwnam 函数获得的登录名关联的起始目录路径名替换波浪号前缀。如果系统无法识别登录名,则结果不确定。

波浪号展开通常仅出现在单词开头,但下面的以往做法是一种例外情况:

PATH=/posix/bin:~dgk/bin

符合进行波浪号展开的条件,因为波浪号跟在冒号后面,而且相关字符都不带引号。考虑禁止这种行为,因为以下任何替换都是合理的:

PATH=$(printf %s ~karels/bin : ~bostic/bin)
for Dir in ~maart/bin ~srb/bin .
do
     PATH=${PATH:+$PATH:}$Dir
done

使用第一个命令时,为每个目录使用了显式冒号。在所有情况下,shell 都会对每个目录执行波浪号展开,因为所有目录对 shell 而言都是单独的单词。

操作数中的表达式,例如:

make -k mumble LIBDIR=~chet/lib

不符合 shell 变量赋值条件,而且也不会执行波浪号展开(除非命令本身执行波浪号展开,但 make 不会这样做)。

特殊序列 $~ 专门指定给将来的实现,以便作为一种在任何单词中强制执行波浪号展开的方法进行评估。

由于要求单词不得使用引号,因此以下内容不是等效的;只有最后一个会引发波浪号展开:

\~hlj/   ~h\lj/   ~"hlj"/   ~hlj\/   ~hlj/

为波浪号提供未知登录名将导致不确定的结果,因为 KornShell ~+~− 结构利用此条件,但是,为波浪号提供不正确的登录名通常会出错。取消设置 HOME 的结果不确定,因为以前的部分 shell 会将其视为错误。

命令替换

括在圆括号中且前面带有美元符号的命令(即 $(命令))或带有一对重音符 (``) 的命令的标准输出可用作单词的一部分或用作整个单词。系统会删除结尾换行符。在第二种格式(已过时)中,在执行命令之前将处理引号中的字符串,以便替换为特殊引号字符。请参见引用。命令替换 $(cat file) 可以用等效但速度更快的 $(<file) 替代。对不执行输入/输出重定向的大多数特殊命令进行命令替换时不会创建单独的进程。

命令替换允许使用命令输出替换命令名称本身。按照以下方式将命令用括号括起来时会发生命令替换:

$(command)

或者(反引号版本):

`command`

shell 通过以下方式展开命令替换:在子 shell 环境中执行命令,用命令的标准输出取代命令替换(命令文本以及最外层的 $() 或反引号),在替换结束时删除由一个或多个换行符构成的序列。输出结束之前的嵌入换行符不会删除;然而,这些字符可被视为字段分隔符,并在字段分隔过程中删除,具体情况取决于 IFS 值以及生效的引号字符。

在使用反引号格式的命令替换中,反斜杠应保留其字面含义,除非后面跟有以下符号:

$     `     \

(美元符号、反引号、反斜杠)。搜索匹配的反引号时,只需找到第一个无前导反斜杠的反引号即可。在此搜索过程中,如果在 shell 注释、here-document、$(命令) 形式的嵌入式命令替换或者带引号的字符串中遇到未转义反引号,则会产生不确定的结果。带单引号或双引号的字符串在 "..." 序列中开始,但未在其中结束时,会产生不确定的结果。

采用 $(命令) 形式时,左括号后到匹配的右括号前的所有字符会构成命令。任何有效的 shell 脚本均可用于命令,除非:

  • 仅包含重定向的脚本会产生不确定的结果。

  • 请参见有关单一子 shell 的限制。

不会对命令替换的结果进行字段拆分和路径名展开处理来进一步进行波浪号展开、参数展开、命令替换或算术展开。如果命令替换发生在双引号内部,则不对替换结果执行命令替换。

命令替换可以进行嵌套。要在反引号版本中指定嵌套,应用程序必须将反斜杠放在内部反引号之前,例如:

`\`command\``

$() 形式的命令替换可以解决使用反引号时出现的行为不一致问题。例如:

命令
输出
echo '\$x'
\$x
echo `echo '\$x'`
$x
echo $(echo '\$x')
\$x

此外,反引号语法对嵌入式命令的内容有历史性的限制。尽管新的 $() 形式可以处理任何类型的有效嵌入式脚本,但反引号形式无法处理某些包含反引号的有效脚本。例如,在左栏中,这些在其他方面有效的嵌入式脚本无法运行,但在右栏中可以运行:

echo `
echo $(
cat <<eeof
cat <<eeof
a here-doc with `
a here-doc with )
eof
eof
`
)
echo `
echo $(
echo abc # a comment with `
echo abc # a comment with )
`
)
echo `
echo $(
echo '`'
echo ')'
`
)

由于这些行为不一致,建议不要将反引号形式的命令替换用于嵌套命令替换或尝试嵌入复杂脚本的新应用程序。

如果命令替换由一个单一子 shell 组成,例如:

$( (command) )

可移植应用程序必须将 $(( 分隔为两个标记(即,使用空格进行分隔)。这是避免算术展开出现歧义所必需的。

算术扩展

前面带有美元符号的双括号所括起来的算术表达式 ( $((算术表达式)) ) 替换为双括号中的算术表达式的值。算术展开提供了用于计算算术表达式和替换其值的一种机制。算术展开格式如下所示:

$((expression))

算术表达式按照使用双引号引起来的方式加以处理,除非不对表达式内部的双引号进行特殊处理。shell 将展开表达式中的所有标记,以便进行参数展开、命令替换和引号删除。

接着,shell 会将其当作算术表达式进行处理,并且替换表达式的值。算术表达式根据 ISO C 规则进行处理,但下述情况例外:

  • 只有整数算术是必需的。

  • sizeof() 运算符、前缀和后缀 ++ 以及 − − 运算符不是必需的。

  • 不支持选择、迭代和跳转语句。

  • /usr/sunos/bin/ksh/usr/sunos/bin/rksh 将前缀 0 到 9 视为十进制常量。请参见以下示例:

    命令
    /bin/ksh 中的结果
    /usr/xpg4/bin/sh 中的结果
    echo $((010+10))
    20
    18
    echo $((019+10))
    29
    error
    [ 10 —le $((011)) ]
    true
    false

作为扩展,shell 能够识别此处所列内容以外的算术表达式。如果表达式无效,则展开会失败,并且 shell 会向标准错误写入一条指示失败的消息。

一个使用算术展开的简单示例:

# repeat a command 100 times
x=100
while [ $x −gt 0 ]
do
     command
     x=$(($x−1))
done

进程替换

此功能在 SunOS 中可用,并且只在支持使用 /dev/fd 目录命名打开文件的 UNIX 操作系统版本上可用。<(list)>( list) 格式的每个命令参数都会运行异步连接到 /dev/fd 中某个文件的进程 list。此文件的名称即为该命令的参数。如果选择了带有 > 的形式,则在此文件中写入的内容为 list 提供输入。如果使用了 <,则作为参数传递的文件包含 list 进程的输出。例如:

paste <(cut -f1 file1) <(cut -f3 file2) | tee >(process1) >(process2)

分别对文件 file1file2 中的字段 1 和 3 执行 cut 操作,将其结果 paste 在一起,并将其发送到进程 process1process2,同时将其放入标准输出。作为参数传递给命令的文件是一个 UNIX pipe(2),因此预期在该文件上执行 lseek(2) 的程序将无法运行。

参数替换

参数是一个标识符、一个或多个数字或 *@#?$! 中的任意字符。变量(以标识符表示的参数)具有一个以及零个或多个属性。可以使用 typeset 特殊命令为变量指定属性。后文介绍了在使用 typeset 特殊命令时 shell 支持的属性。导出的变量向环境传递值和属性。

shell 支持一维数组功能。数组变量的元素通过一个下标进行引用。下标[ 予以指示,后面依次跟有算术表达式]。请参见算术计算。要为数组赋值,请使用 set –A name value ...。所有下标的都必须介于 0 和 4095 之间。数组不需要声明。对带有有效下标的变量的任何引用都是合法的,并且会根据需要创建数组。引用数组时不指定下标等同于引用元素 0。如果使用带有下标 *@ 的数组标识符,则会替换每个元素的值(以字段分隔符分隔)。

可通过写入以下代码来为变量

name=value [ name=value ] ...

如果为 name 设置了整数属性 –i,则 value 可能取决于算术计算。

位置参数是通过数字表示的参数,可使用 set 特殊命令为这些参数赋值。当调用 shell 时,参数 $0 从参数零开始设置。如果 parameter 是一个或多个数字,该参数则为位置参数。包含多个数字的位置参数必须括在花括号中。

参数扩展

参数展开格式如下所示:

${expression}

其中,expression 由配对的 } 前的所有字符构成。在确定配对的 } 时,不检查任何使用反斜杠转义的或带引号的字符串中的 } 以及嵌入式算术展开、命令替换和变量展开中的字符。

最简单的参数展开形式为:

${parameter}

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

参数名称或符号可以括在花括号中,而这类花括号属于可选内容,但位置参数含有多个数字或者 parameter 后面跟有可以作为名称的一部分解释的字符时除外。将通过计算花括号层数来确定配对的右侧花括号,并跳过用括号括起来的带引号的字符串和命令替换。

如果参数名称或符号未括在花括号中,展开将使用最长的有效名称,而不论该名称表示的符号是否存在。shell 扫描其输入以确定名称边界时,它不受它对已定义名称的了解的限制。例如,如果 F 是一个已定义的 shell 变量,则命令:

echo $Fred

不回显后面跟有 red$F 的值;它会选择尽可能最长的有效名称,即 Fred,而后者在本例中可能未设置。

如果参数展开发生在双引号内部:

  • 不会对展开结果执行路径名展开。

  • 不会对展开结果执行字段拆分,但 @ 除外。

此外,可使用以下格式之一修改参数展开。在需要 word 值的每种情况下(根据 parameter 的状态),word 可能会执行波浪号展开、参数展开、命令替换和算术展开。如果不需要 word,则不对其执行展开。分隔下列参数展开修改项的 } 字符按照本部分和 dquote 中的前述内容确定。(例如,如果设置了 foo,则 ${foo-bar}xyz} 将导致 foo 展开后跟字符串 xyz},否则后跟字符串 barxyz})。

${parameter:−word}

使用缺省值。如果 parameter 未设置或为空,则会替换为 word 的展开。否则,会替换为 parameter 的值。

${parameter:=word}

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

${parameter:?[word]}

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

${parameter:+[word]}

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

在前面所示的参数展开中,在格式中使用冒号会导致对未设置的或为空的参数进行测试。省略冒号会导致只对未设置的参数进行测试。以下两个表格对冒号的作用进行了汇总:

parameter 已设置且不为空
parameter 已设置且为空
${parameter:-word}
替换为 parameter
替换为 word
${parameterword}
替换为 parameter
替换 null
${parameter:=word}
替换为 parameter
赋予 word 的值
${parameter=word}
替换为 parameter
替换为 parameter
${parameter:?word}
替换为 parameter
错误,退出
${parameter?word}
替换为 parameter
替换 null
${parameter:+word}
替换为 word
替换 null
${parameter+word}
替换为 word
替换为 word
parameter 未设置
${parameter:-word}
替换为 word
${parameterword}
替换为 word
${parameter:=word}
赋予 word 的值
${parameter=word}
赋予 null 值
${parameter:?word}
错误,退出
${parameter?word}
错误,退出
${parameter:+word}
替换 null
${parameter+word}
替换 null

在显示有“替换为”的所有案例中,表达式将被替换为所显示的值。在显示有“赋予”的所有案例中,会将该值赋予 parameter,这也会替换表达式。

${#parameter}

String Length.parameter 值的字符长度。如果 parameter*@,则会替换为从 $1 开始的所有位置参数(以字段分隔符分隔)。

以下四种参数展开变量用于处理子字符串。在每个案例中,都使用模式匹配表示法(请参见 patmat)而非正则表达式表示法来评估这些模式。如果 parameter*@,则会替换为从 $1 开始的所有位置参数(以字段分隔符分隔)。用双引号将完整的参数展开字符串括起来不会导致以下四个模式字符变量会被引号括起来,而花括号中的引号字符则具有这一作用。

${parameter%word}

删除最小后缀模式。word 展开以生成一个模式。然后,参数展开将通过删除与该模式匹配的最小后缀部分来生成 parameter

${parameter%%word}

删除最大后缀模式。word 展开以生成一个模式。然后,参数展开将通过删除与该模式匹配的最大后缀部分来生成 parameter

${parameter#word}

删除最小前缀模式。word 展开以生成一个模式。然后,参数展开将通过删除与该模式匹配的最小前缀部分来生成 parameter

${parameter##word}

删除最大前缀模式。word 展开以生成一个模式。然后,参数展开将通过删除与该模式匹配的最大前缀部分来生成 parameter

示例

${parameter:−word}

在本例中,仅当 x 为空或未设置时,才会执行 ls。(上文中的“命令替换”部分已对 $(ls) 命令替换表示法进行了说明。)

${x:-$(ls)}

${parameter:=word}

unset X
echo ${X:=abc}
abc

${parameter:?word}

unset posix
echo ${posix:?}
sh: posix: parameter null or not set

${parameter:+word}

set a b c
echo ${3:+posix}
posix

${#parameter}

HOME=/usr/posix
echo ${#HOME} 
10

${parameter%word}

x=file.c
echo ${x%.c}.o
file.o

${parameter%%word}

x=posix/src/std
echo ${x%%/*}
posix

${parameter#word}

x=$HOME/src/cmd
echo ${x#$HOME}
/src/cmd

${parameter##word}

x=/one/two/three
echo ${x##*/}
three

由 Shell 设置的参数

shell 自动设置下列参数:

#

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

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

?

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

$

此 shell 的进程数。

_

一开始时,_ 的值是在 environment 中传递时所执行的 shell 或脚本的绝对路径名。然后会向它赋予上一命令的最后一个参数。对于异步命令,未设置此参数。此参数还可用于保存查看邮件时的匹配 MAIL 文件的名称。

!

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

ERRNO

由最近失败的系统调用设置的 errno 的值。该值取决于系统,是针对调试用途设计的。

LINENO

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

OLDPWD

cd 命令设置的早期工作目录。

OPTARG

getopts 特殊命令处理的最后一个选项参数的值。

OPTIND

getopts 特殊命令处理的最后一个选项参数的索引。

PPID

shell 的父级的进程数。

PWD

cd 命令设置的当前工作目录。

RANDOM

每次引用此变量时将生成一个在 0 和 32767 之间统一分布的随机整数。通过为 RANDOM 分配一个数值,可以初始化随机数字的序列。

REPLY

如果未提供参数,则此变量由 select 语句和 read 特殊命令设置。

SECONDS

每次引用此变量时,将返回自调用 shell 以来所经过的秒数。如果为此变量分配了一个值,引用时返回的值即为此分配的值以及自分配以来所经过的秒数。

Shell 使用的变量

shell 使用下列变量:

CDPATH

cd 命令的搜索路径。

COLUMNS

如果设置了此变量,该值用于定义 shell 编辑模式的编辑窗口以及用于输出 select 列表的编辑窗口的宽度。

EDITOR

如果此变量的值以 emacsgmacsvi 结尾,并且 VISUAL 变量未设置,则会启用相应选项。请参见 set 特殊命令。

ENV

当且仅当调用交互式 shell 时,此变量可能会由 shell 执行参数展开,而生成的值用作含有在当前环境中执行所需的 shell 命令的文件的路径名。该文件不必是可执行文件。如果 ENV 的展开值不是绝对路径名,则结果不确定。如果用户的实际和有效用户 ID 不同或者实际和有效用户组 ID 不同,则会忽略 ENV。

此变量可用于设置别名以及调用 shell 时的其他本地项。ENV 引用的文件不同于 $HOME/.profile,因为 .profile 通常在会话启动时执行,而 ENV 文件在每次开始调用 shell 时执行。以一种类似于点脚本的方式解释 ENV 值,因为这些命令在当前环境中执行,并且文件必需是可读文件,但不必是可执行文件。然而,与点脚本不同的是不执行 PATH 搜索。这可以用来防范特洛伊木马安全违规。

FCEDIT

fc 命令的缺省编辑器名称。

FPATH

函数定义的搜索路径。缺省情况下,FPATH 目录在 PATH 变量之后进行搜索。如果找到一个可执行文件,将在当前环境中读取和执行该文件。引用使用 –u 属性的函数时,将先搜索 FPATH,然后才搜索 PATH。预设别名 autoload 会导致创建使用 –u 属性的函数。

HISTFILE

如果在调用 shell 时设置了此变量,则此变量的值是存储命令历史记录时所使用的文件的路径名。请参见“命令重新输入”

HISTSIZE

如果在调用 shell 时设置了此变量,此 shell 可访问的以前输入的命令的数目则大于或等于此数目。缺省值为 128

HOME

cd 命令的缺省参数(起始目录)。

IFS

内部字段分隔符(通常为空格制表符换行符)用于分隔命令或参数替换产生的命令单词,以及随特殊命令 read 使用以分隔单词。IFS 变量的第一个字符用于分隔参数以便进行 $* 替换。请参见引用

LANG

为未设置的或者空的国际化变量提供缺省值。如果任何国际化变量包含无效设置,实用程序的行为就像未定义任何变量时一样。

LC_ALL

此变量为 LC_* 变量提供缺省值。

LC_COLLATE

此变量确定范围表达式、等效类和多字节字符整理元素在模式匹配中的行为。

LC_CTYPE

确定 shell 处理字符的方式。LC_CTYPE 设置为有效值时,shell 能够显示和处理包含对此语言环境有效的字符的文本和文件名。如果环境中未设置 LC_CTYPE(请参见 environ(5)),则 shell 的操作行为由 LANG 环境变量的值确定。如果设置了 LC_ALL,则会使用其内容覆盖 LANG 和其他 LC_* 变量。

LC_MESSAGES

此变量确定编写消息时应当使用的语言。

LINENO

在执行每个命令之前,此变量由 shell 设置为一个十进制数字,代表脚本或函数中的当前顺序行号(从 1 开始编号)。如果用户取消设置或者重置 LINENO,此变量在 shell 的生命周期内都会失去其特殊意义。如果 shell 当前没有执行脚本或函数,LINENO 的值不确定。

LINES

如果设置了此变量,则使用此变量的值确定输出 select 列表时的列长度。选择列表纵向输出,直到填充了大约 2/3 的 LINES 行为止。

MAIL

如果此变量设置为邮件文件的名称,并且未设置 MAILPATH 变量,shell 则会在指定文件中通知用户已收到邮件。

MAILCHECK

此变量指定 shell 检查 MAILPATH 或 MAIL 变量指定的所有文件的修改时间更改的频率(秒)。缺省值为 600 秒。经过此时间后,shell 会在发出下一提示前进行检查。

MAILPATH

以冒号 (:) 分隔的文件名列表。如果设置了此变量,shell 会通知用户在最后 MAILCHECK 秒内对指定文件所做的任何修改。每个文件名后面都可以带有 ? 以及输出的消息。此消息会进行参数替换,并将变量 $_ 定义为已发生更改的文件的名称。缺省消息为在 $_ 中您有一个邮件

NLSPATH

确定消息目录的位置,以便处理 LC_MESSAGES。

PATH

命令的搜索路径。请参见“执行”。除非在 .profile 中,否则用户无法在 rksh 下执行时更改 PATH。

PPID

此变量由 shell 设置为之前调用了 shell 的进程的十进制进程 ID。在子 shell 中,将 PPID 设置为与当前 shell 的父代相同的值。例如,echo $PPID(echo $PPID) 会生成相同的值。

PS1

展开此变量的值,以便进行参数替换,从而定义主提示字符串,缺省情况下,主提示字符串为 "$  "。主提示字符串中的字符 ! 替换为 command 编号。请参见“命令重新输入”。当输出提示字符串时,出现的两个连续 ! 可生成一个 !

PS2

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

PS3

select 循环中使用的选择提示字符,缺省情况下为 "#?  "。

PS4

此变量的值将展开以进行参数替换,并且位于执行跟踪的每一行之前。如果省略,则执行跟踪提示为 "+  "。

PWD

由 shell 设置为当前工作目录的绝对路径名,且在 shell 初始化时不含类型符号链接组件、点组件以及双点组件。如果应用程序设置或取消设置了 PWD 的值,则 cdpwd 实用程序的行为不确定。

SHELL

在环境中保存 shell 的路径名。如果此变量的基名在调用时为 rshrkshkrsh,则此 shell 成为受限制的。

TMOUT

如果设置为大于零的值,并且未在发出 PS1 提示后的规定秒数内输入某个命令,shell 将终止。可以为 shell 编译此值的最大限制,不能超过此最大限制。

VISUAL

如果此变量的值以 emacsgmacsvi 结尾,将启用相应选项。请参见特殊命令 set

shell 向 PATH、PS1、PS2、PS3、PS4、MAILCHECK、FCEDIT、TMOUT 和 IFS 提供缺省值,而 HOME、SHELL、ENV 和 MAIL 都不是由 shell 设置的(尽管 HOME 是由 login(1) 设置的)。在某些系统上,MAIL 和 SHELL 也是由 login 设置的。

对空白的解释

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

文件名生成

执行替换之后,系统将扫描每个命令以查找字符 *?[,除非已设置了 –f 选项。如果出现了其中的某个字符,则会将该词视为模式。该词将替换为与该模式相匹配的按字典顺序排序的文件名。如果未找到与该模式相匹配的文件名,该词将保持不变。当使用某个模式进行文件名生成时,位于文件名开头的或紧跟 / 的字符句点 (.) 以及字符 / 本身必须明确匹配。以句点开头的文件名与括号内含有句点的模式不匹配。也就是说,ls .@(r*) 会定位名为 .restore 的文件,但 ls @(.r*) 却不会。在模式匹配的其他实例中,不会对 /. 进行特殊处理。

*

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

?

匹配任何单个字符。

[...]

匹配其中包围的任意一个字符。使用 分隔的一对字符将在词汇上匹配这对字符之间的任何字符,包括这对字符。如果左 “[” 后面的第一个字符为 “!”,则匹配任何未包括在括号中的字符。通过将 作为第一个或最后一个字符,可以将其包含在字符集中。

pattern-list 是由以 | 彼此分隔的一个或多个模式构成的列表。复合模式可以由下列一个或多个模式组成:

?(pattern-list)

选择性地匹配任何给定模式之一。

*(pattern-list)

匹配出现的零个或多个给定模式。

+(pattern-list)

匹配出现的一个或多个给定模式。

@(pattern-list)

与某个给定模式完全匹配。

!(pattern-list)

与除某个给定模式以外的所有内容匹配。

引用

上面列出的每一个元字符(请参见“定义”部分)对 shell 而言都有特殊含义,并且会导致单词终止(除非用引号引起来)。可以通过在此字符前面添加一个 \ 引用此字符(即,使此字符代表其自身)。系统将删除 \ NEWLINE 对。包围在单引号对 (' ') 之间的所有字符将被引用。单引号内部不能出现单引号。在双引号 ("") 内,参数和命令替换将执行,并且可使用 \ 来引用字符 \ `"$。当不是被引用时,或者当用作参数赋值的值或文件名时,$*$@ 的含义相同。不过,当用作命令参数时,$* 等效于 ``$1d $2d...'',其中 dIFS 变量的第一个字符,而 $@ 等效于 $1 $2 . . .。在重音符 (``) 内,可使用 \ 来引用字符 \ '$。如果重音符引号出现在双引号内,则 \ 还可用来引用字符 "

通过引用保留字的任何字符,可以删除保留字或别名的特殊意义。列出的函数名称或特殊命令名称的识别方式无法通过引用它们来进行更改。

算术计算

执行整数算术的能力是通过特殊命令 let 提供的。计算是使用 long 算术执行的。常量可以采用 [ base# ] n 形式,其中 base 是介于 2 到 36 之间的表示算术基的十进制数字,n 是该基中的数字。如果省略了 base,则使用基 10。

算术表达式使用与 C 语言相同的表达式语法、优先级和关联。支持除 ++–;?:, 以外的所有整数运算符。算术表达式中的名称可引用变量,而不必使用参数替换语法。引用变量时,该变量的值将作为算术表达式计算。

使用 typeset 特殊命令的 –i 选项可以指定 variable 的内部整数表示。使用 –i 属性对变量的每个赋值的值执行算术计算。如果未指定算术基,则使用变量的第一个赋值确定算术基。此算术基在发生参数替换时使用。

因为许多算术运算符都需要带引号,所以提供 let 命令的备用形式。对于任何以 (( 开头的命令,配对的 )) 之前的所有字符都被视为一个被引用的表达式。更确切地说, ((. . .)) 等效于 let " . . ."

提示

以交互方式使用时,shell 在读取命令之前将使用 PS1 的参数展开值发出提示。如果在任何时间键入了换行符,并且需要进行进一步输入才能完成命令,则会发出辅助提示(即,PS2 的值)。

条件表达式

条件表达式[[ 复合命令配合使用,以便测试文件属性和比较字符串。不会对 [[]] 之间的单词执行单词拆分和文件名生成。每个表达式均可由下面的一个或多个一元表达式或二元表达式构成:

–a file

True(如果 file 存在)。

–b file

True(如果 file 存在且为块特殊文件)。

–c file

True(如果 file 存在且为字符特殊文件)。

–d file

True(如果 file 存在且为目录)。

–e file

True(如果 file 存在)。

–f file

True(如果 file 存在且为普通文件)。

–g file

True(如果 file 存在且设置了其 setgid 位)。

–h file

True(如果 file 存在且为符号链接)。

–k file

True(如果 file 存在且设置了其 sticky 位)。

–n string

True(如果 string 的长度为非零值)。

–o option

True(如果已启用名为 option 的选项)。

–p file

True(如果 file 存在且为 fifo 特殊文件或管道)。

–r file

True(如果 file 存在,并且可供当前进程读取)。

–s file

True(如果 file 存在且其大小大于零)。

–t fildes

True(如果文件描述符编号 fildes 已打开且与终端设备相关联)。

–u file

True(如果 file 存在且设置了其 setuid 位)。

–w file

True(如果 file 存在,并且可供当前进程写入)。

–x file

True(如果 file 存在,并且可供当前进程执行)。如果 file 存在且为目录,则当前进程有权在此目录中搜索。

–z string

True(如果 string 的长度为零)。

–L file

True(如果 file 存在且为符号链接)。

–O file

True(如果 file 存在,并且归此进程的有效用户 ID 所有)。

–G file

True(如果 file 存在,并且其组与此进程的有效组 ID 匹配)。

–S file

True(如果 file 存在且为套接字)。

file1 –nt file2

True(如果 file1 存在且比 file2 更新)。

file1 –ot file2

True(如果 file1 存在且比 file2 更旧)。

file1 –ef file2

True(如果 file1file2 存在,并且引用同一文件)。

string

True(如果字符串 string 不是 null 字符串)。

string == pattern

True(如果 stringpattern 匹配)。

string = pattern

== 相同,但已过时。

string != pattern

True(如果 stringpattern 不匹配)。

string1 < string2

True(如果根据按类别 LC_COLLATE 的语言环境设置进行适当解释的字符串,string1string2 之前)。

string1 > string2

True(如果根据按类别 LC_COLLATE 的语言环境设置进行适当解释的字符串,string1string2 之后)。

exp1 –eq exp2

True(如果 exp1 等于 exp2)。

exp1 –ne exp2

True(如果 exp1 不等于 exp2)。

exp1 –lt exp2

True(如果 exp1 小于 exp2)。

exp1 –gt exp2

True(如果 exp1 大于 exp2)。

exp1 –le exp2

True(如果 exp1 小于或等于 exp2)。

exp1 –ge exp2

True(如果 exp1 大于或等于 exp2)。

在上述每个表达式中,如果 file 格式为 /dev/fd/n(其中 n 为整数),则会对描述符编号为 n 的已打开文件进行测试。

通过使用下列任何基元,可以使用这些基元构成复合表达式(这些基元按优先级的降序顺序列出)。

(表达式)

True(如果 expression 为 True)。用于对表达式进行分组。

! 表达式

True(如果 expression 为 False)。

expression1 && expression2

True(如果 expression1expression2 均为 True)。

expression1 || expression2

True(如果 expression1expression2 为 True)。

输入/输出

执行命令之前,使用 shell 解释的特殊表示法可以重定向该命令的输入和输出。以下内容可显示在简单命令中的任意位置,也可以位于命令之前或之后,并且不会传递给调用的命令。除非另行说明,否则,命令和参数替换都发生在使用 worddigit 之前。仅当模式与某个文件匹配并且不执行空格解释时,才会执行文件名生成。

<word

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

>word

使用文件 word 作为标准输出(文件描述符 1)。如果文件不存在,则会创建一个文件。如果文件存在并且启用了 –noclobber 选项,则会导致错误;否则会将其截断至零长度。

>|word

> 相同,但它会覆盖 –noclobber 选项。

>>word

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

<>word

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

<< []word

shell 输入读取至与 word 相同的行或读取至 EOF。不会对 word 执行参数替换、命令替换或文件名生成。生成的名为 here-document 的文档将成为标准输入。如果引用了 word 的任何字符,则不会对文档的字符进行任何解释。否则会执行参数和命令替换,忽略 \ NEWLINE,并且必须使用 \ 引用字符 \ $` 以及 word 的第一个字符。如果将 附加到 <<,则会从 word 和文档中删除所有前导制表符。

<&digit

从文件描述符 digit 复制标准输入(请参见 dup(2))。类似地,对于标准输出,请使用 >& digit

<&−

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

<&p

将协同进程的输入移至标准输入。

>&p

将协同进程的输出移至标准输出。

如果上述某个选项前面带有一个数字,引用的文件描述符编号即为该数字(而非缺省值 0 或 1)指定的文件描述符编号。例如:

... 2>&1

表示打开文件描述符 2 以便作为文件描述符 1 的副本写入。

重定向的指定顺序至关重要。shell 根据评估时的(文件描述符, 文件)关联来评估每个重定向。例如:

... 1>fname 2>&1

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

如果命令后跟有 &,并且作业控制处于非活动状态,则该命令的缺省标准输入是空文件 /dev/null。否则,命令执行环境包含调用根据输入/输出规范修改的 shell 的文件描述符。

环境

环境(请参见 environ(5))是按照标准参数列表的相同传递方式传递给执行程序的名称-值对列表。这些名称必须是标识符,值必须是字符串。shell 采用多种方式与环境交互。shell 在调用时扫描环境,为找到的每个名称创建一个变量,为变量指定相应值,并将其标记为导出。执行命令继承此环境。如果用户使用 exporttypeset –x 命令修改了这些变量的值或创建了新的变量,这些变量将成为环境的一部分。因此,向任何执行命令显示的环境包括 shell 最初继承的所有名称-值对(当前 shell 可修改这些名称-值对的值)以及必须在 exporttypeset –x 命令中说明的所有添加内容。

通过在任何简单命令函数前面添加一个或多个变量赋值,可以扩展它们的环境。变量赋值参数是 identifier=value 格式的词。因此:

TERM=450 cmd args

(export TERM; TERM=450; cmd args)

是等效的(就上述 cmd 执行而言,已列出的前面带有星号的特殊命令除外)。

如果设置了 –k 标志,all 变量赋值参数会放置到环境中,即使这些变量赋值参数出现在命令名称之后。下面的命令首先输出 a=b c,然后输出 c

echo a=b c
set −k echo
a=b c 

此功能旨在用于为早期 shell 版本编写的脚本,强烈建议不要将此功能用于新脚本中。它很可能在某天就会消失。

函数

可使用上文中的“命令”部分介绍的 function 保留字定义 shell 函数。Shell 函数在内部读取和存储。别名在读取函数时解析。函数的执行方式与将参数作为位置参数传递的命令相似。请参见“执行”

函数与调用者在同一进程中执行,并且与调用者共享所有文件和当前工作目录。调用者捕获的陷阱在函数中重置为其缺省操作。函数未捕获或忽略的陷阱条件导致该函数终止,并将此条件传递给调用者。

函数在调用者的环境中完成之后,将执行在函数内设置的 EXIT 关联陷阱。这仅适用于按照以下方式声明的非 POSIX 样式函数

function func

而不是按照以下方式声明的 POSIX 样式函数

func()

通常在调用程序和函数之间共享变量。然而,在函数中使用的 typeset 特殊命令会定义其作用域包括当前函数及其调用的所有函数的局部变量。

特殊命令 return 用于从函数调用返回。函数中的错误将控制权返回给调用者。

使用 typeset–f 可以列出所有函数的名称。typeset –f 会列出所有函数名称以及所有函数的文本。typeset –f function-names 仅列出指定函数的文本。使用 unset 特殊命令的 –f 选项可以取消定义函数。

函数通常在 shell 执行 shell 脚本时 unsettypeset 命令的 –xf 选项可用来将函数导出到执行时无需单独调用 shell 的脚本。应当使用 typeset–xf 选项,在 ENV 文件中指定需要跨不同 shell 调用定义的函数。

函数定义命令

函数是一个用户定义名称,可用作调用复合命令的简单命令(通过新的位置参数)。函数是通过函数定义命令定义的。

函数定义命令的格式如下所示:

fname() compound-command[io-redirect ...]

将函数命名为 fname;它必须是一个名称。实现时,允许在函数名称中使用其他字符作为扩展名。实现为函数和变量维护不同的名称空间。

函数定义命令中的 () 由两个运算符组成。因此,允许但不必混合使用空白字符与 fname()

参数 compound-command 表示一个复合命令。

声明函数时,不会对 compound-commandio-redirect 中的文本执行 wordexp 中的任何展开;在每次调用函数时正常执行所有展开。类似地,可选的 io-redirect 重定向和 compound-command 中的任何变量赋值是在执行函数本身期间执行的,而非在定义函数时执行。

执行函数时,它会向特殊的内置实用程序提供语法错误和变量赋值属性。

每当将函数名称指定为简单命令的名称时,都会执行 compound-command。命令的操作数在执行 compound-command 期间临时变成位置参数;也可以更改特殊参数 # 以反映操作数的数目。特殊参数 0 保持不变。函数完成时,位置参数和特殊参数的值 # 将恢复到执行函数之前的值。如果在 compound-command 中执行特殊的内置 return,则函数完成并且在函数调用之后恢复执行下一个命令。

下面的示例说明了如何在允许执行简单命令的情况下使用函数定义:

# If variable i is equal to "yes",
# define function foo to be ls −l
#
[ "$i" = yes ] && foo() {
      ls −l
}

如果成功声明函数,则函数定义的退出状态为 0,否则将大于零。函数调用的退出状态为函数执行的最后一个命令的退出状态。

作业

如果启用了 set 命令的 monitor 选项,交互式 shell 会将 job 与每个管道相关联。shell 保存当前作业的表,并使用 jobs 命令输出此表,然后为这些作业分配较小的整数。使用 & 异步启动作业时,shell 输出如下行:

[1] 1234

这表示异步启动的作业的作业编号为 1,并且该作业具有一个(顶级)进程,其进程 ID 为 1234

如果您正在运行一个作业,并希望执行其他工作,则可以按下键 ^Z (Ctrl-Z),此时会向当前作业发送 STOP 信号。正常情况下,shell 随后会指明该作业“已停止”,并输出另一个提示符。然后,您可以处理此作业的状态,使用 bg 命令将其放置到后台,或者运行某些其他命令,最后使用前台命令 fg 将其放回到前台。^Z 立即生效,并在键入时放弃暂挂输出和未读输入,因此它与中断相似。

如果在后台运行的作业尝试从终端读取,则会停止该作业。通常允许后台作业生成输出,但是通过指定命令 “stty tostop” 可以禁用此功能。如果设置了此 tty 选项,后台作业将在尝试生成输出时停止,就像在尝试读取输入时停止一样。

在 shell 中引用作业有多种方法。可通过作业的任意进程的进程 ID 或通过下列项之一来引用作业

%number

带有给定编号的作业。

%string

命令行以字符串开头的所有作业。

%?string

命令行包含字符串的所有作业。

%%

当前作业。

%+

等效于 %%

%−

以前的作业。

当进程更改状态时,shell 可立即获悉。当作业已被阻塞以致无法执行其他进程时,shell 通常会向您发送通知,但仅在输出提示前发送此通知。其目的是为了避免打扰您的工作。

当启用了监视模式时,完成的每个后台作业都会触发为 CHLD 设置的所有陷阱。

试图在作业正在运行或已停止期间离开 shell 时,系统会发出 "You have stopped(running) jobs" 这一警告消息。此时可以使用 jobs 命令查看作业内容。如果您执行此操作或立即尝试再次退出,shell 不会向您发出第二次警告,而会终止停止的作业。如果在运行调用了 nohup 命令的作业时尝试注销,您会收到一条警告消息:

You have jobs running.(您有正在运行的作业。)

您需要再次注销才能真正注销。然而,后台作业将继续运行。

信号

如果调用的命令后跟有 &,并且 monitor 选项处于非活动状态,则会忽略该命令的 INT–QUIT 信号。否则,信号具有 shell 从父级继承的值。请参见特殊命令部分中的 trap

执行

每次执行命令时都会执行上述替换。如果命令名称与列出的特殊命令之一相匹配,将在当前 shell 进程中执行此命令。接着,系统会检查此命令名称,确定它是否与某个用户定义函数相匹配。如果匹配,则会保存位置参数,并将其重置为函数调用的参数。当函数完成或发出了 return 时,将恢复位置参数列表,并且执行在函数中设置的任何 EXIT 关联陷阱。函数的值是执行的最后一个命令的值。函数同样在当前 shell 进程中执行。如果命令名称不是特殊命令或者用户定义的函数,将会创建一个进程,并尝试使用 exec(2) 执行此命令。

shell 变量 PATH 定义此命令所在的目录的搜索路径。备用路径名称使用冒号 (:) 分隔。缺省路径为 /usr/bin:(按此顺序指定 /usr/bin 和当前目录)。可以使用两个或多个相邻冒号指定当前目录,也可以使用位于路径列表开头或末尾的一个冒号来指定当前目录。如果命令名称包含 /,则不会使用搜索路径。否则,将在路径中的每个目录中搜索可执行文件。如果此文件具有执行权限,但不是目录或 a.out 文件,则假定此文件是包含 shell 命令的文件。系统会派生一个子 shell 来读取此文件。此种情况下,将删除所有非导出的别名、函数和变量。带有括号的命令在子 shell 中执行,而不会删除非导出的值。

命令重新输入

从终端设备输入的最近 HISTSIZE 个命令(缺省值为 128)的文本保存在 history 文件中。如果未设置 HISTFILE 变量或者如果此变量指定的文件无法写入,则会使用 $HOME/.sh_history。shell 可以访问使用指定的同一 HISTFILE 的所有非交互式 shell 的命令。特殊命令 fc 用来列出或编辑此文件的某个部分。要编辑或列出的文件部分可以根据编号进行选择,或者通过指定此命令的第一个字符或前几个字符来进行选择。可以指定一个命令或一系列命令。如果未将编辑器程序指定为 fc 的参数,则会使用变量 FCEDIT 的值。如果未定义 FCEDIT,则使用 /bin/ed。退出编辑器时,将输出并重新执行编辑后的命令。编辑器名称 用于跳过编辑阶段,并重新执行命令。在这种情况下,在执行之前可使用 old =new 格式的替换参数来修改命令。例如,如果将 r 的别名设置为 'fc –e ',则键入 'r bad=good c' 将重新执行以字母 c 开头的最近的命令,并将第一次出现的字符串 bad 替换为字符串 good

内嵌编辑选项

通常,从终端设备输入的每个命令行在键入时仅后跟有一个换行符(RETURN 或 LINEFEED)。如果已激活 emacsgmacsvi 选项,用户则可以编辑命令行。要进入这两种编辑模式之一,请设置相应选项。每次向 VISUALEDITOR 变量分配一个以上述选项名称结尾的值时,都会自动选择编辑选项。

编辑功能要求用户终端将 RETURN 作为无换行符的回车接受,并且空格必须覆盖屏幕上的当前字符。

编辑模式会实现用户在当前行查看整个窗口的内容的概念。窗口宽度为 COLUMNS 的值(如果定义),否则为 80。如果窗口宽度太小以致无法显示提示,并且至少保留了 8 列来输入相关输入,则会从左侧截断提示。如果此行长于窗口宽度减去 2 的值,则会在窗口末端显示一个标记以便通知用户。当光标移动并达到窗口边界时,该窗口会将光标放置在中间位置。如果此行在窗口右侧扩展,则标记为 >;如果此行在窗口左侧扩展,则标记为 <;如果此行在窗口两侧扩展,则标记为 *

每种编辑模式下的搜索命令都可以提供对历史文件的访问。仅匹配字符串(而非模式),但字符串中的前导插入记号 (^) 将匹配范围限制为从行中的第一个字符开始。

emacs 编辑模式

通过启用 emacsgmacs 选项,可以进入此模式。这两种模式之间的唯一区别在于它们对 ^T 的处理方式。要进行编辑,请将光标移至需要校正的位置,然后根据需要插入或删除字符或单词。所有编辑命令均为控制字符或转义序列。控制字符的表示法为后跟有字符的插入记号 (^)。例如,^F 是控制 F 的表示法。这可通过按住 CTRL(控制)键并按下 "f" 来输入。SHIFT 键要按下。(表示法 ^? 表示 DEL (delete) 键。)

转义序列的表示法为后跟有字符的 M-。例如,M-f(读作 Meta f)是通过按下 ESC (ascii 033) 再按下 "f" 输入的。(M-F 可能为后跟有 SHIFT(大写)"F" 的 ESC 的表示法。)

所有编辑命令都可从行中的任意位置运行,而不仅限于行开头。除非另有说明,否则在编辑命令之后不输入 RETURN 或 LINEFEED 键。

^F

将光标向前(向右)移动一个字符。

M-f

将光标向前移动一个词。(对于 emacs 编辑器而言,单词是仅由字母、数字和下划线组成的字符串。)

^B

将光标向后(向左)移动一个字符。

M-b

将光标向后移动一个词。

^A

将光标移到行的开头。

^M

将光标移到行的结尾。

^]char

将光标向前移动到当前行中的字符 char

M-^]char

将光标向后移动到当前行中的字符 char

^X^X

交换光标和标记。

erase

(使用 stty(1) 命令定义的用户定义清除字符,通常为 ^H#。)删除上一字符。

^D

删除当前字符。

M-d

删除当前单词。

M-^H

(Meta 退格)删除上一个词。

M-h

删除上一个单词。

M-^?

(Meta-DEL) 删除上一个单词(如果使用的中断字符为 ^?(缺省值为 DEL),则此命令不会起作用)。

^T

emacs 模式下将当前字符与下一个字符换位。在 gmacs 模式下将前两个字符换位。

^C

将当前字符变为大写。

M-c

将当前单词变为大写。

M-l

将当前单词更改为小写字母。

^K

删除光标至行尾之间的内容。如果此命令前面带有一个其值小于当前光标位置的数字参数,则删除给定位置到光标之间的内容。如果此命令前面带有一个其值大于当前光标位置的数字参数,则删除光标到给定光标位置之间的内容。

^由 W

删除光标到标记之间的内容。

M-p

将光标到标记之间的区域推送到栈中。

kill

(使用 stty(1) 命令定义的用户定义中止字符,通常为 ^G@。)删除整个当前行。如果连续输入两个 kill 字符,则自此以后的所有中止字符都会导致换行(使用纸张终端时,此功能非常有用)。

^Y

恢复从行中删除的上一项。(在行中重新输出此项。)

^L

换行并输出当前行。

^@

(空字符)设置标记。

M-space

(元空格)设置标记。

J

(换行)执行当前行。

M

(返回)执行当前行。

eof

仅当当前行为空时,文件结尾字符(通常为 ^D)才会作为文件结尾处理。

^P

获取上一个命令。每次输入 ^P 时,都会访问前面的上一命令。如果该命令不在多行命令的第一行中,则往回移动一行。

M-<

获取最早(最旧)的历史行。

M->

获取最近(最新)的历史行。

^N

获取下一个命令行。每次输入 ^N 时,都会访问后面的下一命令。

^Rstring

颠倒含有 string 的上一命令行的搜索历史。如果给定参数 0,搜索则为正向搜索。string 以 RETURN 或 NEW LINE 结束。如果 string 前面带有 ^,匹配行必须以 string 开头。如果省略了 string,则会访问包含最新的 string 的下一命令行。此种情况下,参数 0 将颠倒搜索方向。

^O

运行。执行当前行,获取历史文件中相对于当前行的下一行。

M-digits

(转义)定义数字参数,这些数字作为下一个命令的参数。接受参数的命令包括:^F^Berase^C^D^K^R^P^N^]M-.M-^]M-_M-bM-cM-dM-fM-hM-lM-^H

M-letter

软键。在别名列表中按名称 _letter 搜索别名,而且,如果此名称的别名已定义,其值将插入输入队列。letter 不得为上述元函数之一。

M-[letter

软键。在别名列表中按名称 __letter 搜索别名,而且,如果此名称的别名已定义,其值将插入输入队列。此命令可用于在许多终端上对功能键进行编程。

M−.

在行中插入上一命令的最后一个单词。如果此命令前面带有一个数字参数,此参数的值确定要插入的单词,而不是最后一个单词。

M−_

M−. 相同。

M−*

将星号附加到单词末尾,并尝试执行文件名展开。

M−ESC

文件名完成。使用与附加有星号的当前单词相匹配的所有文件名中的最长共同前缀替换当前单词。如果匹配项是唯一的,则会附加一个 /(如果该文件为目录)和空格(如果该文件不为目录)。

M−=

如果附加有星号,则列出与当前单词模式相匹配的文件。

^U

将下一命令的参数乘以 4。

\

对下一个字符进行转义。如果前面带有 \ ,则可以在命令行或搜索字符串中输入编辑字符、用户的清除、删除和中断(通常为 ^?)字符。\ 会删除下一个字符的编辑功能(如果有)。

^A

显示 shell 的版本。

M-#

在行开头插入 # 并执行此行。这会导致在历史文件中插入注释。

vi 编辑模式

有两种键入模式。最初,当您输入命令时,您处于输入模式下。要进行编辑,请通过键入 ESC (033) 进入控制模式,并将光标移至需要校正的位置,然后根据需要插入或删除字符或单词。大多数控制命令都接受命令前面的可选重复 count

当在大多数系统上处于 vi 模式时,如果速度为 1200 波特或更大值,并且命令包含任何控制字符,或者自输出提示以来所经过的时间不到 1 秒,则会在一开始时启用标准化处理,并重新回显命令。ESC 字符会终止命令提示的标准化处理,然后用户可以修改命令行。此方案具有标准化处理以及对原始模式进行输入提示回显的优势。

如果还设置了选项 viraw,终端始终会禁用标准化处理。对于不支持两种备用的行尾分隔符的系统,此模式是固有的,并且对某些终端可能会很有用。

输入编辑命令

缺省情况下,编辑器处于输入模式。

erase

(使用 stty(1) 命令定义的用户定义清除字符,通常为 ^H#。)删除上一字符。

^由 W

删除由空格分隔的上一单词。

^D

终止 shell。

^A

对下一个字符进行转义。如果前面带有 ^V,则可以在命令行或搜索字符串中输入编辑字符和用户的清除或中止字符。^V 会删除下一个字符的编辑功能(如果有)。

\

将下一个 erasekill 字符转义。

运动编辑命令

下列命令可以移动光标:

[count]l

将光标向前(向右)移动一个字符。

[count]w

将光标向前移动一个字母数字单词。

[count]W

将光标移至空格后的下一个单词的开头。

[count]e

将光标移至单词末尾。

[count]E

将光标移至以当前空格分隔的单词的末尾。

[count]h

将光标向后(向左)移动一个字符。

[count]b

将光标向后移动一个单词。

[count]B

将光标移至以空格分隔的上一个单词。

[count]|

将光标移至列 count

[count]fc

在当前行中查找下一字符 c

[count]Fc

在当前行中查找上一个字符 c

[count]tc

等效于 f 后跟 h

[count]Tc

等效于 F 后跟 l

[count];

将最后一个单字符查找命令 fFtT 重复 count 次。

[count],

反向执行最后一个单字符查找命令 count 次。

0

将光标移至行的开头。

^

将光标移至行中的第一个非空白字符。

$

将光标移至行尾。

%

移动到对称的 (){}[]。如果光标不在上述某个字符上,将首先在此行的剩余部分中搜索第一次出现的这些字符之一。

搜索编辑命令

这些命令可以访问命令历史记录。

[count]k

获取上一个命令。每次输入 k 时,都会访问之前的上一条命令。

[count]

等效于 k

[count]j

获取下一个命令。每次输入 j 时,都会访问以后的下一条命令。

[count]+

等效于 j

[count]G

获取命令编号 count。缺省命令为最早的历史命令。

/字符串

在历史记录中向后搜索包含 string 的上一条命令。string 以 RETURN 或 NEWLINE 终止。如果 string 前面带有 ^,则匹配行必须以 string 开头。如果 string 为 NULL,则使用上一个字符串。

?字符串

除了搜索方向是向前外,其余均与 / 相同。

n

搜索 /? 命令的最后一个模式的下一个匹配项。

N

反向搜索 /? 命令的最后一个模式的下一个匹配项。搜索历史记录中由上一个 / 命令输入的 string

文本修改编辑命令

这些命令可以修改行。

a

进入输入模式并在当前字符后输入文本。

A

将文本附加到行尾。等效于 $a

[count]cmotion
c[count]motion

从当前字符删除到 motion 将光标移动到的字符,并进入输入模式。如果 motionc,将删除整行并进入输入模式。

C

从当前字符删除到行尾并进入输入模式。等效于 c$

[count]s

删除 count 个字符并进入输入模式。

S

等效于 cc

D

从当前字符删除到行尾。等效于 d$

[count]dmotion
d[count]motion

从当前字符删除到 motion 将移动到的字符。如果 motiond,将删除整行。

i

进入输入模式并在当前字符前插入文本。

I

在行首之前插入文本。等效于 0i

[count]P

在光标之前放置以前修改的文本。

[count]p

在光标之后放置以前修改的文本。

R

进入输入模式并将屏幕上的字符替换为您以覆盖方式键入的字符。

[count]rc

将从当前光标位置开始的 count 个字符替换为 c,并向前移动光标。

[count]x

删除当前字符。

[count]X

删除前面的字符。

[count].

重复上一条文本修改命令。

[count]~

转换从当前光标位置开始的 count 个字符的大小写,并向前移动光标。

[count]_

促使附加上一条命令中的 count 单词并进入输入模式。如果省略 count,则使用最后一个单词。

*

促使 * 附加到当前的单词并尝试生成文件名。如果未找到匹配项,则会发出铃声。否则,将该单词替换为匹配模式并进入输入模式。

\

文件名完成。使用与附加有星号的当前单词相匹配的所有文件名中的最长共同前缀替换当前单词。如果匹配项是唯一的,则会附加一个 /(如果该文件为目录)和空格(如果该文件不为目录)。

其他编辑命令

其他命令。

[count]ymotion
y[count]motion

从当前字符移出到 motion 将光标移至的字符,并将移出的字符放在删除缓冲区中。文本和光标保持不变。

Y

从当前位置移出到行尾。等效于 y$

u

撤消最后一个文本修改命令。

U

撤消对此行执行的所有文本修改命令。

[count]v

返回输入缓冲区中的命令 fc –e ${VISUAL:–${EDITOR:–vi}} count。如果省略了 count,则会使用当前行。

^L

换行并输出当前行。仅在控制模式下有效。

J

(换行)无论处于什么模式下,都执行当前行。

M

(返回)无论处于什么模式下,都执行当前行。

#

如果此命令的第一个字符是 #,则此命令将删除该 # 及换行符之后的每个 #。否则,在此命令的每行前面插入 # 之后发送此行。此命令非常有用,可以将当前作为注释插入历史记录中,以及删除历史记录文件中以前注释命令的注释。

=

如果当前单词附加有星号,则列出与当前单词匹配的文件名。

@letter

在别名列表中按名称 _letter 搜索别名,而且,如果此名称的别名已定义,其值将插入输入队列进行处理。

特殊命令

以下的 simple-commands 将在 shell 进程中执行。允许输入/输出重定向。除非另有指示,输出将写入到文件描述符 1 上,如果没有语法错误,则退出状态为 0。前面有一个或两个*(星号)的命令专门通过以下方式进行处理:

  1. 命令完成时,该命令前面的变量赋值列表仍然有效。

  2. 在变量赋值之后处理 I/O 重定向。

  3. 脚本中包含的错误会导致其中止。

  4. 如果字的后面是前面加有**的命令且字为变量赋值的格式,则使用与变量赋值相同的规则扩展这些字。这表示在 = 符号之后执行波浪号替换,并且不执行字拆分和文件名生成。

* : [ arg ... ]

该命令仅扩展参数。

* . file [ arg ... ]

读取完整的 file,然后执行命令。在当前 shell 环境中执行命令。PATH 指定的搜索路径用于查找包含 file 的目录。如果给定了任何参数 arg,则它们将成为位置参数。否则,位置参数保持不变。退出状态是最后执行的命令的退出状态。

** alias [ –tx ] [ name[ =value ] ] ...

不包含参数的 alias 可在标准输出中以 name=value 格式显示别名列表。将为已指定了其的每个名称定义别名value 中的结尾空格将导致对下一个单词进行检查以执行别名替换。–t 标志用于设置和列出被跟踪的别名。被跟踪别名的值是与给定的 name 对应的完整路径名。如果 PATH 的值重置但别名仍被跟踪,则被跟踪别名的值将变成未定义的值。如果没有 –t 标志,则对于参数列表中没有为其给定 value 的每个 name,都将输出别名的名称和值。–x 标志用于设置或输出导出的别名导出的别名是为通过名称调用的脚本定义的。如果给定了 name,但没有提供值,也没有为 name 定义别名,则退出状态为非零值。

bg [ %job... ]

该命令仅适用于支持作业控制的系统。将指定的每个 job 放入后台。如果未指定 job,则将当前作业放入后台。有关作业格式的描述,请参见上文中的“作业”部分。

* break [ n ]

从封闭的 forwhileuntilselect 循环(如果有)中退出。如果指定了 n,则 break n 层。如果 n 大于封闭式循环的数量,则应退出最外层的封闭式循环。

* continue [ n ]

继续执行封闭的 forwhileuntilselect 循环的下一次迭代。如果指定了 n,则从第 n 次封闭式循环继续执行。如果 n 大于封闭式循环的数量,则应使用最外层的封闭式循环。

cd [ –L ] [ –P ] [ arg ]
cd old new

此命令可以采用两种形式中的任意一个。在第一种形式中,它将当前目录更改为 arg。如果 arg,目录将被更改为以前的目录。shell 变量 HOME 是缺省的 arg。将环境变量 PWD 设置为当前目录。如果更改了 PWD,则还应将 OLDPWD 环境变量更改为之前的工作目录值,即调用更改目录 (cd) 之前最近的当前工作目录。shell 变量 CDPATH 定义包含 arg 的目录的搜索路径。备用路径名称使用冒号 (:) 分隔。缺省路径为空(指定当前目录)。当前目录是通过空路径名指定的,可以直接显示在等号之后或显示在路径列表中任何其他位置的冒号分隔符之间。如果 arg/ 开头,则不使用搜索路径。否则,将搜索路径中每个目录的 arg。如果失败,cd 会尝试将目录更改为通过串联 PWD 值、斜杠字符和 arg 而组成的路径名。

–L

以逻辑方式处理双点 (..) 运算。在处理双点组件之前,解析符号链接组件。

–P

以物理方式处理操作数双点。在处理双点组件之前,解析符号链接组件。

如果同时指定了 –L–P 选项,则使用要调用的最后一个选项而忽略另一个选项。如果 –L–P 都未指定,则按照双点逻辑处理操作数。

cd 的第二种形式在当前目录名称 PWD 中用字符串 new 替换字符串 old,并尝试更改为此新目录。不能通过 rksh 执行 cd 命令。

command [–p] [command_name] [argument ...]
command [–v | –V] command_name

command 实用程序可使 shell 将参数当作简单命令,禁止 shell 查找函数。–p 标志使用 PATH 的缺省值执行命令搜索,而此路径可以保证找到所有标准实用程序。–v 标志将字符串写入标准输出,指示由 shell 使用的路径名或命令,以便在当前的 shell 执行环境中调用 command_name–V 标志将字符串写入标准输出,指示 shell 如何在当前的 shell 执行环境中解释在 command_name 操作数中给定的名称。

echo [ arg ... ]

请参见 echo(1) 了解用法和说明。

* eval [ arg ... ]

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

* exec [ arg ... ]

如果给定了 arg,将执行这些参数指定的命令而不是此 shell,同时不创建新进程。输入参数/输出参数可以显示并会影响当前进程。如果未给定参数,则此命令的作用是修改输入/输出重定向列表所指定的文件描述符。在这种情况下,任何通过该机制打开的 2 以上的文件描述符编号将在调用其他程序时关闭。

* exit [ n ]

导致调用 shell 或 shell 脚本退出,退出状态由 n 指定。该值是指定状态的最低有效 8 位。如果省略 n,则退出状态为最后执行的命令的退出状态。执行陷阱时发生 exit 时,最后一个命令指的是在调用该陷阱之前执行的命令。此外,EOF 也会导致 shell 退出,但启用了 ignoreeof 选项的 shell 除外。请参见 set

** export [ name[=value] ] ...
** export –p

标记给定 name,以便自动导出到随后执行的命令的环境中。

指定 –p 时,export 按以下格式将所有导出变量的名称和值写入到标准输出中:

"export %s=%s\n", name, value

如果 name 已设置并且:

"export %s\n", name

如果 name 未设置。

shell 会设置输出的格式,包括适当使用引号,以便适合作为实现相同导出结果的命令重新输入 shell,但以下情况除外:

  1. 无法重置带值的只读变量。

  2. 如果在保存状态时以及将保存的输出重新输入 shell 时之间为变量分配一个值,则输出时取消设置的变量不能重置为取消设置状态。

fc [ –e ename ] [ –nlr ] [ first [ last ] ]
fc –e [ old =new ] [ command ]
fc –s [ old=new ] [ command ]

在第一种形式中,从 firstlast 的命令范围是从在终端键入的最后的 HISTSIZE 命令中选择的。参数 firstlast 可以指定为数字或字符串。字符串用于查找以指定字符串开头的最近命令。负数用作到当前命令数的偏移。如果选择了 –l 标志,则命令将列在标准输出中。否则,在包含这些键盘命令的文件中调用编辑器程序 ename。如果未提供 ename,则会将变量 FCEDIT 的值(缺省值 /bin/ed)用作编辑器。编辑完成后,将执行编辑后的命令。如果未指定 last,则将它设置为 first。如果未指定 first,针对编辑和列举的缺省值分别为上一条命令和 −16。标志 –r 会颠倒命令顺序,而标志 –n 在执行列出操作时抑制命令编号。在第二种格式中,在执行 old=new 替换之后重新执行 command。如果不存在 command 参数,则会执行在此终端键入的最近一个命令。

fg [ %job... ]

该命令仅适用于支持作业控制的系统。将指定的每个作业带到前台。否则,将当前作业放入前台。有关作业格式的描述,请参见上文中的“作业”部分。

getopts optstring name [ arg ... ]

检查 arg 是否具有合法选项。如果省略了 arg,则会使用位置参数。选项参数以 + 开头。未以 + 开头的选项或者参数 表示选项的结尾。optstring 包含 getopts 可识别的字母。如果字母后面跟有一个 :,则该选项需要有一个参数。选项与参数之间可以用空格隔开。

每次在有前缀 + 的情况下被调用时,如果 arg+ 开头,则 getopts 会将它发现的下一个选项字母放置在变量 name 中。下一个 arg 的索引存储在 OPTIND 中。选项参数(如果有)存储在 OPTARG 中。

optstring 中的前导 : 将导致 getopts 将无效选项的字母存储在 OPTARG 中,并针对未知选项将 name 设置为 ?,而在缺少某个必需的选项时将 name 设置为 :。其他情况下,getopts 将显示一条错误消息。如果没有更多选项,则退出状态是非零的。有关用法和描述,请参见 getoptcvt(1)

getopts 支持传统的单字符短选项和由 Sun 的命令行接口范例 (Command Line Interface Paradigm, CLIP) 定义的长选项。

每个长选项都是短选项的别名,是在紧跟在其等效短选项后的括号中指定的。例如,可以使用以下脚本行将长选项 file 指定为短选项 f 的别名:


getopts "f(file)" opt

在命令行上,请在长选项之前加上前缀 --++。在上面的示例中,命令行上的 --file 等同于 -f,而命令行上的 ++file 等同于 +f

每个短选项可以有多个长选项等效体,但是这有违 CLIP 规范,应谨慎使用。必须将每个长选项等效体都放置到括号中,如下所示:


getopts "f:(file)(input-file)o:(output-file)"

在上面的示例中,--file--input-file 均等同于 -f,而 --output-file 等同于 -o

变量 name 始终设置为短选项。当在命令行上指定长选项时,name 将被设置为其短选项等效体。

hash [ name ... ]
hash [ –r ]

对于每个 name,shell 都会确定并记录 name 指定的命令搜索路径中的位置。使用 –r 选项时,shell 会清除它记录的所有位置。如果未给定参数,则显示记录的命令的相关信息。Hits 是 shell 进程调用命令的次数。Cost 是找到搜索路径中的命令所需的工作量的衡量方法。如果在搜索路径相对目录中发现一个命令,则更改到该目录后,该命令的存储位置将重新计算。需要执行此操作的命令由 hits 信息旁的星号 (*) 标识。Cost 将在重新计算完成后递增。

jobs [ –lnp ] [ %job ... ]

列出有关每个给定作业的信息;如果省略了 job,则列出有关所有活动作业的信息。除普通信息外,–l 标志还列出进程 ID。–n 标志仅显示自上次通知以来停止或退出的作业。–p 标志导致只列出进程组。有关作业格式的描述,请参见上文中的“作业”部分jobs(1)

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

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

let arg...

每个 arg 都是一个可求值的独立算术表达式。有关算术表达式计算的说明,请参见上文中的“算术计算”部分

如果最后一个表达式的值为非零值,则退出状态为 0,否则为 1

login argument . . .

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

* newgrp [ arg ... ]

等效于 exec /bin/newgrp arg ....

print [ –Rnprsu[n ] ] [ arg ... ]

shell 输出机制。如果没有标志或者具有标志 ,将按照 echo(1) 描述的方式在标准输出中输出参数。退出状态为 0,除非用于写入的输出文件未打开。

–n

阻止将 NEWLINE 添加到输出。

–R | –r

原始模式。忽略 echo 的转义约定。–R 选项输出除 –n 之外的所有后续参数和选项。

–p

将参数写入到通过 |& 派生的进程管道中,而不是标准输出中。

–s

将参数写入到历史记录文件而不是标准输出中。

–u [ n ]

指定输出所在的一位文件描述符单元编号 n。缺省值为 1

pwd [ –L | –P ]

将当前工作目录的绝对路径名写入到标准输出中,而此目录不含文件名点 (.) 或双点 (..)。

–L

如果 PWD 环境变量包含当前目录(不包含文件名点或双点)的绝对路径名,pwd 会将此路径名写入到标准输出中。否则,–L 选项的行为与 –P 选项相同。

–P

写入的绝对路径名不应包含在路径名上下文中表示类型符号链接的文件的文件名。

如果同时指定 –L–P,则应用最后一个。如果既不指定 –L 也不指定 –Ppwd 的行为就像已指定 –L 一样。

read [ –prsu[ n ] ] [ name?prompt ] [ name ... ]

Shell 输入机制。读取一行并使用 IFS 中的字符作为分隔符将此行分为多个字段。转义符 (\) 用于去除下一个字符和续行符的任何特殊含义。在原始模式下 (–r),不特殊处理 \ 字符。第一个字段分配给第一个 name,第二个字段分配给第二个 name,依次类推,剩余的字段分配给最后一个 name。通过 –p 选项,使用 |& 从 shell 产生的进程输入管道中获取输入行。如果存在 –s 标志,则会将输入作为命令保存在历史记录文件中。标志 –u 可用于指定从中读取的一位文件描述符单元 n。文件描述符可以通过 exec 特殊命令打开。n 的缺省值为 0。如果省略了 name,则会将 REPLY 用作缺省 name。退出状态为 0,除非用于读取的输入文件未打开或者遇到了 EOF。具有 –p 选项的 EOF 可清除此进程,这样可以派生其他进程。如果第一个参数包含 ?,则当 shell 为交互式 shell 时,该单词的剩余部分将用作标准错误输出中的 prompt。退出状态为 0,除非遇到 EOF。

** readonly [ name[=value] ] ...
** readonly –p

将给定的 name 标记为 readonly,且不能通过后续赋值更改这些名称。

指定了 –p 时,readonly 按以下格式将所有只读变量的名称和值写入到标准输出中:

"readonly %s=%s\n", name, value

如果 name 已设置并且:

"readonly $s\n", name

如果 name 未设置。

shell 会设置输出的格式,包括适当使用引号,以便适合作为在 shell 执行环境中实现相同值和只读属性设置结果的命令重新输入 shell,其中:

  1. 具备输出时设置的值的变量未设置只读属性。

  2. 在输出时取消设置的变量在将保存的输出重新输入 shell 时不具备任何值。

* return [ n ]

使 shell 函数或 '.' 脚本返回到具有由 n 指定的返回状态的调用脚本。该值是指定状态的最低有效 8 位。如果省略 n,则返回状态为最后执行的命令的返回状态。如果不在函数或 '.' 脚本中时调用了 return,则该命令与 exit 相同。

set [ ±abCefhkmnopstuvx ] [ ±o option ]. . . [ ±A name ] [ arg ... ]

此命令的标志具有以下含义:

–A

数组赋值。取消设置变量 name,并按顺序从 arg 列表中分配值。如果使用了 +A,则不会首先取消设置变量 name

–a

自动导出已定义的所有后续变量。

–b

使 shell 以异步方式将后台作业完成情况通知用户。将以下消息写入到标准错误:


"[%d]%c %s%s\n", <job-number>, <current>, <status>, \
     whe<job-name>

其中的各个字段如下所述:

<current>

字符 + 标识将用作 fgbg 实用程序的缺省作业的作业。此作业也可以使用 job_id %+%% 指定。字符 标识将在当前缺省作业退出时变为缺省作业的作业;此作业也可以使用 job_id %− 指定。对于其他作业,此字段为空格字符。最多只有一个作业可以使用 + 标识,也最多只有一个作业可以使用 标识。如果存在任何挂起的作业,则当前作业是某个挂起的作业。如果存在至少两个挂起的作业,则前一个作业也是挂起的作业。

<job-number>

一个可用来为 waitfgbgkill 实用程序标识进程组的编号。使用这些实用程序时,可通过在作业编号前加上 % 前缀来标识作业。

<status>

未指定。

<job-name>

未指定。

当 shell 通知用户作业已完成时,它可以从当前 shell 执行环境中的已知作业列表删除该作业的进程 ID。缺省情况下不启用异步通知。

–C

阻止 shell 的 > 重定向运算符覆盖现有文件。>| 重定向运算符可以覆盖每个文件的 –noclobber 选项。

–e

如果命令具有非零退出状态,则执行 ERR 陷阱(如果已设置)并退出。该模式在读取配置文件时被禁用。

–f

禁用文件名生成。

–h

每个命令在第一次遇到时将成为被跟踪别名。

–k

将所有的变量赋值参数放在命令的环境中,而不仅仅是命令名称前面的参数。

–m

后台作业在单独的进程组中运行,并在完成时输出一行。在完成消息中报告后台作业的退出状态。在具有作业控制的系统上,为交互式 shell 自动启用该标志。

–n

读取命令并检查其中是否存在语法错误,但不执行这些命令。对于交互式 shell,忽略此命令。

–o

将当前选项设置写入到标准输出中,且输出时使用的格式适合作为实现相同选项设置的命令重新输入 shell。

–o

下列参数可以是下列选项名称之一:

allexport

–a 相同。

errexit

–e 相同。

bgnice

以较低的优先级运行所有后台作业。这是缺省模式。

emacs

使您进入 emacs 样式的内嵌编辑器,以便输入命令。

gmacs

使您进入 gmacs 样式的内嵌编辑器,以便输入命令。

ignoreeof

shell 不会在 EOF 上退出。必须使用 exit 命令。

keyword

–k 相同。

markdirs

文件名生成操作生成的所有目录名称都附加有结尾 /

monitor

–m 相同。

noclobber

阻止重定向 > 截断现有文件。启用时要求使用 >| 截断文件。等效于 –C

noexec

–n 相同。

noglob

–f 相同。

nolog

不会在历史记录文件中保存函数定义。

notify

等效于 –b

nounset

–u 相同。

privileged

–p 相同。

verbose

–v 相同。

trackall

–h 相同。

vi

使您进入 vi 样式的内联编辑器的插入模式,直到您键入转义符 033 为止。这会使您进入控制模式。回车可发送此行。

viraw

各个字符在 vi 模式下键入时处理。

xtrace

–x 相同。

如果未提供选项名称,则输出当前选项设置。

–p

禁用对$HOME/.profile 文件的处理,并使用文件 /etc/suid_profile(而非 ENV 文件)。当有效 UID 不等于实际 UID 时或者有效 GID 不等于实际 GID 时,将启用此模式。禁用此模式会导致将有效 UID 和 GID 设置为实际 UID 和 GID。

–s

按字典顺序对位置参数进行排序。

–t

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

–u

替换时会将未设置的参数视为错误。

–v

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

–x

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

关闭 –x–v 标志,并停止检查参数的标志。

−−

不更改任何标志。在将 $1 设置为以 开头的值时非常有用。如果此标志后没有任何参数,则取消设置位置参数。

使用 +(而非 )将导致禁用这些标志。此外,还可以在调用 shell 时使用这些标志。当前标志集可在 $− 中找到。除非指定了 –A,否则剩余的参数都是位置参数,并按照顺序分配为 $1 $2 ...。如果未给定参数,则在标准输出上输出所有变量的名称和值。

* shift [ n ]

将来自 $n+1 $n+1 . . . 的位置参数重新命名为 $1 . . .,缺省 n 为 1。参数 n 可以为任何算术表达式,此算术表达式的计算结果为小于或等于 $# 的非负数字。

stop%jobid ...
stop pid ...

stop 会使用后台作业的 jobid 停止执行这类作业,或使用其 pid 停止执行任何进程。请参见 ps(1)

suspend

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

test expression

评估条件表达式。有关用法和描述,请参见上文中的“条件表达式”部分test(1)

* times

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

* trap [ arg sig ... ]

arg 是一个在 shell 接收信号 sig 时读取和执行的命令。arg 在设置陷阱和获取陷阱时分别扫描一次。sig 可以指定为信号编号或信号名称。trap 命令按信号编号顺序执行。尝试对输入到当前 shell 时忽略的信号编号设置陷阱将不起作用。

如果 arg,shell 会将每个 sig 重置为缺省值。如果 arg 为 null (''),shell 会忽略每个指定的 sig(如果出现)。否则, arg 会在出现其中一个相应 sigs 时由 shell 读取并执行。陷阱操作会覆盖上一个操作(既可以是缺省操作,也可以是明确设置的操作)。陷阱操作完成后的 $? 值是调用陷阱前的值。

sig 可以是 EXIT, 0(等效于 EXIT)或使用符号名称指定的信号,但不具有 SIG 前缀,例如,HUPINTQUIT TERM。如果 sig0EXIT,并且在函数主体内执行 trap 语句,则会在此函数完成后执行命令 arg。对于任何函数外部设置的 trap,如果 sig 0EXIT,则会在退出时从 shell 执行命令 arg。如果 sigERR,当命令的退出状态为非零值时,将执行 arg。如果 sigDEBUG,则会在每个命令之后执行 arg

shell 在 EXIT 时执行陷阱的环境与在 EXIT 时获取陷阱之前执行最后一个命令之后立即生成的环境相同。

每次调用陷阱时,都会以等效于 eval "$arg" 的方式处理 arg

无法捕获或重置进入非交互式 shell 时忽略的信号,尽管尝试此操作时无需报告错误。交互式 shell 能够重置或捕获进入时忽略的信号。给定 shell 的陷阱将留在原地,直到通过另一个 trap 命令做出显式更改为止。

进入子 shell 时,将陷阱设置为缺省参数。这并不意味着 trap 命令不能在子 shell 中用于设置新陷阱。

不带参数的 trap 命令可以将与各信号关联的命令列表写入到标准输出。该格式为:

trap −− %s %s ... <arg>, <sig> ...

shell 会设置输出的格式,包括适当使用引号,以便适合作为实现相同捕获结果的命令重新输入 shell。例如:

save_traps=$(trap)
. . .
eval "$save_traps"

如果陷阱名称或编号无效,则返回非零退出状态。否则将返回 0。对于交互式和非交互式 shell,无效的信号名称或编号不会被视为语法错误,并且不会导致 shell 中止。

当作业正在等待前台进程时,不会处理陷阱。因此,在前台作业终止之前,不会执行 CHLD 中的陷阱。

type name ...

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

** typeset [ ±HLRZfilrtux[n] ] [ name[=value ] ] ...

设置 shell 变量和函数的属性及值。在函数内部调用 typeset 时,会创建变量 name 的新实例。当函数完成时,将恢复变量和类型。可以指定下列属性列表:

–H

此标志提供非 UNIX 计算机上的 UNIX 到主机名文件映射。

–L

向左调整 value,并删除其中的前导空格。如果 n 为非零值,它将定义字段宽度。否则根据第一个赋值的值的宽度确定字段宽度。如果为此变量赋值,则会根据需要使用空格填充此值的右侧或者截断此值,使其适合此字段。如果同时设置了 –Z 标志,则删除前导零。禁用 –R 标志。

–R

向右调整,并使用前导空格填充。如果 n 为非零值,则定义字段宽度,否则根据第一个赋值的值的宽度确定字段宽度。如果重新为此变量赋值,则会使用空格填充此字段的左侧,或者截断此字段的末尾。禁用 –L 标志。

–Z

如果第一个非空字符为数字,并且未设置 –L 标志,则会向右调整,并使用前导零进行填充。如果 n 为非零值,它将定义字段宽度。否则根据第一个赋值的值的宽度确定字段宽度。

–f

这些名称引用函数名称,而非变量名称。不可赋值,且其他有效标志只有 –t–u–x–t 标志开启对此函数的执行跟踪。–u 标志会导致将此函数标记为未定义。搜索 FPATH 变量,以便在引用函数时查找函数定义。–x 标志允许函数定义在通过名称调用的 shell 过程之间仍然有效。

–i

参数为整数。这将加快算术运算速度。如果 n 为非零值,则定义输出算术基,否则第一个赋值确定输出算术基。

–l

将所有大写字符都转换为小写字符。禁用大写标志 –u

–r

将给定的 name 标记为 readonly,且不能通过后续赋值更改这些名称。

–t

标记变量。用户可以定义标记,对 shell 而言,这些标记没有任何特殊意义。

–u

将所有小写字符都转换为大写字符。禁用小写标志 –l

–x

标记给定 name,以便自动导出到随后执行的命令的环境中。

–i 属性不能与 –R–L–Z–f 一起指定。

使用 +(而非 )将导致禁用这些标志。如果未给定 name 参数但指定了标志,则输出设置有这些标志的变量名称列表(还可以输出其)。(使用 + 而非 可防止输出值。)如果未给定 name 和标志,则会输出所有变量名称属性

ulimit [ –HSacdfnstv ] [ limit ]

设置或显示资源限制。以下部分列出了可用的资源限制。许多系统都不包含这些限制中的一个或多个。如果指定了 limit,则会设置指定资源的限制。limit 的值可以是一个数字(采用随各资源指定的单位为单位),也可以为值 unlimited。字符串 unlimited 请求删除当前限制(如果有)。–H–S 标志指定为给定资源设置硬限制还是软限制。硬限制一旦设置便不能增加。软限制最多可增加至硬限制的值。如果未指定 –H–S 选项,此限制同时适用于两个选项。如果省略了 limit,则会输出当前资源限制。此种情况下,除非指定 –H,否则将输出软限制。如果指定了多种资源,则会在值之前输出限制名称及单位。

–a

列出当前的所有资源限制。

–c

核心转储大小中的 512 字节块的数目。

–d

数据区域大小中的千字节数目。

–f

子进程可写入的文件中的 512 字节块的数目(可以读取任意大小的文件)。

–n

文件描述符数目加 1。

–s

栈区域大小中的千字节数目。

–t

各进程使用的秒数。

–v

虚拟内存的千字节数目。

如果未给定任何选项,则采用 –f

umask [–S] [ mask ]

用户文件创建掩码设置为 mask(请参见 umask(2))。mask 可以是八进制数字或符号值,如 chmod(1) 中所述。如果给定了符号值,新 umask 值即为对以前的 umask 值的补数应用 mask。如果省略了 mask,则会输出掩码的当前值。–S 标志生成符号输出。

unalias name ...
unalias –a

从别名列表中删除 name 列表给定的别名。–a 选项从当前执行环境中删除所有别名定义。

unset [ –f ] name ...

未分配 name 列表给定的变量,即,已清除这些变量的值和属性。无法取消设置 readonly 变量。如果设置了 –f 标志,这些名称将引用函数名称。取消设置 ERRNOLINENOMAILCHECKOPTARGOPTINDRANDOMSECONDSTMOUT_ 将删除其特殊含义,即使在随后对这些变量赋值也是如此。

* wait [ job ]

等待指定的 job 并报告其终止状态。如果未给定 job,则等待当前处于活动状态的所有子进程。此命令的退出状态即为进程等待的退出状态。请参见 Jobs 了解 job 格式的说明。

whence [ –pv ] name ...

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

–v 标志会生成更详细的报告。

即使名称为别名、函数或保留字,–p 标志也会针对 name 进行路径搜索。

调用

如果使用 exec(2) 调用 shell,并且参数 0 ($0) 的第一个字符为 ,则假定此 shell 为 login shell,并从 /etc/profile 读取命令,然后从当前目录的 .profile$HOME/.profile 中读取命令(如果任一文件存在)。接着,从通过对环境变量 ENV 的值执行参数替换命名的文件读取命令(如果存在此文件)。如果 –s 标志不存在并且 arg 存在,则对第一个 arg 执行路径搜索,以便确定要执行的脚本的名称。脚本 arg 必须具有读取权限,并且忽略任何 setuidsetgid 设置。如果未在此路径中找到脚本,则会处理 arg,就像指定了内置命令或函数一样。然后,按下述方式读取命令。调用时,shell 解释以下标志:

–c

command_string 操作数读取命令。根据 command_name 操作数的值设置特殊参数 0 的值,并按顺序从其余 arg 操作数设置位置参数($1$2等等)。不从标准输入读取任何命令。

–s

如果存在 –s 标志,或者如果未保留任何参数,则从标准输入读取命令。Shell 输出(上文中列出的特殊命令的输出除外)将写入到文件描述符 2。

–i

如果提供了 –i 标志,或者如果将 shell 输入和输出附加到终端(根据 ioctl(2) 的指示),则此 shell 为交互式的。在此情况下,将忽略 TERM(因此,kill 0 不会中止交互式 shell),并捕获和忽略 INTR(因此,可以中断 wait)。在所有情况下,shell 将忽略 QUIT

–r

如果提供了 –r 标志,则 shell 为受限 shell。

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

仅限 rksh

rksh 用于设置登录名和执行环境,其功能比标准 shell 的功能更受约束。rksh 的操作与 ksh 的操作相同,但前者不允许以下操作:

  • 更改目录(请参见 cd(1)

  • 设置 SHELL、ENV 或 PATH 的值

  • 指定包含 / 的路径或命令名称

  • 重定向输出(>>|<>>>

  • 更改组(请参见 newgrp(1))。

在解释 .profile 和 ENV 文件后将强制实施上述限制。

如果发现要执行的命令为 shell 过程,rksh 则会调用 ksh 来执行此命令。因此,可以向最终用户提供有权访问标准 shell 完整功能的 shell 过程,并强制提供有限的命令菜单;此方案假定最终用户在同一目录下不具备写入和执行权限。

这些规则的实际结果是,通过执行保证的设置操作,并将用户保留在适当的目录(可能不是登录目录)中,.profile 的写入者具有用户操作的完整控制权。

系统管理员通常设置可由 rksh 安全调用的命令目录(即,/usr/rbin)。

错误

shell 检测到的错误(例如,语法错误)会导致 shell 返回非零退出状态。否则,shell 将返回执行的最后一个命令的退出状态(另请参见上述 exit 命令)。如果以非交互方式使用 shell,会放弃执行此 shell 文件。通过输出命令或函数名称以及错误状态,报告 shell 检测到的运行时错误。如果出现错误的行号大于 1,则还会在命令或函数名称后面的方括号 ([]) 中输出此行号。

对于非交互式 shell,当特殊的内置实用程序或其他类型的实用程序遇到错误情况时,shell 会向标准错误写入一条诊断消息并如下表所示退出:

错误
特殊的内置实用程序
其他实用程序
Shell 语言语法错误
退出
退出
实用程序语法错误(选项或操作数错误)
退出
不退出
重定向错误
退出
不退出
变量赋值错误
退出
不退出
展开错误
退出
退出
未找到命令
不适用
可能退出
未找到点脚本
退出
不适用

执行 shell 展开时发生了展开错误(例如,${x!y},因为 ! 不是有效运算符)。如果实现能够在标记化期间而非展开过程中检测到这些错误,则实现会将它们视为语法错误。

如果子 shell 中发生任何显示为“可能退出”或“退出”的错误,子 shell 会以或可能会以非零状态退出,但包含子 shell 的脚本不会因为错误而退出。

在上表列出的所有情况下,交互式 shell 会将一条诊断消息写入标准错误并且不退出。

用法

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

退出状态

每个命令的退出状态都会影响其他 shell 命令的行为。不属于实用程序的命令的退出状态记录在本部分。标准实用程序的退出状态分别记录在它们各自的部分。

如果未找到命令,则退出状态为 127.如果找到命令名称,但不是可执行实用程序,则退出状态为 126.不使用 shell 调用实用程序的应用程序应当使用这些退出状态值报告类似错误。

如果命令在执行单词展开或重定向过程中失败,其退出状态则大于零。

通过特殊参数 ? 报告退出状态时,shell 会报告可用的完整八位退出状态。因收到信号而终止的命令的退出状态大于 128.

文件

/etc/profile

/etc/suid_profile

$HOME/.profile

/tmp/sh*

/dev/null

属性

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

/usr/sunos/bin/ksh, /usr/sunos/bin/rksh

属性类型
属性值
可用性
shell/ksh88
CSI
Enabled(已启用)

/usr/xpg4/bin/sh

属性类型
属性值
可用性
system/core-os
CSI
Enabled(已启用)
接口稳定性
Committed(已确定)
标准
请参见 standards(5)

另请参见

cat(1)cd(1)chmod(1)cut(1)echo(1)env(1)getoptcvt(1)jobs(1)login(1)newgrp(1)paste(1)pfksh(1)pfexec(1)ps(1)shell_builtins(1)stty(1)test(1)vi(1)dup(2)exec(2)fork(2)ioctl(2)lseek(2)pipe(2)ulimit(2)umask(2)rand(3C)signal(3C)signal.h(3HEAD)wait(3C)a.out(4)profile(4)attributes(5)environ(5)largefile(5)standards(5)

Morris I.Bolsky 和 David G.Korn 合著的《The KornShell Command and Programming Language》,Prentice Hall 出版,1989 年。

警告

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

附注

如果执行属于被跟踪别名的命令,并在搜索路径中原始命令所在目录之前的目录中安装同名命令,shell 会继续 exec 原始命令。使用 alias 命令的 –t 选项可以更正此情况。

某些很早的 shell 脚本包含 ^,并将其用作管道字符 | 的同义词。

在复合命令中使用 fc 内置命令会导致整个命令从历史记录文件中消失。

内置命令 .file 在执行任意命令之前读取整个文件。因此,此文件中的 aliasunalias 命令不适用于文件中定义的任何函数。

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