转自http://blog.csdn.net/laoyiin?viewmode=contents
方便学习,这些命令真是头大,想看的看看不想看就当手册了,哈哈
1 简介
•什么是Bash:Bash的一个简短的描述。
•什么是shell?:简要介绍了shell。
1.1 什么是Bash?
Bash是GNU操作系统的shell,或命令语言解释器。这个名字是“Bourne-Again Shell“的首字母缩写,这是一个双关语,作者是当前的Unix中使用的sh的上一版本shell的作者——斯蒂芬·伯恩,最早发布于贝尔实验室基础科学研究院的Unix第七版。
Bash大致与sh兼容,并采纳了一些来自Korn shell (ksh)和C shell(csh)的有用的功能。它的目的是成为符合IEEE POSIX Shell和IEEE POSIX规范(IEEE标准1003.1)工具部分的一个实现。它提供了对于sh在交互和编程功能上的改进。
Bash是GNU操作系统的默认shell,同时GNU操作系统也提供其他shell,比如csh。与其他GNU软件一样,Bash是相当精巧。目前可以运行在几乎每一个版本的Unix上,它也运行在一些其它的操作系统 , 例如MS-DOS,OS / 2和Windows平台上——当然是由其他机构提供支持的。
1.2什么是shell?
基本上来说,shell是执行命令的宏处理器。宏处理器是指把文字和符号扩展以创建更大的表达式的功能。
一个UNIX shell既是命令解释器也是编程语言。作为一个命令解释器,shell提供了一套丰富的GNU工具的用户界面。编程语言的特性让这些实用程序可以相互结合。可以创建包含很多命令的文件,而这个文件也可以成为新的命令。这些新的命令和系统命令(例如位于/bin目录中的命令)具有相同的地位,允许用户建立自定义的环境,以及自动化日常任务。
shell即可以交互式使用,也可以非交互方式使用。在交互模式下,shell接受用户从键盘的输入内容。当非交互式执行时,shell执行从文件中读取的命令。
shell允许同步和异步的执行GNU命令。 shell等待同步命令完成后再接受更多的输入命令;异步命令在shell读取和执行其他命令的同时,继续并行执行异步命令。重定向结构允许细粒度的控制这些命令的输入和输出。此外,shell允许控制命令的环境方面的内容。
shell还提供了一个小的内置命令的集合(内建命令集),实现那些通过独立的程序不方便或者不可能实现的功能。例如,(cd,break,continue,和exec)无法在shell之外来实现,因为他们直接处理shell本身。history,getopts,kill,以及pwd 等其他内建命令,虽然可以在独立程序中实现,但作为内置命令更方便使用。后面的章节中将描述所有的shell内建命令。
执行命令是shell的基础功能,大部分shell的能力(和复杂性)是来自于它内嵌的编程语言。象任何高级语言一样,shell具有变量,流程控制结构,引用和函数。
shell提供的交互性不仅限于编程语言的参数等等。交互功能还包括作业控制,命令行编辑,命令历史和别名。本手册中也会描述这些功能。
2 定义
这些定义用于本手册。
POSIX基于Unix的开放系统标准的族。 Bash主要关注的是POSIX 1003.1标准的shell和实用工具部分。
blank/空白
空格或制表符。
builtin/内置命令
一个shell本身的内部实现的命令,而不是一个可执行程序。
control operator/控制操作符
执行控制功能的一个符号。它是一个换行或以下之一:“| |”,“&&”,“&”,“,”,“;”,'|','|&','('或')'。
exit status/退出状态
命令给调用者返回的值。这个值被限制为8位,因此,最大值是255。
field/字段
这是一个文本的单位,这个文本是shell扩展的结果。扩建后,执行命令时,生成的字段包括命令的名称和参数。
filename/文件名
来标识文件的一个字符串。
job/作业
一组处理的集合,包括管道,和任何处理的结果,都在同一个处理组。
job control/作业控制
一种机制,用户可选择性地停止(暂停),然后重新启动(简历)执行的过程。
Metacharacter/分隔符
一个字符,不带引号的时候,分割单词。分隔符是空白或以下字符:'|','&',',','(',')','<'或'>'。
name/名称
一个单词,只包含字母,数字和下划线,并以字母或下划线开始。名称将用作shell变量和函数名。也称为作为一个标识符。
operator/操作符
控制操作符或重定向操作符。在重定向节,有重定向操作符的列表。操作符至少包含一个不带引号的分隔符。
process group/进程组
具有相同的进程组ID的相关进程的集合。
process group ID/进程组ID
在其生命周期中的唯一代表一个进程组的ID。
reserved word/保留字
在shell中具有特殊含义的单词。大多数和流的控制结构有关,如for和while。
return status/返回状态。
退出状态的同义词。
signal/信号
当系统中发生某些事件时,进程会收到内核的通知的机制。
special builtin/特殊内置命令
被POSIX标准列为特殊的命令的shell内置命令。
token/符号
被shell视为独立单位的一个字符序列。它要么是一个单词或者操作符。
word/单词
被shell视为独立单位的一个字符序列。单词不包括不加引号的分隔符。
3.2.2 管道
管道是由控制操作符'|'或'|&'分隔开的一组简单命令的序列。
管道的格式
[time [-p]] [!] command1 [ [| or |&] command2 …]
在管道中的每个命令的输出是通过管道连接到下一个命令的输入。也就是说,每个命令读取前一个命令的输出。此连接在该命令指定的重定向之前执行。
如果使用'|&',则command1的标准错误通过管道连接到command2的标准输入。它是 2>&1 |的简写。这个隐含的标准错误重定向在其他重定向之后执行。
保留字time,会在管道完成后,打印时间统计数据。目前的统计数据包括整个管道的执行时间,以及命令执行消耗的用户时间和系统时间。 -p选项指定了POSIX输出格式。当shell在POSIX模式(参见bash POSIX模式),如果下一个标记以一个“ - ”开始时,它不识别time为保留字。 TIMEFORMAT变量可以设置为一个字符串,以设置显示时间的格式。可用的格式的说明(见 Bash变量)。time保留字允许记录shell的内建命令,shell函数和管道的计时。外部命令time不能容易地达到这些计时的目的。
当shell在POSIX模式(参见bash POSIX模式),time后面可能会跟着一个换行符。在这种情况下,shell显示由shell和它的子进程消耗的总的用户和系统时间。变量TIMEFORMAT被用来指定时间信息的格式。
如果管道不是异步执行的(见列表),shell会等待管道中的所有命令完成。
在管道中的每个命令在其自己的子shell中执行(见命令执行环境)。管道的退出状态是在管道中的最后一个命令的退出状态,除非pipefail选项被启用(参见内建命令set)。如果启用了pipefail,管道的返回值是最后一个(最右边)的命令的退出状态,可能是一个非零的值,或者,如果所有命令成功完成,则是零值。如果保留字'!'位于管道之前,则退出状态是上述的退出状态的逻辑否。 shell等待管道中的所有命令终止后才返回一个值。
3.2.3 命令列表
命令列表是由一个或多个管道组成的序列,它们被这些分隔符号“;“,”&“,”&&“,”| |“分隔,并且由一个';','&',或换行符终止。
在这些操作符中,“&&”和“| |”具有相同的优先级,然后';'和'&',具有相同的优先级。
可能会出现一个或多个换行符来分隔命令列表,它们相当于分号。
如果命令终止于控制操作符'&',shell将在子shell中异步执行这个命令。这被称为在后台执行命令。 shell不会等待命令完成,返回值是0(真)。当作业控制没有被激活时(见作业控制),异步命令的标准输入,在没有指定明确的重定向时,将被重定向到/dev/null。
“;”分隔开的命令将按顺序执行,shell会等待每个命令都终止。返回状态是最后执行的命令的退出状态。
AND和OR命令列表,是使用控制操作符“&&”和“| |”分隔的一个或多个管道组成的序列。 AND和OR命令列表按左结合执行。
AND命令列表的形式
command1 && command2
command2,当且仅当,command1返回的退出状态是零的情况下才执行。
OR命令列表的形式
AND和OR命令列表的返回状态,是命令列表中的最后一个执行的命令的退出状态。command1 || command2
command2,当且仅当,command1返回的退出状态非零的情况下才执行。
3.2.4 复合命令
•循环结构:实现迭代的shell命令。
•条件结构:实现按条件执行的shell命令。
•命令组合:组合命令的方法。
复合命令是shell编程的结构件。每一个结构以一个保留字或控制操作符开始,并终止于相应的保留字或操作符。复合命令的重定向(见重定向)应用于该复合命令中的所有命令,除非明确覆盖。
Bash提供了循环结构,条件结构,和把命令组合起来作为一个单元执行的机制。
3.2.4.1 循环结构
Bash支持以下的循环结构。
注意,出现在语法描述的';',可以被替换为一个或多个换行。
until
until命令的语法是:
until test-commands; do consequent-commands; done
test-commands的退出状态是非0值,则循环执行consequent-commands。返回状态是consequent-commands的最后一条命令的退出状态,或者如果没有执行consequent-commands中的命令,则是零。
while
while命令的语法是:
while test-commands; do consequent-commands; done
执行consequent-commands,直到test-commands的退出状态是0值。返回状态是consequent-commands的最后一条命令的退出状态,或者如果没有执行consequent-commands中的命令,则是零。
for
for命令的语法是:
for name [ [in [words …] ] ; ] do commands; done
展开words,对于展开结果列表的每一个成员,执行一次commands,同时,name绑定到当前被展开的成员。如果不存在‘in words’,for命令对每个位置参数(见特殊参数)执行一次commands,就像指定了“in $@”。返回状态是执行的最后一个命令的退出状态。如果words展开后,没有内容的话,则commands不被执行,返回值是零。
另一种形式的for命令:
for (( expr1 ; expr2 ; expr3 )) ; do commands ; done
首先,根据下述规则(见Shell运算)计算表达式expr1。然后计算表达式expr2,直到结果为零。每次expr2的计算结果为一个非零值时,执行commands,然后计算表达式expr3。如果任何表达式被省略,它的值相当于1。返回值是commands的最后一个命令的退出状态,或者,如果任何一个表达式是无效的,则返回值为假。
break和continue内建命令(见Bourne shell的内建命令)可以用来控制循环的执行。
3.2.4.2 条件结构
if
if命令的语法是:
if test-commands; then
consequent-commands;
[elif more-test-commands; then
more-consequents;]
[else alternate-consequents;]
fi
test-commands被执行,如果其返回值是零,则consequent-commands被执行。如果test-commands返回一个非零的状态,elif依次执行每个elif,如果它的退出状态是零,则相应的more-consequents被执行,然后结束。如果存在‘else alternate-consequents’,并在最后一个if或者elif子句中的最后一个命令是非零的退出状态,则alternate-consequents被执行。返回状态是最后执行的命令的退出状态,或者如果没有条件是真时,返回状态是零。
case
case命令的语法是:
case word in [ [(] pattern [| pattern]…) command-list ;;]… esac
case会选择性地执行第一个匹配word的pattern所对应的command-list。如果shell选项nocasematch是打开的话(见shopt内建命令),匹配过程不考虑字符中的字母大小写。 '|'用于分隔多个pattern,“)”操作符用于终止一个pattern列表。pattern列表和相关的command-list被称为一个子句。
每个子句必须使用';;',';&',或';;&“终止。这个word在匹配之前要进行波浪线扩展,参数扩展,命令替换,算术扩展和移除引号等操作。每种pattern都要进行波浪线扩展,参数扩展,命令替换和算术扩展。
可以有任意数量的case子句,每个子句由“;;',';&',或';;&'终止。第一个相匹配的pattern确定了被执行的command-list。
下面是一个例子,在脚本中使用case,可以用来描述动物的有趣的特性:
echo -n "Enter the name of an animal: "
read ANIMAL
echo -n "The $ANIMAL has "
case $ANIMAL in
horse | dog | cat) echo -n "four";;
man | kangaroo ) echo -n "two";;
*) echo -n "an unknown number of";;
esac
echo " legs."
如果使用操作符';;',在第一个pattern匹配后,不再尝试后续的匹配动作。使用';&'代替';;'导致继续执行下一个子句的command-list。使用';;&'代替';;',shell会测试后续子句的pattern,如果匹配,则执行相应的command-list。
如果没有pattern能够匹配,则返回值是零。否则,返回值是被执行的command-list的退出状态。
select
select name [in words …]; do commands; done
in后面的words列表被扩展,形成项目清单。扩展后的words打印在标准错误输出流中,每个项目前面都有一个数字。如果省略‘in words’,则打印位置参数,如同指定了‘in "$@"’。 然后显示PS3提示,从标准输入中读取一行。如果该行内容和一个显示的内容前对应的数字匹配,然后name的值被设置到该内容。如果该行是空的,则再次显示项目内容和提示。如果读取到EOF,select命令完成。读到任何其他值会导致name被设置为null。读取的行的内容被保存在变量REPLY中。
每次选择后执行commands的命令,直到遇到break命令,此时select命令完成。
select fname in *;
do
echo you picked $fname @H_212_404@ $REPLY
break;
done
((…))
((expression))
根据下述规则(见Shell运算)的对expression求值。如果表达式的值是非零值,返回值是0,否则,返回值是1。完全等同于
let "expression"
见Bash内建命令,let内置命令的完整说明。
[[...]]
[[expression]]
返回状态0或1,取决于条件表达式expression的结果。表达式的组成见下述Bash中的条件表达式的内容。在'['和']'之间,单词分割和文件名扩展不执行;波浪线扩展,参数和变量扩展,算术扩展,命令替换,进程替换,和移除引号都执行。条件操作符'-f'必须去除引号,以被识别为运算符。
在'[['中使用'<'和'>'操作符时的排序词典使用当前区域设置。
当使用'=='和'!='运算符时,运算符右边的字符串被认为是一个模式,并根据下述的(见模式匹配)规则匹配。如果shell选项nocasematch(见shopt内建命令的shopt命令描述部分)被激活,匹配时不考虑字符大小写。如果字符串匹配(“==”)的或不匹配('!=')则返回值是0,否则为1。在模式的任何一部分,可以被引号包含,以强制它作为一个字符串匹配。
附加的二进制运算符'=〜',和'=='和'!='具有相同的优先级。当使用它时,操作符右边的字符串被认为是扩展正则表达式,按相应的匹配规则匹配(如regex3)。如果该字符串匹配,则返回值是0,否则为1。如果正则表达式的语法是不正确的,条件表达式的返回值是2。如果shell选项nocasematch(见shopt内建命令的shopt命令描述部分)被激活,匹配时不考虑字符大小写。在模式的任何一部分,可以被引号包含,以强制它作为一个字符串匹配。和正则表达式中的子表达式匹配的子字符串,被存储在数组变量BASH_REMATCH中。BASH_REMATCH中索引为0的元素,是匹配整个正则表达式的那部分字符串。BASH_REMATCH索引为n的元素,是字符串匹配的第n个子表达式的部分。
表达式可以结合使用下面的操作符,按从高到低的优先顺序列出:
(expression)
返回expression的值。这可用于覆盖正常的运算符优先级。
!expression
如果expression是假的,则结果为真。
expression1&&expression2
如果expression1和expression2都是真,则结果为真。
expression1||expression2
如果expression1或expression2是真,则结果为真。
如果expression1的值足以决定整个条件表达式的返回值,则操作符 && 和 || 不计算expression2。
3.2.4.3 分组命令
Bash提供两种组合方式,把一组命令列表组作为一个单元执行。命令被组合时,重定向施加到整个命令列表。例如,在列表中的所有命令的输出可能会被重定向到同一个数据流。
()
(list)
把一个命令列表放在括号中,导致系统创建一个子shell环境(见命令执行环境),每一个list中的命令都在该子shell中执行。由于list是在一个子shell中执行的,变量赋值不会保留到子shell完成后。
{}
{list;}
放在大括号中的命令列表中的命令,在当前shell环境中执行。不创建子shell。分号(或换行)是必需的。
除了是否创建子shell的区别,这两个结构之间的细微差异还有历史的原因,。大括号是保留字,所以他们必须通过空白或者其他分隔符号与list分开。小括号是操作符,即使它们和list之间不用空白分隔开,也被shell作为分隔符号。
3.2.5 协同处理
coprocess(协同处理)是在一个shell命令前面加上coproc保留字。一个协同处理在子shell中异步执行,就像以‘&’控制操作符终止的命令,同时,在正在执行的shell和协同处理之间建立一个双向的管道。
协同处理的格式是:
coproc [NAME] command [redirections]
这将创建一个名为NAME的协同处理。如果不提供NAME,默认名称为COPROC。如果command是一个简单的命令(见简单的命令),则不能提供NAME;否则,它会在简单指令的第一个单词后被中断。
当协同处理器执行时,shell在正在执行的shell上下文中创建一个名字为NAME的数组变量(见数组)。在正在执行的shell中,command的标准输出通过管道连接到一个文件描述符,该文件描述符被指定给NAME[0]。在正在执行的shell中,command的标准输入通过管道连接到一个文件描述符,该文件描述符被指定给NAME[1]。这个管道在命令指定的任何重定向之前被建立起来。该文件描述符可被用来作为shell命令的参数和重定向,可以使用标准的单词扩展。
shell为执行协同处理产生的进程ID,可以在变量NAME_PID中获得。内建命令wait可用于等待协同处理终止。
协同处理的返回状态是command的退出状态。
3.2.6 GNU并行
GNU并行,正如它的名字所暗示的,可用于并行构建和运行命令。您可以运行相同的命令,用不同的参数,不管他们是文件名,用户名,主机名,或从文件中读取的行。
完整的描述,请参阅GNU并行文档。下面举几个例子,简要介绍一下它的用途。
例如,在一个文本文件中每一行的开头增加指定的字符串:
cat file | parallel -k echo prefix_string
需要保留行的顺序的话,使用-k选项。
同样的,也可以在一个文本文件中的每一行的行尾追加指定的字符串:
cat file | parallel -k echo {} append_string
当文件的数量太大而不能使用mv来处理时,可以使并行移动当前目录中的文件:
ls | parallel mv {} destdir
正如你看到的,{}被替换成从标准输入中读取的每一行。这将运行与在当前目录中的文件数相同数量的mv命令。可以通过加入-X选项,模拟一个并行xargs:
ls | parallel -X mv {} destdir
GNU并行可以取代某些常做的操作,比如操作从文件中读取的行(在这个例子里,是文件名):
for x in $(cat list); do
do-something1 $x config-$x
do-something2 < $x
done | process-output
使用一个更紧凑的lambda表达式:
cat list | parallel "do-something1 {} config-{} ; do-something2 < {}" | process-output
并行提供了一个内置的机制来去除文件扩展名,这使其常用来批量转换文件,或文件重命名:
ls *.gz | parallel -j+0 "zcat {} | bzip2 >{.}.bz2 && rm {}"
这将使用bzip2重新压缩在当前目录中的所有文件名以.gz结束的文件。并行的在每个cpu上运行作业(-j+0)。
如果一个命令生成输出,可能要在输出中保持输入的顺序。例如,下面的命令
{ echo foss.org.my ; echo debian.org; echo freenetproject.org; } | parallel traceroute
第一个完成traceroute调用的输出将先显示。使用-k选项,
{ echo foss.org.my ; echo debian.org; echo freenetproject.org; } | parallel -k traceroute
确保首先显示traceroute foss.org.my的输出。
3.3 Shell函数
Shell函数是使用一个简单的名字来执行一组命令的方式。就像一个“普通”命令被执行似的。当一个shell函数的名称被用作一个简单的命令名称时,和该函数名相关的命令列表就被执行。 Shell函数在当前shell上下文中执行,没有创建新的进程。
函数声明使用的语法如下:
name () compound-command [ redirections ]
或
function name [()] compound-command [ redirections ]
这定义了一个名为name的shell函数。保留字function是可选的。如果使用了function保留字,括号是可选的。函数的body是复合命令compound-command(见复合命令)。该复合命令通常是被{和}包围的list,但也可以是上面列出的复合命令。当name被指定为一个命令的名称时,compound-command被执行。任何重定向(见重定向)在shell函数执行后执行。
使用带-f选项的unset内建命令(见Bourne shell的内建命令),可以删除函数的定义。
函数定义的退出状态是零,除非发生语法错误或已经存在一个具有相同的名称的函数。在执行时,函数的退出状态是函数体中执行的最后一个命令的退出状态。
请注意,由于历史的原因,花括号最常见的用法——包围函数体,必须使用空白或换行和函数体分隔。这是因为花括号本身是保留字,并只有用空格或其他shell元字符,把他们和命令列表分开时,才被识别为包围函数体。此外,当使用大括号时,list必须终止于分号,'&',或换行。
当一个函数被执行时,在执行过程中,函数的参数成为位置参数(请参阅位置参数)。特殊的参数“#”——被扩展成位置参数的个数——将被更新,以反映变化。特殊参数0是不变的。该函数被执行时,FUNCNAME变量的第一个元素被设置为函数名称。
函数和调用它的shell的执行环境在所有其他方面是相同的,除了这些以外:DEBUG和RETURN陷阱不被继承,除非该函数已被使用内建命令declare设置trace属性,或内建命令set启用-o functrace选项,(在这种情况下,所有的函数都继承DEBUG和RETURN陷阱),ERR陷阱是不会继承的,除非使用shell 的-o errtrace 选项启用。关于内建命令trap的描述,请参阅Bourne shell的内建命令。
FUNCNEST变量,如果被设置为一个大于0的数值,定义了函数的最大嵌套级别。函数调用超过限制,导致整个命令中止。
如果函数执行了内建命令return,函数执行完毕并继续执行函数调用后的下一个命令。任何与RETURN陷阱相关的命令在继续执行函数调用点之后的命令之前执行。当函数完成后,位置参数和特殊参数'#'的值恢复到他们在函数执行之前的值。如果return获得一个数字值,这就是该函数的返回状态;否则该函数的返回状态是在return前最后执行的命令的退出状态。
函数的局部变量,可以使用内建命令local声明。这些变量只对函数和它调用的命令是可见的。
函数的名称和定义可以使用带-f选项的declare或typeset内建命令(请参阅Bash内建命令)列出。 带-F选项的declare或typeset只列出函数名(如果shell选项extdebug启用,则列出的源文件和行号)。使用带-f选项的内建命令export,函数可以被导出,从而子shell可以自动获得它们的定义(见Bourne shell的内建命令)。需要注意的是shell函数和变量具有相同的名称时,可能会导致环境中多个相同名称的实体被传递到子shell中。必须当心这种情况,这会导致问题。
函数可以是递归的。 FUNCNEST变量可以用来限制的函数的调用栈的深度和限制函数调用的次数。默认情况下,递归调用的数量没有限制。
3.4 shell参数
•位置参数:shell的命令行参数。
•特殊参数:特殊字符来表示的参数。
parameter(参数)是一个存储值的实体。它可以是一个名字,一个数字,或下面列出的特殊字符之一。variable(变量)是使用name表示的参数。一个变量有value(值)和零或更多的属性。属性指定使用declare内建命令(Bash内建命令declare的描述)。
如果参数已被指定值,则是被设置了。空字符串是一个有效的值。一旦一个变量被设置,只能使用unset内置命令取消设置。
一个变量被指定的形式
name=[value]
如果没有给出value,该变量被指定为空字符串。所有value进行波浪线扩展,参数和变量扩展,命令替换,算术扩展和去除引号(详见下文)。如果该变量被设定了整数属性,即使没有使用表达式$((...)),value也被看作是一个算术表达式(见算术扩展)。不执行分词,“$@”是个例外,下面会解释。不执行文件名扩展。对于alias,declare,typeset,export,readonly,和local等内建命令,赋值语句也可能以参数的形式出现。
在上下文中,赋值语句分配值到shell变量或数组索引(见数组)时,“+=”操作符可以用于向变量的当前值追加或增加。当'+='被施加到设置了整数属性的变量时,value被当作算术表达式,并加上变量的当前值。当“+=”应用到使用复合赋值的数组变量时(请参阅阵列),该变量的值不是被取消设置,(就像使用“=”的情况),新的值是被追加到数组的开始位置,比数组最大索引大1(对于索引数组来说),或者,对于联合数组而言,追加额外的键-值对。当应用到一个字符串变量时,value被扩展并追加到变量上。
3.4.1 位置参数
位置参数是由一个或多个数字,除了一位数字0以外,表示的参数。位置参数是在shell被调用时,被shell的参数赋值的,也可能会被内建命令set重新赋值。位置参数N可以被引用为${N},或$N——当N为一位数字时。位置参数不能使用赋值语句赋值。内建命令set和shift用于对位置参数进行设置和取消设置(见shell内置命令)。执行一个shell函数时,位置参数被临时替换(见Shell函数)。
当位置参数由超过一位数字组成时,必须用大括号括起来。
3.4.2 特殊参数
shell中有几个特殊的参数。这些参数仅可以被引用,赋值给它们的是不允许的。
*
从1开始,扩展所有位置参数。当扩展发生在双引号中时,它扩展为一个单词——每个参数之间使用特殊变量IFS的第一个字符分隔。也就是说,“$ *”是相当于“$1c$2c...”,其中,c是IFS变量值的第一个字符。如果IFS未设置,参数用空格分开。如果IFS为空,参数中间没有分隔符。
@
从1开始,扩展所有位置参数。当扩展发生在双引号中时,每个参数扩展到一个单独的单词。也就是说,“$@”等同于“$1” “$2”...。如果双引号扩展出现在一个单词内,则扩展的第一个参数被连接到该单词的开头部分,并且扩展的最后的参数被连接到该单词的其余部分。如果没有位置参数时,“$@”和$@扩展为空(即,它们将被移除)。
#
扩展为十进制的位置参数的个数。
?
扩展为最近执行的前台管道的退出状态。
-
(连字符)。扩展为当前选项标志,即在调用时指定的标志。一般使用内建命令set,或由shell本身(如使用-i选项)设置的。
$
扩展为shell的进程ID。在()子shell,它扩展到调用shell,而不是子shell的进程ID。
!
扩展为最近执行的后台(异步)命令的进程ID。
0
扩展为shell或者shell脚本的名称。这是在shell初始化时设置的。如果bash是命令文件调用的(见Shell脚本),$0被设定为该文件的名称。如果bash以-c选项(参见调用Bash)启动,那么$0被设置为字符串被执行后的第一个参数,如果存在一个字符串的话。否则,它被设置为调用bash的文件名。
_
(下划线)。在shell启动时,被设定为通过环境或参数列表来调用shell或者shell脚本的绝对路径名。随后,扩展为前一个命令扩展后的最后一个参数。也设置为用来调用每一个命令的全路径名,和从环境中导出到该命令的全路径名。当检查邮件时,这个参数保存邮件文件的名称。
3.5 Shell扩展
在命令被分解后,扩展在命令行上执行。有执行7种类型的扩展要执行:
•大括号扩展
•波浪线扩展
•参数和变量扩展
•命令替换
•算术扩展
•单词分割
•文件名扩展
•大括号扩展:扩展大括号内的表达式。
•波浪线扩展:扩展〜字符。
•shell参数扩展:Bash扩展变量为值的方法。
•命令替换:使用一个命令的输出作为参数。
•算术扩展:在shell扩展中如何使用算术计算。
•进程替换:从命令读取和向命令写入的方法。
•单词分割:把扩展的结果分割成单独的参数。
•文件名扩展:指定文件名匹配模式的简写。
•引号移除:如何以及何时从单词中移除引号字符。
扩展的顺序是:大括号扩展,波浪线扩展,参数,变量和算术扩展和命令替换(由左到右的方式进行),单词分割,文件名扩展。
有一个额外的扩展——进程替换,在能够支持它的系统上使用。它和参数,变量,和算术扩展和命令替换同时执行。
仅有大括号扩展,单词分割,文件名扩展可以改变的扩展的单词数目,其他扩展把一个单一单词扩展成一个单一单词。唯一的例外是“$ @”(见特殊参数)和“$ {name[@]}”(请参阅阵列)的扩展。
引号扩展在所有扩展完成后执行(见引号移除)。
3.5.1 大括号扩展
大括号扩展是一个产生任意字符串的机制。这个机制和文件名扩展(见文件名扩展)相似,但生成的文件名必须不存在。被大括号扩展的模式一般是这种形式,一个可选的preamble(序言),后跟位于一对大括号之间的一系列以逗号分隔的字符串或一个序列表达,后跟一个可选的postscript(附言)。序言将被作为包含在大括号中的每个字符串的前缀,附言被附加到每个生成的字符串后边,扩展从左到右执行。
括号扩展可以嵌套。被扩展结果中的字符串是没有排序的,从左至右的顺序被保留。例如,
bash$ echo a{d,c,b}e
ade ace abe
序列表达式采取{x..y[..incr]}的形式,其中x和y是整数或单个的字符,incr是可选的增量,是一个整数。当序列是整数时,该表达式扩展为x和y之间的数字,包括x和y。可以在整数前面加上'0',以强制每个段都具有相同的宽度。当x或y以零开头时,shell试图强制所有产生的字段包含相同的位数,必要填充时零。当序列是字符串时,表达式扩展为x和y之间的字符,包括x和y。需要注意的是,x和y必须是相同类型。如果指定增量时,该增量被用于每个字段之间的差值。默认的增量根据情况是1或-1。
大括号扩展在任何其他扩展之前执行,在结果中保留对其他扩展具有特殊含义的字符。它是严格按照字面扩展的。 Bash不对扩展内容或者大括号之间的文本进行任何句法翻译。为了避免和参数扩展冲突,字符串'$ {'不被视为大括号扩展。
一个正确形式的大括号扩展,必须包含不带引号的左右大括号,以及至少一个的不带引号的逗号,或一个有效的序列表达式。任何不正确的大括号扩展将保持不变。
{或者','可以用引号包含并加上反斜杠,以防止其被认为是一个大括号表达式。为了避免和参数扩展冲突,字符串'$ {'不被视为大括号扩展。
当要生成的字符串的公共前缀的长度比在上面的例子中的长时,常用此结构来缩短命令的长度:
mkdir /usr/local/src/bash/{old,new,dist,bugs}
或
chown root /usr/{ucb/{ex,edit},lib/{ex?.?*,how_ex}}
3.5.2 波浪线扩展
如果一个单词以未被引号包含的波形符(“~”)开头,那么,从开始到第一个没有引号包含的斜杠(或所有字符,如果没有引号包含的斜杠)被认为是一个 tilde-prefix(波浪线前缀)。如果波浪线前缀中的字符没有被引号包括,则波浪线前缀中波浪线后的字符被视为一个login name(登录名)。如果该登录名是空字符串,波浪线被替换为shell变量HOME的值。如果HOME没被设置,则它被替换为执行当前shell的用户的主目录。否则,波浪线前缀将被指定的登录名的主目录替换。
如果波浪线前缀是'~+',shell变量PWD的值将取代波浪线前缀。如果波浪线前缀是' ~-',将被替换为shell变量OLDPWD的值。
如果波浪线前缀中的波浪号后面的字符组成一个数字N,并由'+'或' - '前缀,则波浪线前缀被替换为目录栈中的相应元素,如同使用内建命令dirs,并且命令参数就是上述波浪线前缀中的波浪号后面的字符(见目录堆栈)。如果波浪线前缀,除了波浪线外,由一个前边没有加上一个'+'或' - '的数字组成的话,则假定是带'+'的。
如果登录名是无效的,或波浪线扩展失败,这个单词保持不变。
任何后跟':'或'='的变量赋值,将检查是否是不带括号的波浪线扩展。在这些情况下,也进行波浪线扩展。因此,给PATH,MAILPATH,和CDPATH赋值时,可以使用带波浪线的文件名,shell会把扩展后的值赋给这些变量。
下表显示了bash如何对待不带括号的波浪线前缀:
~
$HOME的值
~/foo
$HOME/foo
~fred/foo
用户fred的主目录的foo子目录
~+/foo
$PWD/foo
~-/foo
${OLDPWD-'~-'}/foo
~N
将显示一个'dirs +N'命令的结果字符串
~+N
将显示一个'dirs +N'命令的结果字符串
~-N
将显示一个'dirs -N'命令的结果字符串
3.5.3 shell参数扩展
“$”字符引入了参数扩展,命令替换,或者算术扩展。可以选择把被扩展的参数名或者符号用大括号括起来的方式的,这样可以防止把跟随在变量名后的字符解释为变量名称的一部分。
当使用大括号时,被匹配的右大括号“}”是第一个没有被反斜杠转义,或不是在引号内的字符串,而且不是在一个内嵌的算术扩展,命令替换,或参数扩展中。
参数扩展的基本形式为${parameter}。parameter的值是可替换的。当parameter是一位以上的数字的位置参数时,或者parameter后面的字符不能被解释为它的名称的一部分时,需要使用大括号。
如果parameter的第一个字符是一个感叹号(!),那么将引入一个间接变量。 bash使用组成这个parameter的其余的字符作为变量的名称;然后这个变量被扩展,该值被用在其余的替代上,而不是parmeter本身的值。这被称为间接扩展。这种扩展的例外,是下面描述的的${!prefix}和${!name[@]}。感叹号必须紧跟在左大括号后面,以实现间接变量。
在下面的每一种情况下,word是波浪线扩展,参数扩展,命令替换和算术扩展的对象。
在不执行子字符串扩展时,使用下面所描述的形式,bash测试参数是没有设置还是空。仅对于未设置的参数的测试,则可以省略冒号。换句话说,如果有冒号,将测试两个参数的存在性,和值不为空;如果省略冒号,只测试存在性。
${parameter:-word}
如果parameter没有被设置,或者是空,结果为word的扩展。否则,结果为parameter的值。${parameter:=word}
如果parameter没有被设置,或者是空,word的扩展被赋值给parameter。然后,结果为parameter的值。位置参数和特殊参数不能以这种方式赋值。${parameter:?word}
如果parameter没有被设置,或者是空,word的扩展(或如果word不存在,会发出消息)被写入到标准错误和shell,如果不是交互的就退出。否则,结果是parameter的值。${parameter:+word}
如果parameter没有被设置,或者是空,结果是空白(nothing),否则是word的扩展。${parameter:offset}
${parameter:offset:length}
扩展parameter中,从offset设定的开始的length那么长的字符。如果省略length,扩展为从offset设定的开始位置的parameter的子串。length和offset是算术表达式(见shell算术)。这被称为的子字符串扩展。
如果offset的计算结果为小于零的数字,该值被设置为从parameter的值的尾部开始的偏移量。如果length的计算结果为小于零的数,并且parameter不是“@”,也不是索引或关联数组,它被解释为从parameter的值的尾部开始的偏移量,而不是一个字符的号码,扩展结果是两个偏移量之间的字符。如果parameter是'@',结果是从offset开始的length个位置参数。如果parameter是一个索引数组下标以'@'或'*'为名称,其结果是从${parameter[offset]}开始的length长度的数组元素。负的offset是指定数组的最大索引+1。对关联数组作子字符串扩展,会产生不可预料的结果。
注意,负的offset必须至少和冒号隔开一个空格,以避免和':-'扩展混淆。子字符串的索引是从零开始的,位置参数除外,使用位置参数时,默认索引从1开始。如果offset为0,并且使用了位置参数,$@为列表的前缀。${!prefix*}
${!prefix@}
扩展为名称以prefix开头的变量名,使用特殊变量IFS的第一个字符来分隔名称。当使用'@',并且扩展被双引号包含时,每个变量名扩展为一个单独的单词。${!name[@]}
${!name[*]}
如果name是一个数组变量,扩展为name中的索引(键)列表。如果name不是数组,当name已经被设置的话,扩展为0,否则返回null。如果使用'@',并且被双引号包含,则每个键被扩展为一个单独的词。${#parameter}
获得扩展后的parameter的字符的长度。如果parameter是'*'或'@',获得的值是位置参数的个数。如果parameter是数组名,并且使用下标“*”或“@”,获得的值是数组中元素的数量。${parameter#word}
${parameter##word}
word被扩展,产生一个类似文件名扩展的模式(见文件名扩展)。如果这个模式匹配parameter扩展结果的开头,那么这个表达式的结果就是parameter扩展的结果,并删除掉其中最短的匹配模式('#'的情况下)的那部分,或最长匹配的模式('##'的情况下)的那部分。如果parameter是'@'或'*',则模式的删除操作被依次施加到每个位置参数,获得的是结果列表。如果参数是数组变量,并带有下标'@'或'*',模式的删除应用到数组中的每个成员,获得的是结果列表。${parameter%word}
${parameter%%word}
word被扩展,产生一个类似文件名扩展的模式(见文件名扩展)。如果这个模式匹配parameter扩展结果的结尾部分,那么这个表达式的结果就是parameter扩展的结果,并删除掉其中最短的匹配模式('#'的情况下)的那部分,或最长匹配的模式('##'的情况下)的那部分。如果parameter是'@'或'*',则模式的删除操作被依次施加到每个位置参数,获得的是结果列表。如果参数是数组变量,并带有下标'@'或'*',模式的删除应用到数组中的每个成员,获得的是结果列表。${parameter/pattern/string}
pattern被扩展,产生一个类似文件名扩展的模式。pamameter被扩展,并且其中最长的匹配pattern的字符串被string替换。如果pattern以'/'开始,所有匹配pattern的字符串被替换。通常情况下,只有第一个匹配被替换。如果pattern以'#'开始,它必须匹配扩展后的parameter的开头。如果pattern以'%'开始,它必须匹配扩展后的parameter的尾部。如果string是null,匹配pattern的部分被删除,pattern后面的/被忽略。如果parameter是'@'或'*',替换操作被依次施加到每个位置参数,获得的是结果列表。如果parameter是数组变量,且下标为'@'或'*',替换操作被依次施加到数组中的每个成员,获得的是结果列表。${parameter^pattern}
${parameter^^pattern}
${parameter,pattern}
${parameter,pattern}
这种扩展修改parameter中的英文字母的大小写。pattern被扩展,产生一个类似文件名扩展的模式。 “^”操作符把匹配pattern的小写字母转换为大写;“,”操作符将匹配pattern的大写字母转换为小写。 '^^'和','扩展,在扩展后的值中转换每一个匹配的字符,'^'和','扩展,仅在扩展后的值中转换第一个字符。如果pattern被省略,它被视为'?'——匹配每一个字符。如果parameter是'@'或'*',修改操作被依次施加到每个位置参数,获得的是结果列表。如果parameter是数组变量,且下标是'@'或'*',修改操作被依次施加到数组中的每一个成员,获得的是结果列表。
3.5.4 命令替换
命令替换允许一个命令的输出来替换这个命令本身。命令替换发生在如下情形:
$(command)
或
`command`
Bash通过执行command,把命令替换为该命令的标准输出,来进行扩展,同时需要删除尾部的换行。内嵌的换行符不会被删除,但在可能会在单词分割时移除。$(catfile)可以换成等价的,但速度更快的$(<file)。
当使用旧式的反引号替换形式时,反斜杠保留它的字面意思,但在后面跟着'$','`',或'\'时除外。第一个前面没有反斜杠的反引号终止命令替换。当使用$(command)的形式时,在括号之间的所有字符被当做命令,没有特殊处理。
命令替换可以嵌套。使用反引号形式时,嵌套内部的反引号要用反斜杠转义。
如果替换出现在双引号中,在结果上不执行单词分割和文件名扩展。
3.5.5 算术扩展
算术扩展允许计算一个算术表达式并替换为结果。算术扩展的格式是:
$(( expression ))
表达式被视为是在双引号内,但括号内的双引号是不会特殊处理的。在表达式中的所有标记进行参数扩展,命令替换和引号移除。算术扩展可以嵌套。
根据下面列出(参阅Shell算术)的规则进行计算。如果表达式是无效的,bash打印指出问题的消息到标准错误,并且不做替换。
3.5.6 进程替换
进程替换仅仅在支持命名管道(FIFO)或/dev/fd来命名打开的文件的系统上可用。它采取的形式是:
<(list)
或
>(list)
进程list运行时,输入或输出连接到FIFO或在/dev/fd中的文件。作为扩展的结果,把此文件名作为参数传递到当前命令。如果使用>(list)的形式,对该文件的写入,将为list提供输入。如果使用<(list)形式时,作为参数传递的文件应被读取,以获得list的输出。需要注意的<或>和左括号之间是没有空格的,否则将被解释为重定向。
当进程替换可用时,进程替换和参数变量扩展,命令替换和算术扩展,同时进行。
3.5.7 单词分割
shell扫描参数扩展,命令替换和算术扩展的结果,对于没有被双引号包含的内容进行单词分割。
shell将$IFS的每个字符作为分隔符,按照这些字符分割其他扩展的结果。如果$IFS未设置,或者它的值正好是<space><tab><newline>这样的缺省值,那么<space>,<tab>,<newline>的序列,出现在其他扩展的结果的开始和结束位置时,将被忽略,而没有出现在开头或结尾的任何IFS字符的序列起到分隔的作用。如果IFS的值不是缺省值,那么,只要空白字符在IFS(IFS空白字符)的值中出现,单词开头和结尾的空白字符(space和tab)就被忽略。在IFS字符中不是IFS空白字符的那些字符,随着任何相邻的IFS空白字符起到分隔字段的作用。IFS空白字符的序列也被视为一个分隔符。如果IFS的值是null,则不会发生单词分割。
显式的空值参数(""或者'')将被保留。不带引号的隐式空值参数,从参数扩展来的没有值的结果,将被删除。如果一个没有值的参数在双引号中扩展,则产生一个空值参数,并被保留下来。
请注意,如果没有发生扩展,则不进行单词分割。
3.5.8 文件名扩展
•模式匹配:shell如何匹配模式。
在单词分割之后,除非-f选项已被设置(参见内建命令set),Bash将扫描每个单词中的字符'*','?',和'['。如果这些字符中的任一个出现,那么这个单词被视为一个模式,并且被替换成和模式相匹配的按字母顺序排序的文件名列表。如果没有匹配的文件名,并且shell选项nullglob被禁用,单词保持不变。 如果nullglob选项被设置,并且没有找到任何匹配,这个单词被删除。如果设置了shell选项failglob,并且没有找到任何匹配,则显示错误消息,而且不执行该命令。 如果启用了shell选项nocaseglob,匹配时不考虑字母大小写。
当一个模式用于文件名扩展时,字符'.'位于文件名开始位置,或紧随一个斜线时,必须明确地匹配,除非shell的选项dotglob被设置。当匹配文件名时,斜线字符必须总是明确地匹配。其他情况下,'.'字符不作特殊处理。
请参阅内建命令shopt命令中shopt的描述,以查看nocaseglob,nullglob,failglob,和dotglob选项的说明。
shell变量GLOBIGNORE可用于限制匹配模式的文件名集合。如果设置了GLOBIGNORE,每个匹配的文件名,也符合GLOBIGNORE中的一个模式的文件名将从匹配列表中删除。GLOBIGNORE被设置且不是空时,文件名.和..总是被忽略。然而,设置GLOBIGNORE为一个非空值,也起到启用shell选项dotglob的效果,这样所有以'.'开头的其他的文件名也将匹配。要获得原来的行为——忽略以'.'开头的文件名,则需要在GLOBIGNORE中设置一个'.*'的模式。 GLOBIGNORE被取消设置时,dotglob选项被禁用。
3.5.8.1 模式匹配
除了下面描述的特殊模式字符以外的,任何出现在模式中的字符,匹配其本身。NUL字符不会出现在模式中。反斜杠转义以下的字符,匹配时反斜线自身被丢弃。如果特殊模式字符要匹配字面上的含义时,必须用引号包起来。
特殊模式字符有以下含义:
*
匹配任何字符串,包括空字符串。当shell启用了选项globstar,并在文件名扩展上下文中使用“*”时,相邻的两个“*”用来作为一个单一的模式,以匹配所有文件和零个或多个目录和子目录。如果跟在'/'后面,两个相邻的'*'将只匹配目录和子目录。
?
匹配任意单个字符。
[…]
匹配包围的字符中的任何一个。一对由连字符隔开的字符表示一个(range expression)范围表达式;任何排序在这两个字符之间的字符,包含边界上的字符被匹配——使用当前区域设置的排序序列和字符集。如果'['之后的第一个字符是一个'!'或一个'^',那么未包括在范围表达式中的任何字符被匹配。 '-'可以被匹配的情况是,把它作为集合的第一个或最后一个字符时。 ']'可以被匹配的情况是,它是集合中的第一个字符。范围表达式中的字符的排序顺序是由目前的区域设置和shell变量LC_COLLATE的值(假如已被设置)决定的。
例如,在默认的C区域设置环境下,'[a-dx-z]'相当于'[abcdxyz]'。许多区域设置场合,字符按字典顺序排序,在这些场合中,'[a-dx-z]'通常不等于'[abcdxyz]',它可能是相当于'[aBbCcDdxXyYz]'。在方括号表达式中,为了获得的传统上的范围结果,你可以强制使用C区域设置,设置LC_COLLATE或LC_ALL环境变量的值为'C'。
在‘[’和‘]’中,可以使用语法[:class:]指定(character class)字符类,其中class是在POSIX标准中定义的下列类之一:
alnum alpha ascii blank cntrl digit graph lower
print punct space upper word xdigit
一个字符类匹配属于该类的任何字符。word字符类匹配字母,数字和'_'。
在'[',']'中,可以使用语法[=c=]指定一个等价类,匹配所有和字符c具有相同权重(由当前区域设置定义)的所有字符。
在'[',']'中,语法[.symbol.]匹配校对符号symbol。
如果使用内建命令shopt启用了shell选项extglob,几个扩展模式匹配被识别。在以下的说明中,pattern-list是由'|'分隔的一个或多个模式组成的列表。可以使用下列子模式中的一个或多个组成复合模式。
?(pattern-list)
匹配零个或一个给定的模式。
*(pattern-list)
匹配零个或多个给定的模式。
+(pattern-list)
匹配一个或多个给定的模式。
@(pattern-list)
匹配一个给定的模式。
!(pattern-list)
不匹配任何一个给定的模式。
3.5.9 引号移除
在前述的扩展之后,所有不是从任何一个上述扩展中产生的不带引号的字符'\',''',和'“'被移除。
3.6 重定向
在一个命令被执行前,可能会使用一个特殊的符号,重定向它的输入和输出。重定向也可以用来在当前shell执行环境中打开和关闭文件。下面的重定向操作符可以出现在一个简单的命令之前或命令中,或出现在命令之后。重定向由左到右,按照出现的顺序处理。
每个重定向之前可能有一个文件描述符号码,也可能是这种形式{varname}。在这种情况下,对于每个重定向操作符,除>&-和 <&-以外 ,shell将分配一个大于10的文件描述符给{varname}。如果>&-或者<&-前面是{varname},则varname的值定义了要关闭的文件描述符。
在以下描述中,如果文件描述符号码被省略,并且重定向操作符的第一个字符是“<”,则重定向指向的是标准输入(文件描述符0)。如果重定向操作符的第一个字符是'>',重定向指向的是标准输出(文件描述符1)。
在下面的描述中,除非另有说明,重定向操作符之后的单词,要执行大括号扩展,波浪线扩展,参数扩展,命令替换,算术扩展,引号移除,文件名扩展,和单词分割。如果扩展结果多于一个单词,则Bash会报告一个错误。
需要注意的是重定向的顺序是很重要的。例如,命令
ls > dirlist 2>&1
表明把标准输出(文件描述符1)和标准错误(文件描述符2)重定向到文件 dirlist,而命令
ls 2>&1 > dirlist
表明仅仅把标准输出重定向到文件dirlist,因为在标准输出重定向到dirlist之前,标准错误已被作成了标准输出的副本。
Bash在重定向中对几个文件名要作特殊的处理,如下表:
/dev/fd/fd
如果fd是一个合法的整数,文件描述符fd被复制。
/dev/stdin
文件描述符0被复制。
/dev/stdout
文件描述符1被复制。
/dev/stderr
文件描述符2被复制。
/dev/tcp/host/port
如果host是一个有效的主机名或Internet地址,并且port是一个整数端口号或服务名,Bash试图打开一个到相应socket的TCP连接。
/dev/udp/host/port
如果host是一个有效的主机名或Internet地址,并且port是一个整数端口号或服务名,Bash试图打开一个到相应socket的UDP连接。
打开或创建一个文件失败,造成重定向失败。
在重定向时,应谨慎使用大于9的文件描述符,因为它们可能和shell使用的文件描述符冲突。
3.6.1 输入重定向
输入重定向是,以表达式word被扩展的结果字符串为名字的文件被打开,以准备从文件描述符n读出,或如果没有指定n,则准备从标准输入(文件描述符0)读出。
输入重定向的一般格式是:
[n]<word
输出重定向是,以表达式word被扩展的结果字符串为名字的文件被打开,以接受从文件描述符n的写入,或如果没有指定n,则接受从标准输出(文件描述符1)的写入。
输出重定向的一般格式是:
[n]>[|]word
如果重定向操作符是'>',内建命令set的noclobber选项已启用,那么,如果表达式word被扩展的结果字符串为名字的文件存在并且是一个普通文件,则重定向失败。如果重定向操作符是'>|',或重定向操作符是'>',并且noclobber选项是未启用的,即使以word命名的文件存在,也试图重定向。
以这种方式输出重定向,以表达式word被扩展的结果字符串为名字的文件以追加方式被打开,以接受从文件描述符n的写入,或如果没有指定n,则接受从标准输出(文件描述符1)的写入。如果该文件不存在,则创建它。
追加输出重定向的一般格式是:
[n]>>word
这种结构可以把标准输出(文件描述符1)和标准错误输出(文件描述符2)重定向到word扩展结果字符串为文件名的文件中。
标准输出和标准错误重定向的格式有两种:
&>word
和
>&word
两种形式中,常用第一种。这种方式在语义上等同于
>word 2>&1
这种结构可以把标准输出(文件描述符1)和标准错误输出(文件描述符2)以追加方式重定向到word扩展结果字符串为文件名的文件中。
追加标准输出和标准错误重定向的格式是:
&>>word
这在语义上等同于
>>word 2>&1
3.6.6 Here文档(即时文档)
这种类型的重定向,指示shell从当前的源读取输入,直到读到仅仅包含word(没有尾随空白)的行为止。所有在那一点前读入的行,作为命令的标准输入。
Here文档的格式是:
<<[-]word
here-document
delimiter
在word上不执行参数扩展,命令替换,算术扩展,文件名扩展。如果word中任何字符被引号包含,delimiter是在word上作引号移除得到的结果,而here-document中的行不会被扩展。如果word没有引号,here-document的所有的行都是参数扩展,命令替换和算术扩展的对象。在后一种情况下,字符序列\newline将被忽略,并且'\'必须被用来引用字符'\','$',和'`'。
如果重定向操作符是'<<-',那么所有输入行和包含delimiter的行的开头的制表符被去除。这使得here文档在shell脚本文件中以自然方式缩进。
3.6.7 Here字符串(即时字符串)
这里的一个here文档的变种,其格式为:
<<< word
word被扩展并且作为命令的标准输入。
3.6.8 复制文件描述符
重定向操作符
[n]<&word
用于复制输入文件描述符。如果word扩展为一个或多个数字,n表示的文件描述符将成为该文件描述符的副本。如果word中的数字不指向一个输入文件描述符,会产生重定向错误。如果word的结果为‘-’,则关闭文件描述符n。如果n未指定,则使用标准输入(文件描述符0)。
操作符
[n]>&word
和复制输出文件描述符类似。如果n没有指定,则使用标准输出(文件描述符1)。如果word中的数字不指向一个输出文件描述符,会产生重定向错误。作为一个特殊情况,如果n被省略,并且word没有扩展到1个或多个数字,标准输出和标准错误将如前所述被重定向。
3.6.9 移动文件描述符
重定向操作符
[n]<&digit-
移动文件描述符digit到文件描述符n,或,如果未指定n,则移动到标准输入(文件描述符0)。digit被复制到n后,就被关闭。
同样的,重定向操作符
[n]>&digit-
移动文件描述符digit到文件描述符n,或,如果未指定n,则移动到标准输出(文件描述符1)。
3.6.10 打开文件描述符以读和写
重定向操作符
[n]<>word
使名称是word扩展结果的文件被打开,以准备从文件描述符n读取和写入,如果未指定n,则使用文件描述符0。如果该文件不存在,则创建它。
3.7 执行命令
•简单命令扩展:bash如何在执行前扩展简单命令。
•命令搜索和执行:bash如何找到命令和运行。
•命令执行环境:bash执行非shell内建命令的环境。
•环境:命令的环境。
•退出状态:命令返回的状态以及bash如何解释它。
•信号:bash或运行的命令接收到信号时,会发生什么。
3.7.1 简单命令扩展
当一个简单命令执行时,shell由左到右执行以下的扩展,赋值和重定向。
1.那些已经被解析器标记为变量赋值(位于命令前面)和重定向的单词,被保存供以后处理。
2.那些不是变量赋值或重定向的单词被扩展(Shell扩展)。如果扩展的结果包含单词的话,第一个单词是命令的名称,余下的是参数。
4.对于每个变量赋值,先对'='后的文本进行波浪线扩展,参数扩展,命令替换,算术扩展和引号移除,然后再赋值给变量。
如果扩展结果中没有命令名,变量赋值影响当前的shell环境。否则,这些变量被添加到该命令的环境,不影响当前的shell环境。如果尝试赋值到一个只读变量,会发生错误,并且命令退出时返回一个非零的状态。
如果扩展结果中没有命令名,则执行重定向,但不影响当前的shell环境。重定向错误将导致该命令退出,并返回一个非零的状态。
如果扩展结果中有一个命令名,按下述进行命令的执行。否则,该命令将退出。如果扩展中包含了一个命令替换,命令的退出状态是最后执行的命令替换的退出状态。如果没有命令替换,命令退出状态为0。
3.7.2 命令搜索和执行
在命令已经分解成单词后,如果结果是一个简单的命令和一个可选的参数列表,将采取如下动作。
1.如果命令名称中没有包含斜杠,shell试图定位该命令。如果存在同名的shell函数,该函数被调用(见shell函数)。
2.如果名称和函数不匹配,shell在内建命令列表中搜索。如果找到一个匹配项,则该内建命令被调用。
3.如果名字既不是shell函数,也不是内建命令,并且命令名字不包含斜线,bash搜索$PATH中的每一个成员,试图寻找包含该名称的可执行文件的目录。 bash使用一个哈希表来记住可执行文件的全路径名,以避免重复的PATH搜索(见Bourne shell的内建命令中hash的描述)。只有当命令在哈希表中没有找到时,才对$PATH中的目录进行完整的搜索。如果搜索不成功,shell试图搜索一个预定义的shell函数command_not_found_handle。如果该函数存在,它被最初的命令调用,最初的命令的参数作为它的参数,函数的退出状态成为shell的退出状态。如果该函数没有被定义,shell输出错误消息并返回一个退出状态127。
4.如果搜索是成功的,或如果该命令名中包含一个或多个斜杠,shell将在单独的执行环境中执行指定的程序。参数0被设置为给定的名称,该命令的其余参数(如果有的话),被设置为该程序支持的参数。
5.如果因为文件不是可执行格式而执行失败,并且该文件不是一个目录,则它被认为是一个shell脚本,shell将执行它(见shell脚本)。
6.如果该命令不是异步命令,shell等待命令完成并收集它的退出状态。
3.7.3 命令执行环境
shell的执行环境,由以下部分组成:
·在调用时,打开的文件被shell继承,同时,被exec内建命令提供的重定向修改
·当前工作目录被cd,pushd或者popd设置,或在调用时被shell继承
·文件创建模式掩码由umask设置,或继承自这个shell的父shell
·当前的陷阱由trap设置
·shell参数被变量赋值,或者set命令设置,或者继承自父shell
·shell函数在执行被定义,或者继承自所在环境中的父shell
·在调用时(通过缺省值,或者命令行参数)被启用,或通过set启用的选项
·shopt启用的选项(见内建命令shopt)
·通过alias定义的别名(见别名)
当执行一个简单命令,而不是内建命令或者shell函数时,它将在一个单独的执行环境中被调用,该环境由下面这些组成。除非另有说明,否则,值将继承自shell。
·shell打开的文件,以及通过重定向传给命令的修改和附加的内容
·当前的工作目录
·文件创建模式掩码
·被标记为导出的shell变量和函数,以及为命令导出的变量,和在环境中传递的变量(见环境)
·被shell捕获的陷阱,被重新设置成继承自父shell的值,被shell忽略的陷阱将被忽略
在独立的环境中调用的命令,不会影响shell的执行环境。
命令替换,通过括号分组的命令,在子shell环境中调用的异步命令,其环境是shell环境的复制品,除了shell捕获的陷阱在调用时,被重设为继承自父shell的值。作为管道的一部分而被调用的内置命令,也是在一个子shell环境中执行的。在子shell环境中所做的更改不会影响shell的执行环境。
子shell在执行命令替换时,继承父shell的-e选项的值。在非POSIX模式时,bash清除该子shell中的-e选项。
如果命令的结尾是一个'&',并且作业控制未激活时,该命令的默认标准输入是空文件/dev/null。否则,被调用的命令继承调用它的shell的文件描述符。
3.7.4 环境
当一个程序被调用时,它被赋予一个字符串数组,这个数组称为环境。这是一个名-值对列表,形式为name=value。
Bash提供了几种方法来操作环境。在调用时,shell扫描自己的环境,并为每个找到的名字创建一个参数,自动将其标记为导出到子进程。被执行的命令继承该环境。export 和'declare -x'命令允许在环境中,增加和删除参数和函数。如果该环境中的某个参数值被修改,则新的值取代旧的成为环境的一部分。任何被执行的命令继承的环境中,包括shell的初始环境,其值可能在shell中被修改:通过unset和‘export -n’命令移除,通过export和‘declare -x’增加。
对于任何简单命令或函数的环境,可能会通过前缀参数赋值,被临时参数化。见shell参数中的描述。这些赋值语句只影响该命令所能看到的环境。
如果-k选项被设置(参见内建命令set),那么,对于命令来说,所有的参数赋值被置于环境中,而不仅仅位于命令名前。
当bash调用外部命令时,变量‘$ _'被设置为命令的完整路径名,并被传递到该命令的环境中。
3.7.5 退出状态
被执行命令的退出状态,是通过waitpid系统调用返回的值或等效的函数的返回值。退出状态介于0和255之间,但是,正如下文所述,shell专门使用大于125的值。来自shell的内建命令和复合命令的退出状态,也被限于这个范围内。在某些情况下,shell将使用特殊的值来表示特定的故障模式。
对shell来说,返回状态为0的命令意味着成功。而一个非零的退出状态表示失败。使用这种看起来似乎是反直觉的模式,导致以一个良好定义的方式来表示成功,以多种方式来指示各种故障的模式。当一个命令因一个致命信号N而终止时,bash使用值128+ N作为退出状态。
如果未找到命令,被创建以执行它的子进程返回状态127。如果命令被找到,但不是可执行文件,返回状态是126。
如果一个命令在扩展或重定向时失败,则退出状态大于零。
退出状态可以用于bash的条件命令(请参阅条件结构)和一些列表结构(见列表)。
所有的Bash内建命令,如果他们成功则返回退出状态零,失败则非零,所以可用于条件和列表结构。所有的内建命令返回退出状态为2,以表示用法不正确。
3.7.6 信号
当Bash在交互状态时,没有任何陷阱,它忽略SIGTERM(这样“kill 0”不杀交互式shell),SIGINT被捕获并处理(这样内建命令wait可中断)。当Bash收到一个SIGINT信号,它跳出任何正在执行的循环。在所有情况下,Bash会忽略SIGQUIT。如果作业控制有效(见作业控制),Bash会忽略SIGTTIN,SIGTTOU,SIGTSTP。
Bash启动的非内建命令,信号处理操作被设置成从其父shell继承的值。当作业控制无效时,异步命令忽略SIGINT和SIGQUIT,除非他们继承了操作。命令替换的结果中的命令,忽略键盘产生的作业控制信号SIGTTIN,SIGTTOU,和SIGTSTP。
默认情况下,在收到一个SIGHUP时,shell退出。在退出之前,一个交互式shell重新发送SIGHUP到所有作业——运行或停止状态。停止的作业,发送SIGCONT以确保他们收到SIGHUP。为了防止shell发送SIGHUP信号到一个特定的作业,应使用内建命令disown(见作业控制内建命令)把该作业从作业表中删除,或使用disown -h标记为不接收SIGHUP。
如果shell选项huponexit已被设置命令shopt(见内建命令shopt)设置,Bash会在一个交互登录shell退出时,发送一个SIGHUP到所有作业。
如果bash正在等待一个命令的完成,并且收到陷阱被设置的信号,陷阱将在命令完成后执行。当Bash正在通过wait内建命令等待异步命令时,收到陷阱已设置的信号,会导致内置命令wait立即返回,并且退出状态大于128,其后立即执行陷阱。
3.8 Shell脚本
shell脚本是一个文本文件,其中包含shell命令。当调用bash时,把这样的文件用作第一个非选项参数时,并且没有指定-c或-s选项(见调用Bash),则Bash读取和执行文件中的命令,然后退出。这种操作模式,创建了一个非交互的shell。 shell首先在当前目录中搜索该文件,如果没有找到,会在$PATH中的目录搜索。
当bash运行一个shell脚本,它设置特殊参数0为文件名,而不是shell的名称,位置参数设置为剩余的参数,如果有的话。如果没有提供额外的参数,位置参数则是未设定状态。
可以使用chmod命令来打开执行位,以使一个shell脚本变成可执行文件。当Bash在$PATH中搜索命令时,找到这样的文件时,它会产生一个子shell来执行它。换句话说,执行
filename arguments
相当于执行
bash filename arguments
如果filename 是可执行的shell脚本。子shell重新初始化它自己,达到这样的效果:就像一个新的shell被调用来解释该脚本,除了由父shell记录的(见Bourne shell的内建命令中hash的描述)命令的位置,由子shell保持。
大多数的Unix版本,把这作为操作系统命令执行机制的一部分。如果脚本的第一行开始的两个字符是'#!',这就是表示该行是指定程序的解释器。因此,您可以指定bash,awk,Perl或一些其他的解释器,并使用该语言编写脚本文件的其余部分。
在脚本文件的第一行,解释器的参数包括一个跟在解释器后的可选的参数,后面是脚本文件的名称,然后是其余的参数。 Bash在操作系统上将不处理它自己。需要注意的是,一些老版本的Unix的解释器名称和参数被限制到最多32个字符。
Bash脚本通常以 #!/bin/bash(假设bash已经安装在/bin),因为这样能确保Bash将被用来解释脚本,哪怕是另一个shell下执行该脚本。
4 shell内建命令
•Bourne shell的内建命令:从Bourne shell继承的内建命令。
•Bash内建命令:Bash的内建命令表格。
•修改shell的行为:修改shell的属性和可选的行为的内建命令。
•特殊内建命令:POSIX专属的内建命令。
内建命令被包含在shell本身里。当一个内建命令作为一个简单的命令(见简单的命令)的第一个单词时,shell将直接执行该命令,而无需调用其他程序。对于通过分开的实用程序不可能实现,或者不方便获得的功能来说,内建命令是很必要的。
本节简要介绍了Bash继承自Bourne shell的内建命令,以及Bash独有的或在Bash中得到扩充的内建命令。
有几个内置命令将在其他章节中描述:提供了作业控制工具和Bash的接口的内建命令(见作业控制内建命令),目录栈(见目录栈内建命令),命令历史记录(见bash的历史内建命令),和可编程补全功能(见可编程补全内建命令)。
很多内建命令都被POSIX或Bash扩充了。
除非另有说明,每一个记录为接受前面带'-'的选项的内建命令都接受'-- '来表示选项的结尾。 :,true,false,和 test内建命令不接受选项,不特殊处理'-- '。 exit,logout,let,和shift内建命令接受和处理以'-'开头而不带'--'的参数。其他接受参数但是没有说明接受选项的内建命令,把以‘-’开头的参数解释为无效的选项,并需要通过'--',以防止这种解释。
4.1 Bourne shell的内建命令
下面的shell内建命令都继承自Bourne shell的。这些命令都是按照POSIX标准内容实现的。
:(冒号)
: [arguments]
仅仅扩展arguments,和进行重定向。返回状态是零。
.(句号)
. filename [arguments]
当前shell环境中,读取和执行参数filename中的命令。如果filename不包含斜杠,使用PATH变量,寻找filename 。当Bash不在POSIX模式下,如果在$PATH中没有找到filename 的话,则在当前目录中搜索。如果提供了任何arguments,在执行filename时,它们成为位置参数。否则的位置参数都保持不变。返回状态是最后执行的命令的退出状态,或者,如果没有命令被执行,则是0。如果没有找到filename,或无法读取filename,返回状态是非零值。这个内建命令等价于source。
break
break [n]
从for,while,until或select循环中退出。如果提供了n时,从第n个封闭循环退出。 n必须大于或等于1。返回状态是零,除非n不大于或等于1。
cd
cd [-L|[-P [-e]]] [directory]
改变当前的工作目录到directory。如果没有给出directory,则使用shell变量HOME的值。如果shell变量CDPATH存在,把它作为搜索路径。如果directory以斜线开头,则不使用CDPATH。
-p选项意味着不跟随符号链接;默认情况,或带-L选项时,跟随符号链接。 如果-P和-e选项同时使用,并成功进行了目录的变化,而当前的工作目录不能被成功确定时,cd将返回一个失败的状态。如果directory是' - ',这是等同于$OLDPWD。
如果使用了来自CDPATH的非空目录名时,或者,如果' - '是第一个参数,并且目录的改变是成功的,新的工作目录的绝对路径被写到标准输出。
如果成功地改变了目录,则返回状态是零,否则返回非零。
continue
continue [n]
继续一个for,while,until,或者select循环的下一次迭代。如果指定了n,则继续执行第n个封闭循环。 n必须大于或等于1。返回状态是为零,除非n不大于或等于1。
eval
eval [arguments]
把参数连接在一起,形成一个命令,然后读取和执行,它的退出状态被返回当做eval的退出状态。如果没有参数,或只有空参数,返回值是零。
exec
exec [-cl] [-a name] [command [arguments]]
如果指定了command,则它取代shell,而不创建一个新的进程。如果使用-l选项,shell放置一个'-'到command的第零个参数的开头。这是login程序的做法。 -c选项会导致在一个空环境中执行command。如果使用-a,shell把name作为第零个参数传给command。如果没有指定command,可能会使用重定向去影响当前的shell环境。如果没有发生重定向错误,返回状态是0,否则返回状态是非零。
exit
exit [n]
退出shell,返回一个状态n到父shell。如果省略n,退出状态是最后执行的命令的状态。在shell终止之前执行任何EXIT上的陷阱。
4.1 Bourne shell的内建命令(续)
export
export [-fn] [-p] [name[=value]]
在环境中,标记每个被传送到子shell中的name。如果使用-f选项,则name指的是shell函数,否则name指的是shell变量。 -n选项意味着,不再为导出而标记每一个name。如果没有指定name,或如果使用-p选项,则显示已经导出的名称的列表。 -p选项显示的输出形式,可以重用为输入。如果变量名的后面是=value,则变量的值被设置为value。
返回值是零,除非提供了无效的选项,其中一个名字不是一个有效的shell变量名,或者带-f选项的名字不是一个shell函数的名称。
getopts
getopts optstring name [args]
getopts被shell脚本用来解析位置参数。 optstring中包含需要识别的选项字符;如果字符后面跟着一个冒号,则预计该选项会有一个参数,应该用空格分开选项。冒号(’:‘)和问号(’?‘)不能被作为选项字符。每次调用getopts时,该命令把下一个选项放到shell变量name中,如果name不存在,就初始化它,同时,下一个参数的索引被记录到变量OPTIND中。 每次调用shell或shell脚本时,OPTIND被初始化为1。当一个选项需要一个参数时,getopts把那个参数放到变量OPTARG中。 shell不会自动复位OPTIND;如果要使用一组新的参数,则需要在同一个shell中多次调用getopts时,手动复位。
当遇到选项结束时,getopts将退出,并且返回值大于零。 OPTIND被设置为第一个非选项参数的索引,name设置为‘?’。
getopts一般用来解析位置参数,但如果在args中有更多的参数,则getopts解析args中的参数。
getopts可以通过两种方式报告错误。如果optstring中的第一个字符是一个冒号,使用(silent)静默错误报告。一般地,当遇到无效选项或者缺少选项参数的情况时,打印诊断消息。如果变量OPTERR被设置为0,则不显示错误消息,即使optstring中的第一个字符不是冒号。
如果一个无效的选项出现,getopts把name置为‘?’,如果不是静默模式,打印错误消息并取消OPTARG的设置。如果getopts是在静默模式,找到的选项字符被放置在OPTARG,且不打印诊断消息。
如果没有找到所需的参数,并且getopts是非静默模式,则一个问号(‘?’)被放置在name中,OPTARG被取消设置,然后打印诊断消息。如果getopts是静默模式,则一个冒号(‘:’)被放置在name中,然后OPTARG被设置为找到的选项字符。
hash
hash [-r] [-p filename] [-dt] [name]
每一次hash被调用时,它会记住为name参数指定的命令的全路径名,因此在后续调用时不需要搜索该命令。在$PATH列出的目录中搜索该命令。任何先前记住的路径名被丢弃。 -p选项抑制路径搜索,并且把filename作为name的位置。 -r选项,令shell忘记所有已经记住的位置。使用-d选项,使shell忘记每一个已经记住的name的位置。如果使用-t选项,每个name对应的完整路径名被打印出来。如果有多个name,并且带-t选项,则哈希全路径名前打印name。 使用-l选项,导致输出中显示可在输入中重复使用的格式。如果没有参数,如果只有-l选项,记住的命令信息被打印出来。返回值是零,除非有一个name没有被找到,或提供了无效的选项。
pwd
pwd [-LP]
打印当前的工作目录的绝对路径名。如果使用-p选项,打印的路径名中不包含符号链接。如果使用-L选项,打印的路径名可包含符号链接。返回状态是零,除非在确定当前目录时遇到错误,或者,提供了无效的选项。
readonly
readonly [-aAf] [-p] [name[=value]] …
把每个name标记为只读。这些name的值在后续赋值时,不会被改变。如果使用-f选项,每一个name是指一个shell函数。 使用-a选项,表示每个name是一个索引的数组变量;使用-A选项,是指每个name,指向的是一个关联数组变量。如果两个选项同时出现,则-A最优先。如果没有name参数,或者,如果使用-p选项,打印所有的只读的name。其他选项可用于将输出限制为只读name的组的一个子集。 使用-p选项,导致输出中显示可在输入中重复使用的格式。如果一个变量名后面是=value,则变量的值被设置为value。返回状态是零,除非提供了无效的选项,name参数之一不是有效的shell变量或函数的名称,或有-f选项时,name不是shell函数。
return
return [n]
引起一个shell函数携带返回值n退出。如果未提供n,则返回值是函数中执行的最后一个命令的退出状态。这也可以用于终止使用内建命令.(source)启动并执行的脚本的执行,返回值是n,或在脚本中执行的最后一个命令的退出状态,此返回值作为脚本的返回值。任何和RETURN陷阱关联的命令,在函数或脚本之后继续执行命令之前执行。如果在函数之外使用return,并且不是通过.(source)启动并执行的脚本,则返回状态是非零值。
shift
shift [n]
把位置参数向左移动n个位置。从 n+1 … $#的位置参数被重新命名为$1 … $#-n。从$# 到 $#-n+1 的数字所代表的参数被取消设置。 n必须是一个小于或等于$#非负的数。如果n是零,或大于$#,位置参数不改变。如果没有n,则它被假定为1。返回状态是为零,除非n大于$#或小于零,否则返回非零值。
test
[
计算一个条件表达式expr。每个操作符和操作数必须是分开的参数。表达式的组成部分,见下述Bash中的条件表达式的描述。test不接受任何选项,也不接受和忽略带--的参数选项。
当使用[形式时,该命令的最后一个参数必须是一个]。
表达式可以使用下面的操作符结合,并且以优先级降低的顺序列出。计算依赖于参数的个数,见下文。当有5个或更多参数使,使用运算符优先级。
! expr
如果expr是假,结果为真。
( expr )
返回expr的值。可用于覆盖正常的运算优先级。
expr1 -a expr2
如果expr1和expr2都是真,结果为真。
expr1 -o expr2
test和[内建命令,使用基于参数个数的一组规则计算条件表达式。如果expr1或者expr2是真,结果为真。
0个参数
表达式结果为假。
1个参数
当且仅当表达式非空时,结果为真。
2个参数
如果第一个参数是'!',当且仅当第二个参数为空时,表达式为真。如果第一个参数是一个一元条件运算符(参见bash的条件表达式),如果一元的测试结果为真,表达式为真。如果第一个参数不是一个有效的一元运算符,表达式为假。
3个参数
以下条件适用于列出的顺序。如果第二个参数是一个的二进制条件运算符(请参阅Bash的条件表达式),表达式的结果是使用的第一个和第三个参数作为操作数的二进制测试的结果。有三个参数的情况下, '-a'和'-o'运算符被认为是二元运算符。如果第一个参数是'!',使用第二个和第三个参数进行2个参数的test结果的否。如果第一个参数是'(',并且第三个参数是')',结果对第二个参数进行1个参数的test的结果。否则,表达式为假。
4个参数
如果第一个参数是'!',结果是其余参数的3个参数test的结果的否。否则,表达式根据上面列出的优先级规则,被分解和计算。
5个及更多参数
表达式根据上面列出的优先级规则,被分解和计算。
当和test或者'['同时使用时,'<' 和'>'使用ASCII顺序进行词典序排序。
times
times
打印shell和子shell使用的用户和系统时间。返回值是0。
trap
trap [-lp] [arg] [sigspec …]
在shell收到sigspec信号时,读取和执行在arg中的命令。如果arg未指定(同时有一个sigspec),或arg是' - ',则每一个指定信号的值被重置到该shell启动时它的值。如果arg是空字符串,那么每一个sigspec指定的信号被shell和该shell调用的命令忽略。如果arg未指定,并且有-p选项,则shell显示和每个sigspec关联的陷阱命令。如果没有提供参数,或只有-p选项,则trap打印和每个信号编号关联的命令列表,列表的形式可以被重用为shell的输入。 -l选项,使shell打印信号名称及其相应编号的列表。每个sigspec可以是信号名或信号编号。信号名不区分大小写,SIG前缀是可选的。
如果sigspec是0或EXIT,arg在shell退出时执行。如果sigspec是DEBUG,则arg的执行点在以下命令之前:每一个简单命令、for命令,case命令,select命令,每个算术for命令,和shell函数中的第一个命令执行之前。关于DEBUG陷阱的效果的详细信息,请参阅内建命令shopt的extdebug选项的描述(见内建命令shopt)。如果sigspec是RETURN,则命令arg在每个shell函数执行一次,或者,在使用.或者source内建命令执行的脚本执行结束时执行一次。
如果sigspec是ERR,除了下列条件,当一个简单命令有一个非零退出状态时,命令arg被执行。 ERR陷阱在以下情况不执行:如果失败的命令是紧跟在until或者while关键字后面的命令列表的一部分,紧跟在if或者elif关键字之后的测试的一部分,在&&或| |列表中执行的命令的一部分,或该命令的返回状态被!翻转。这些条件和errexit选项具有相同的条件。
在进入shell时忽略的信号,不能被捕获或重置。没有被忽略的信号,在被捕获后,被复位到子shell或shell环境被创建时的原始值。
返回状态是零,除非sigspec没有指定一个有效的信号。
umask
umask [-p] [-S] [mode]
设置shell进程的文件创建掩码为mode。如果mode以数字开头,则它被解释为一个八进制数;如果不是,它被解释为一个类似于可用于chmod命令的符号模式掩码。如果省略mode,则打印当前掩码的值。如果使用-S选项,且没有mode参数,则模式被打印为符号格式。如果有-p选项,并省略mode参数,则输出是可以重用为输入的形式。如果模式成功地被改变,或者,没有mode参数,则返回状态是零,否则返回非零值。
需要注意的是,当模式被解释为一个八进制数,每个umask中的数字被7减。因此,umask为022的结果是755。
unset
unset [-fv] [name]
每一个名为name的变量或函数被删除。如果不提供任何选项,或使用-v选项,每个name指一个shell变量。如果使用-f选项,name是指shell函数,则函数的定义被删除。只读变量和函数不会被取消设置。返回值是零,除非name是只读的。
4.2 Bash的内建命令
本节介绍在Bash中独有的或已扩充的内建命令。其中的一些命令是POSIX标准中指定的。
alias
alias [-p] [name[=value] …]
如果不使用参数或-p选项,alias在标准输出中打印别名的列表,打印格式为能重用为输入的形式。如果使用了参数,则为value定义了名称为name的别名。如果没有给定value,则打印别名的name和value。关于别名的描述请参阅别名
bind
bind [-m keymap] [-lpsvPSV]
bind [-m keymap] [-q function] [-u function] [-r keyseq]
bind [-m keymap] -f filename
bind [-m keymap] -x keyseq:shell-command
bind [-m keymap] keyseq:function-name
bind readline-command
显示当前Readline(请参阅命令行编辑)键和函数绑定,绑定键序列到Readline函数或者宏,或者,设置Readline变量。每一个非选项参数是一个命令,该命令会出现在一个Readline初始化文件中(请参阅Readline初始化文件),但是,每个绑定或命令必须作为一个单独的参数传送,例如,‘"\C-x\C-r":re-read-init-file’。
如果有参数,则含义如下:
-m keymap
使用keymap作为键盘映射表而影响后续绑定。可以接受的keymap名字是emacs,emacs-standard,emacs-Meta,emacs-ctlx,vi,vi-move,vi-command,和 vi-insert。vi等价于vi-command;emacs等价于emacs-standard。
-l
列出所有Readline函数的名字。
-p
显示Readline函数名字和绑定,格式为可用于输入或者用在Readline初始化文件中。
-P
列出当前的Readline函数名和绑定。
-v
显示Readline变量名字和值,格式为可用于输入或者用在Readline初始化文件中。
-V
列出当前的Readline变量名和绑定。
-s
显示绑定到宏的Readline键序列和该宏的输出字符串,格式为可用于输入或者用在Readline初始化文件中。
-S
-f filename
从filename读入键绑定。
-q function
-u
解除所有绑定到function的键。
-r keyseq
删除所有当前对keyseq的绑定。
-x keyseq:shell-command
不管keyseq是否被输入,都执行shell-command。当shell-command被执行时,shell设置READLINE_LINE变量为Readline行缓冲区的内容,READLINE_POINT变量为插入点的当前位置。如果执行的命令改变了READLINE_LINE或者READLINE_POINT的值,则新的值在编辑状态被反映。
返回状态是0,除非有无效选项或者发生错误。
builtin
builtin [shell-builtin [args]]
运行一个shell的内建命令,传递指定参数给该内建命令,并返回它的退出状态。当定义一个和shell内建命令具有相同名字的shell函数时,这是非常有用的,可以在函数中保留内建命令的功能。如果shell-builtin不是shell内建命令时,返回状态是非零值。
caller
caller [expr]
返回任何活动的子程序调用(使用.或者source执行的shell函数或脚本)。
没有expr时,caller显示当前子程序调用的行号和源文件名。如果expr是一个非负的整数,caller显示当前执行的调用堆栈中的对应位置的行号、子程序名称和对应的源文件。可以使用额外的信息,例如,打印一个堆栈跟踪。当前帧是第0帧。
返回值是0,除非shell不执行子程序调用,或者expr不能对应到调用堆栈中的一个有效的位置。
command
command [-pVv] command [arguments …]
忽略任何名为command的shell函数,带arguments运行command。只有shell内置命令或通过搜索PATH发现的命令被执行。如果有一个叫做ls的shell函数,在函数中运行'command ls'会执行外部命令ls,而不是递归调用该函数。 -p选项意味着使用默认值即PATH,以保证能找到所有的标准实用工具程序。如果找不到command,或者发生错误,并且command的退出状态为其他,则返回的状态是127。
如果使用了-V或-v选项,则打印command的描述。 -v选项会导致显示一个单词,该单词表示调用command的命令或文件名;-V选项产生一个更详细的描述。在这种情况下,如果command被找到,则返回值是零,否则是非零值。
declare
declare [-aAfFilrtux] [-p] [name[=value] …]
声明变量并设置变量的属性。如果没有给出name,则显示变量的值。
-p选项将显示每个name的属性和值。当指定name参数并使用-p选项时,其他选项会被忽略。
当使用-p选项,且没有name参数时,declare将显示具有由其他选项指定的属性的变量的属性和值;如果没有提供其他选项,则declare将显示所有shell变量的属性和值。 -f选项将限制仅显示shell函数。
-F选项阻止显示函数定义;仅仅打印函数名和属性。如果使用命令shopt(见内建命令shopt)启用了shell选项extdebug,则同时显示该函数所在源文件名和该函数被定义的行号。 -F隐含着-f。
-g选项强制创建或修改全局变量,即使declare在shell函数中执行。在所有其他情况下,它会被忽略。
下列选项可以用来把输出限制在具有指定属性的变量,或给变量设置属性:
-a
每个name是一个索引数组变量(见数组)。
-A
每个name是一个关联数组变量(见数组)。
-f
仅使用函数名。
-i
变量按照整数来处理;给变量赋值时,执行算术运算(见shell算术)。
-l
-r
使name成为只读变量。这些变量名不能被再赋值或取消。
-t
给每个name增加trace属性。被跟踪的函数继承调用shell的DEBUG和RETURN陷阱。对变量来说,trace属性没有特别意义。
-u
-x
标记每个name,通过环境把它们导出到后续命令中。
使用'+',而不是' - '关闭属性,而作为例外,'+a'不能用来销毁一个数组变量,'+r'将不会移除只读属性。在函数中使用时,除非使用'-g'选项,declare使每个name成为局部变量,相当于local命令。如果name后面是=value,变量的值被设置为value。
返回值是零,除非遇到了无效的选项,或者试图使用'-f foo=bar‘定义函数,试图赋值给一个只读变量,试图不使用复合赋值语法(请参阅阵列)给一个数组变量赋值,或者,其中一个name不是一个有效的shell变量名,或者试图关闭只读变量的只读状态,试图关闭一个数组变量的数组状态,试图使用-f显示一个不存在的函数。
4.2 Bash的内建命令 续
echo
echo [-neE] [arg …]
输出的args之间用空格隔开,以一个换行符结束。返回的状态始终为0。如果指定了-n,其后的换行符被抑制。如果使用-e选项,则启用对后续反斜杠转义字符的解释。 -E选项禁用对这些转义字符解释,即使系统默认解释转义字符。shell选项xpg_echo 可以用来动态地决定echo是否默认启用扩展这些字符。echo不解释指选项的结束的 -- 。
echo解释如下转义字符序列:
\a
响铃
\b
退格键
\c
抑制后续输出
\e
\E
转义
\f
换页
\n
换行
\r
回车
\t
水平tab
\v
垂直tab
\\
反斜线
\0nnn
8bit字符,值为八进制的nnn(0到3位八进制数)
\0xHH
8bit字符,值为十六进制的HH(1或2位十六进制数)
\uHHHH
Unicode (ISO/IEC 10646)字符,值是十六进制的HHHH(1到4位十六进制数)
\uHHHHHHHH
Unicode (ISO/IEC 10646)字符,值是十六进制的HHHHHHHH(1到8位十六进制数)
enable
enable [-a] [-dnps] [-f filename] [name …]
启用和禁用shell内建命令。禁用内建命令,将允许一个磁盘命令——其名字和shell内建命令同名,在没有指定完整的路径名的情况下执行,即使shell通常会在搜索磁盘命令之前搜索内建命令。如果使用了-n选项,则names将被禁用。否则启用names。例如,要使用通过$PATH找到的test代替shell内建命令test: ‘enable -n test’ 。
如果使用-p选项,或没有name参数,则打印shell的内建命令列表。由于没有其他的参数,该列表包含所有启用的shell内建命令。 -a选项列出每一个内置命令,并指示该命令是否启用。
使用-f选项意味着在支持动态加载的系统上,从共享目标filename加载新的内建命令name。-d选项将删除由-f加载的内置命令。
如果没有选项,则显示shell内建命令的列表。 -s选项仅仅能启用POSIX特殊内建命令。如果同时使用-f 和-s选项,则新的内建命令成为一个特殊的内建命令(见特殊内建命令)。
返回状态是零,除非name不是一个shell的内建命令,或从共享目标加载新的内建命令时发生错误。
help
help [-dms] [pattern]
显示关于内建命令的帮助信息。如果指定了pattern,help提供所有匹配pattern的命令的详细帮助,否则打印内建命令列表。
-d
显示每个pattern的简短描述
-m
以manpage格式显示每个pattern的描述
-s
返回状态是0,除非没有匹配pattern的命令。
let内建命令可以对shell变量进行算术运算。每个expression按照下面的(见Shell运算)的规则计算。如果最后一个expression的值是0,let返回1;否则返回0。let expression [expression]
local
local [option] name[=value] …
对于每个参数,创建一个名为name的局部变量,并赋值value。option可以是任何declare接受的选项。local只能用在一个函数内部,它使得变量name的可见的范围被限制到该函数和它的子函数。返回状态是零,除非local在函数外使用,name是无效的,或者name是只读变量。
logout
logout [n]
退出一个登录shell,返回状态n到该shell的父shell。
mapfile
mapfile [-n count] [-O origin] [-s count] [-t] [-u fd] [
-C callback] [-c quantum] [array]
从标准输入中读取行到索引数组变量array中,或者,如果有-u选项时,从文件描述符fd读取内容。变量MAPFILE是缺省的array。选项具有以下含义:
-n
复制最多count行。如果count是0,则复制所有的行。
-O
从索引位置origin开始给array赋值。缺省索引是0。
-s
放弃开头读入的count行。
-t
从读入的每一行中,删除尾部的newline。
-u
从文件描述符fd读入行。
-C
每次读入quantum行时计算callback。-c选项指定quantum。
-c
指定每次调用callback之间读入的行数。
如果指定-C时没有指定-c,则默认的quantum是5000。当调用callback时,把下一个要被赋值的数组元素和相应的读入行作为附加参数。该行被读取后,调用callback,但在给数组元素赋值之前。
如果没有指定一个明确的origin,mapfile将在赋值前清除array。
mapfile成功返回,除非有一个无效的选项,或者无效的选项参数,无效的array,或者不能被赋值,或者array不是索引数组。
4.2 Bash的内建命令 续
printf
printf [-v var] format [arguments]
按照format的控制,把格式化的arguments输出到标准输出。 -v选项使输出内容赋值给变量var,而不是打印到标准输出。
format是一个字符串,其中包含三种类型的对象:普通字符,它们被简单地复制到标准输出;字符转义序列,它们被转换并复制到标准输出;格式规范,每一个格式规范控制打印后续的argument。除了标准的printf(1)格式,printf解释下列扩展:
%b
使printf扩展对应argument中的反斜杠转义序列,(除了‘\c’终止输出,在'\'','\"'和‘\;’中的反斜杠不会被删除,以'\0'开头的8进制序列可包含4位数字。)
%q
使printf输出对应argument的格式,能够作为shell的输入。
%(datefmt)T
使printf输出的日期时间字符串,是使用strftime(3)命令和参数datefmt的结果。对应的argument是一个整数,代表从公元纪元以来的秒数。有两个特殊的参数值:-1表示当前时间,-2代表shell被调用的时间。
没有对应格式说明符的argument被视为C语言常量,除非允许开头有加号或减号,如果开头字符是一个单引号或双引号,该argument的值是后续字符的ASCII值。
必要时,重复使用format以处理所有的argument。如果该format需要的argument数量多于给定的argument时,额外的格式规范的行为是如同处理一个零值或空字符串(如适用)。
成功返回0,非零表示失败。
read
read [-ers] [-a aname] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name …]
从标准输入中读取一行,或从-u选项的参数文件描述符fd读入一行,第一个单词被赋值到第一个name,第二个单词被赋值到第二个name,以此类推。多余的单词和中间的分隔符都赋值给最后一个name。如果从输入流读取的单词比name的数量少,则其余的name是空值。IFS变量值中的字符用于分割单词。反斜杠字符“\”可用于去除下一个字符的特殊含义和续行。如果没有提供name,读入的行被赋值到变量REPLY。返回码是零,除非遇到文件结束EOF,read超时(在这种情况下,返回的代码大于128),或参数-u后面的文件描述符无效。
选项的含义如下:
-a aname
把单词赋值给数组变量aname,索引从0开始。aname中的所有元素在赋值之前被删除。其他name参数被忽略。
-d delim
delim的第一个字符,取代换行符,被用来终止输入行。
-e
使用Readline(见命令行编辑)获取行。Readline使用当前(或者默认情况下,如果行编辑没有提前激活)编辑设置。
-i text
如果使用Readline读入行,在编辑开始前,先把text放到编辑缓冲区。
-n nchars
read在读取nchars个字符后返回,而不用等到一整行完全输入。但是如果遇到分隔符时字符数小于nchars,则优先处理分隔符。
-N nchars
read在读取恰巧nchars个字符后返回,而不用等到一整行完全输入,除非遇到EOF或者read超时。遇到分隔符,也不做特殊处理,直到字符数达到nchars,才返回。
-p prompt
在读取输入前,显示prompt,且不带后续换行符。仅当输入来自终端时,才显示prompt。
-r
如果给定这个选项,反斜杠不作为转义符处理。反斜杠被当做行的内容。特别是,反斜杠-换行符组合不再当做续行。
-s
安静模式。如果输入来自于终端,字符不回显。
-t timeout
如果一行的输入没有在timeout秒内读入,则read超时或者返回失败。timeout可以是一个带小数的十进制数字。仅在read从终端、管道、或者其他特殊文件读取输入时,这个选项才有效。从普通文件读入时,该选项无效。如果timeout是0,则如果特殊文件描述符的输入可用时,read返回成功,其他情况则失败。如果发生超时,则退出状态大于128。
-u fd
从文件描述符fd读取输入。
readarray
readarray [-n count] [-O origin] [-s count] [-t] [-u fd] [
-C callback] [-c quantum] [array]
从标准输入读取行到索引变量array,或者,如果有-u选项则从文件描述符fd读取。
source
source filename
和.同义。(见Bourne Shell内建命令)
type
type [-afptP] [name …]
对于每一个name,指出如果该name当做命令名使用时,如何被系统解释。
如果使用-t选项,当name是别名、shell函数、shell内建命令、磁盘文件、或者shell保留字时,type打印这些单词中的一个——‘alias’,‘function’,‘builtin’,‘file’ ‘keyword’。如果找不到name,则不打印,且type返回一个失败状态。
如果使用-p选项,type或者返回被执行的磁盘文件名,或者,当-t不能返回‘file’时,返回结果为空。
-P选项,则强制在路径中搜索name,即使-t不能返回‘file’。
如果一个命令被哈希了,-p和-P打印哈希值,该文件不一定首次出现在$PATH中。
如果使用-a选项,type返回所有包含名为file的可执行文件的位置。当且仅当不同时使用-p选项时,结果中包括别名和函数。
如果使用-f选项,type不会试图查找shell函数,就像command内建命令。
如果所有的name都被找到,则返回状态是0,任何一个找不到都返回非零值。
typeset
typeset [-afFrxi] [-p] [name[=value] …]
typeset命令是为了兼容Korn shell而提供的,然而,因为declare内建命令的出现,它已经被废弃了。
ulimit
ulimit [-abcdefilmnpqrstuvxHST] [limit]
ulimit用于对于由shell启动的线程的可用资源的控制,仅在允许这种控制的系统上可用。命令选项含义如下:
-S
修改和报告某个资源的软限制。
-H
修改和报告某个资源的硬限制。
-a
报告所有当前的限制。
-b
socket的最大缓冲尺寸。
-c
可以创建的核心文件的最大尺寸。
-d
一个线程的数据段的最大尺寸。
-e
最大规划优先级(“nice”)。
-f
shell和其子shell写文件的最大尺寸。
-i
待处理信号的最大数目。
-l
可以被锁定的内存的最大尺寸。
-m
最大驻留集合的尺寸(很多系统不遵循此限制)。
-n
打开文件描述符的最大数目(很多系统不允许设置这个值)。
-p
管道缓冲区大小。
-q
POSIX消息队列的最大字节数。
-r
最大实时规划优先级。
-s
最大堆栈尺寸。
-t
最大cpu时间,单位是秒。
-u
单一用户可用的最大进程数目。
-v
shell可用的最大虚拟内存,在某些系统上,也包括该shell的子shell。
-x
文件锁的最大个数。
-T
线程的最大个数。
如果给定limit,则它是指定资源的新值;特殊limit值hard,soft和unlimited表示当前的硬限制,当前软限制,和无限制。硬限制的值一旦被设置,就不能被非root用户增加;软限制可以增加到硬限制的值。否则,指定资源的软限制的当前值被打印出来,除非提供-H选项。当设置新的限制时,如果既没有-H,也没有-S选项,则同时设置硬限制和软限制。如果没有给出选项,那么-f是缺省选项。值是以1024字节为单位增加,除了-t选项,该选项的单位是秒,而-p是以512字节块为单位,还有-n和-u,是不能改变的。
返回状态是0,除非有无效选项或者参数,或者设定限制时发生错误。
unalias
unalias [-a] [name … ]
从别名列表中删除每一个name。如果有-a选项,所有别名被删除。别名请参看别名中的描述。
4.3 修改shell的行为
•内建命令set:改变shell的属性和位置参数的值。
•内建命令shopt:修改shell的可选的行为。
4.3.1 内建命令set
这个命令太复杂了,因此单独用一节来描述它。set允许你改变shell选项的值和设置位置参数,或者显示shell变量的名字和值。
set
set [--abefhkmnptuvxBCEHPT] [-o option-name] [argument …]
set [+abefhkmnptuvxBCEHPT] [+o option-name] [argument …]
如果不带选项或参数,则set显示所有shell变量的名字和值,以及所有函数,根据区域设置进行排序,显示的格式为可以重用为输入(设置或者重新设置当前的各个变量)的格式。只读变量不能被重新设置。在POSIX模式,仅仅列出shell变量。
如果带选项,则设置或者取消shell变量。选项的含义如下:
-a
-b
-e
如果管道(见管道)返回一个非零的状态时立即退出,该管道可以由以下内容组成:一个单一的简单的命令(见简单指令),或在括号中的一个子shell命令(见命令组合),或在大括号包围的命令列表中的某个被执行的命令(见命令分组)。下述情况下,shell不会退出:如果失败的命令是命令列表的一部分,并且后面紧随while或者until关键字,在if语句中的测试的一部分,在 && 或 | | 列表中执行的命令(除了在最终的 && 或 | | 之后的命令),在管道中的最后一个任何命令,或如果该命令的返回状态被 ! 反转。 如果设置了ERR陷阱,该陷阱在shell退出之前执行。
此选项适用于shell环境中,每个独自的子shell环境中(见命令执行环境),并可能导致子shell在执行该子shell中所有命令前退出。
-f
-h
查找执行命令时,定位和记住(哈希)命令。这个选项默认打开。
-k
把某条命令的所有赋值语句形式的参数放到环境中,而不是那些在命令前的参数。
-m
打开作业控制(见作业控制)
-n
读取命令,但是不执行,可以用来检查脚本的语法错误。交互shell忽略此选项。
-o option-name
设置option-name对应的选项:
allexport
同-a
braceexpand
同-B
emacs
使用emacs风格的行编辑界面(见命令行编辑)。也影响读-e的编辑界面。
errexit
同-e
errtrace
同-E
functrace
同-T
hashall
同-h
histexpand
同-H
history
启用命令历史,见Bash历史工具。这个选项在交互shell中缺省启用。
ignoreeof
交互式shell读到EOF时,不退出。
keyword
同-k
monitor
同-m
noclobber
同-C
noexec
同-n
noglob
同-f
nolog
当前忽略。
notify
同-b
nounset
同-u
onecmd
同-t
physical
同-P
pipefail
如果设置此选项,则管道的返回值是最后(最右边)的命令的非零返回值,或者,如果所有在管道中的命令都成功退出时,是0。此选项默认关闭。
posix
修改那些与POSIX标准不同的Bash默认行为,使之符合POSIX标准(见Bash POSIX模式)。此选项使Bash的行为成为POSIX标准的严格超集。
privileged
同-p
verbose
同-v
vi
使用vi风格的行编辑界面。此选项也影响read -e的编辑界面。
xtrace
同-x
-p
打开特权模式。在这种模式下,不处理$BASH_ENV和$ENV文件,shell函数不能从环境,以及SHELLOPTS,BASHOPTS,CDPATH和GLOBIGNORE变量中继承,如果它们出现在环境中,都将被忽略。如果shell是由不等于真实用户(组)ID的有效用户(组)ID启动的,则不提供-p选项,这些动作被执行,并且有效用户ID被设置为实际用户ID。如果使用-p选项启动,有效用户ID不被复位。关闭此选项会导致有效用户ID和组ID被设置为真实用户ID和组ID。
-t
读取并执行一条命令后退出。
-u
在执行参数扩展时,把未设置变量和参数,除了特殊参数‘@’ 或者‘*’之外,视为错误。错误信息写到标准错误,并且退出非交互shell。
-v
读取shell输入时,打印shell输入行。
-x
打印简单命令、for命令、case命令、select命令,和扩展后执行前的算术for命令和该命令的参数或者相关的单词列表的跟踪信息。PS4变量的值被扩展,且在命令及其扩展参数前打印该扩展结果。
-B
shell执行大括号扩展(见大括号扩展)。此选项默认打开。
-C
-E
如果设置此选项,shell函数,命令替换,和在子shell环境中执行的命令继承所有ERR陷阱。一般来说,ERR陷阱在上述情形下不被继承。
-H
启用‘!’风格的历史替换(见历史交互)。对于交互shell,此选项默认打开。
-P
如果设置的话,执行如cd改变当前目录等命令时,不遵循符号链接。而使用物理目录。默认情况下,执行改变当前目录的命令时,bash遵循目录的逻辑链。
例如,如果/usr/sys 是 /usr/local/sys的符号链接:
$ cd /usr/sys; echo $PWD
/usr/sys
$ cd ..; pwd
/usr
如果启用-P的话,结果是:
$ cd /usr/sys; echo $PWD
/usr/local/sys
$ cd ..; pwd
/usr/local
-T
如果设置此选项,则DEBUG和RETURN陷阱将被shell函数,命令替换,以及在子shell环境中执行的命令继承。在这种情况下,DEBUG和RETURN陷阱通常不会继承。
--
如果此选项后面没有参数,则位置参数被取消。否则,即使arguments中有以‘-’开头的项目,也被设置为位置参数。
-
选项结束的信号,把余下的arguments都赋值给位置参数。关闭-x和-v。如果没有arguments,则位置参数保持不变。
使用'+',而不是' - ',使这些选项被关闭。这些选项也可用在调用shell时。当前的选项设置可以使用$-获得 。
剩余的N个argument是位置参数,并以$1,$2,...$N的顺序被赋值。特殊参数#被设置为N。
返回状态始终是零,除非提供了无效的选项。
4.3.2 内建命令Shopt
此内建命令改变额外的shell的可选行为。
shopt
shopt [-pqsu] [-o] [optname …]
切换那些用来控制shell的各种可选的行为的变量的值。不带选项,或使用-p选项,则显示所有可设置的选项的列表,同时表明该选项是否被设置。 -p选项以可重用为输入的形式来显示输出。其他选项有以下含义:
-s
启用每个optname。(set)
-u
关闭每个optname。(unset)
-q
抑制正常输出;返回状态表示optname是否启用。当有-q选项,且如果有多个optname参数时,若所有optname被启用,则返回值是零;否则返回非零值。
-o
限制optname的值,仅可以使用内建命令set的-o选项所定义的值。(见内建命令set)
如果使用-s或者-u,且没有optname参数,则显示结果的范围仅限于那些启用或关闭的相应选项。
除非特别说明,shopt选项默认是关闭的。
列出选项时,如果所有optname都是启用状态,则返回值是0,否则是非零值。在设置或取消选项时,返回状态是零,除非某个optname不是有效的shell选项。
shopt的选项列表如下:
autocd
如果设置的话,某个目录的名字被当做cd命令的参数执行。此选项仅在交互式shell中使用。
cdable_vars
如果设置的话,内建命令cd的不是目录名的参数,被当做变量名,该变量的值就是要被切换到的目录。
cdspell
如果设置,cd命令的目录部分的小的拼写错误将得到更正。这些错误包括颠倒的字符,缺少的字符,和多余的一个字符。如果能找到校正后的结果,则校正后的路径被打印出来,并执行命令。此选项仅用于交互式shell。
checkhash
如果设置,Bash在执行该命令前,在哈希表中检查是否存在该命令。如果在哈希表中不存在,则执行一个正常的路径搜索。
checkjobs
如果设置,Bash在退出交互shell前,列出所有停止的和正在运行的作业的状态。如果有任何作业正在运行,这将导致退出的时间推迟到第二次没有干预命令的退出(参见作业控制)。如果有任何作业被停止,shell总是推迟退出。
checkwinsize
如果设置,Bash在每个命令后,检查窗口大小,如果必要的话,更新LINES和COLUMNS的值。
cmdhist
如果设置,Bash在同一个历史实体里面保存一个多行命令的所有行的内容。这样便于重新编辑多行命令。
compat31
如果设置,Bash改变它的行为以符合3.1版本,条件命令操作符‘=~’被引号包括的参数的方式。
compat32
如果设置,Bash改变它的行为以符合3.2版本,当使用‘[[’条件命令的'<' 和 '>'操作符时,区域特定字符串比较的方式。bash-4.0之前版本的Bash使用ASCII定序和strcmp(3);bash-4.1及之后的版本使用当前区域设置的定序和strcoll(3)。
compat40
如果设置,Bash改变它的行为以符合4.0版本,当使用‘[[’条件命令的'<' 和 '>'操作符时,区域特定字符串比较的方式(见上一个项目),以及对中断一个命令列表的影响。
compat41
如果设置,Bash在POSIX模式时,将位于双引号参数扩展中的单引号当做特殊字符。单引号必须匹配(偶数个),单引号之间的字符被认为是引号包围的。这是POSIX模式4.1版本的行为。其他默认的Bash的行为仍然和以前的版本一样。
dirspell
dotglob
execfail
如果设置,非交互shell在不能执行内建命令exec的参数所指定的文件时,将不会退出。如果exec失败,交互式shell不退出。
expand_aliases
如果设置,所有别名以下述“别名”节的描述扩展。交互式shell中,此选项默认启用。
extdebug
如果设置,启用调试器可用的行为:
2.如果使用DEBUG陷阱运行的命令返回一个非零值,下一个命令被跳过且不执行。
3.如果使用DEBUG陷阱运行的命令返回一个值2,并且shell在子过程中(是使用.或者source命令执行)执行,则 模拟一个对return的调用。
4.BASH_ARGC 和 BASH_ARGV 按照他们的描述更新。(参见Bash变量)
5.启用函数跟踪:命令替换,shell函数,和使用( command )调用的子shell继承DEBUG和RETURN陷阱。
extglob
如果设置,启用上述的扩展模式匹配功能。(见模式匹配)
extquote
如果设置,在双引号中的 ${parameter} 扩展中的$'string' 和 $"string" 被执行引号扩展。此选项默认启用。
failglob
force_fignore
如果设置,当执行单词补全时,由FIGNORE指定的那些后缀的shell变量将忽略单词,即使被忽略的单词是唯一的补全候补。关于FIGNORE,请查看bash变量章节。该选项默认启用。
globstar
如果设置,在文件名扩展中使用的模式“**”将匹配所有文件和0个或多个目录和子目录。如果模式以‘/’结尾,则仅仅匹配目录和子目录。
gnu_errfmt
histappend
histreedit
如果设置,将使用Readline,用户将有机会重新编辑失败的命令历史替换。
histverify
如果设置,将使用Readline,命令历史替换的结果不会立即传递给shell解释器。而是被加载到Readline缓冲区,以允许将来修改。
hostcomplete
如果设置,将使用Readline,当单词含有‘@’时, Bash会尝试执行主机名完成。(请参看“命令完成”)。该选项默认启用。
huponexit
如果设置,当交互shell退出时,Bash将发送SIGHUP到所有作业。(请参看“信号”)
interactive_comments
在交互shell中,以‘#’开头的单词将导致该单词及该行该单词之后的所有字符都被忽略。该选项默认开启。
lastpipe
如果设置,并且作业控制未激活,则运行管道的最后一个命令的shell不在当前shell环境的后台执行。
lithist
如果设置,并且cmdhist选项被设置了,则多行命令被保存到历史中时,包含换行符,而不是使用分号代替。
login_shell
mailwarn
如果设置,并且Bash用来检测邮件的文件,在上次检测之后再次被存取时,则显示“The mail in mail file has been read”。
no_empty_cmd_completion
如果设置,并且使用了Readline,Bash在空行上不再试图从PATH中搜索可用的命令完成。
nocaseglob
nocasematch
如果设置,执行case或者 [[ 条件命令时,Bash以大小写不敏感方式匹配模式。
nullglob
progcomp
promptvars
restricted_shell
如果shell以限制模式被启动,则设置此选项。(见“限制shell”)。该值不可更改。启动文件被执行时,不重置此选项,以允许启动文件能够发现shell是否是限制的。
shift_verbose
如果设置,当shift计数器超过位置参数个数时,shift内建命令打印一条错误信息。
sourcepath
如果设置,source内建命令使用PATH的值,去寻找作为参数的文件名所在的目录。此选项默认激活。
xpg_echo
如果设置,echo内建命令默认扩展反斜杠转义序列。
如果所有optnames都激活了,则列出选项的命令返回状态为0,否则为非零值。在设置或者取消选项的设置时返回状态是0,除非optname不是有效的shell选项。
4.4 特殊内建命令
1. 在命令查找过程中,特殊内建命令在shell函数之前被搜索。
2. 如果一个特殊内建命令返回错误状态,则非交互shell会退出。
3. 命令完成后,该命令前的赋值语句在shell环境中仍然保持效果。
当Bash不是在POSIX模式中执行时,这些特殊内建命令和其他Bash内建命令没有区别。关于Bash POSIX模式,请参见 Bash POSIX 模式章节。
以下为POSIX特殊内建命令:
break : . continue eval exec exit export readonly return set
shift trap unset
5 Shell变量
Bourne Shell变量:和Bourne Shell中使用方式一样的变量。
Bash变量:存在于Bash中的变量的列表。
本章解说Bash使用的shell变量。Bash自动给一些变量赋默认值。
5.1 Bourne Shell变量
Bash使用这些变量时,和Bourne Shell的使用方式一样。在某些情况下,Bash给变量赋默认值。
CDPATH
一个分号分隔的目录列表,给cd命令用来当做查找路径。
HOME
当前用户的家目录,cd命令的默认结果。这个变量的值也被波浪线扩展使用。参见波浪线扩展。
IFS
分隔字段的字符列表。shell分隔表达式时使用。
如果此参数被设置为一个文件名或者目录名,并且MAILPATH变量未设置,Bash通知用户在指定的文件或邮件目录中有邮件到达。
MAILPATH
一个分号分隔的文件名列表,shell定时在该列表中检测新邮件。当新邮件到达邮件文件时,每个列表元素可以通过在文件名和消息之间用‘?’分隔的方式显示消息。在消息文本中,$_被扩展为当前的邮件文件。
OPTARG
上一个使用内建命令getopts处理的选项参数的值。
OPTIND
上一个使用内建命令getopts处理的选项参数的索引。
PATH
一个分号分隔的目录列表,shell用来搜索命令。PATH中的一个长度为0的目录名(null)指代当前目录。一个null目录名以两个相连的分号,或者以一个初始或者结尾的分号来表示。
PS1
PS2
第二个提示字符串。默认值是 ‘> ’。
5.2 Bash变量
下面这些变量在Bash中设置或者使用,其他shell一般不会处理这些变量。
Bash使用的一些变量也在其他章节介绍:例如,控制作业的工具使用的变量,请参看‘作业控制变量’。
BASH
执行当前Bash实例的全路径名。
BASHOPTS
冒号分隔的已启用的shell选项列表。列表中的每个单词都是内建命令shopt -s 的有效参数(参看‘shopt内建命令’)。BASHOPTS中出现的选项,都是执行shopt命令时,显示状态为‘on’的那些。当Bash启动时,如果这个变量在环境中,在读入启动文件前,列表中的每个shell选项都会被启用。该变量是只读的。
BASHPID
扩展为当前Bash进程的进程ID。在某些情况下和$$的结果不同,例如不需要Bash重新初始化的子shell。
BASH_ALIASES
一个关联数组变量,其成员对应内部别名列表,该列表由内建命令alias维护。(参看‘Bourne Shell内建命令’)。增加到这个数组的元素会出现在别名列表中,删除数组元素,则对应地从别名列表中移除了相应的别名。
BASH_ARGC
一个数组变量,其值为当前bash执行调用堆栈中的每个帧中的参数个数。当前子程序(使用 . 或者source执行的shell函数或者脚本)的参数个数位于堆栈的顶部。当执行一个子程序时,传入的参数个数被压入BASH_ARGC顶部。shell仅仅在扩展调试模式时才设置这个变量。(请参看'shopt内建'章节,对extdebug选项的描述)
BASH_ARGV
是一个数组变量,包含当前bash执行调用堆栈中的所有参数。最后一个子程序调用的最后一个参数在堆栈的顶部;初始呼叫的第一个参数在底部。一个子程序被执行时,它的参数被压入BASH_ARGV。shell仅在扩展调试模式时设置BASH_ARGV,(见shopt内建命令关 于extdebug选项的描述)。
BASH_CMDS
是一个数组变量,包含的成员对应于由hash内建命令维护的那些命令的内部hash表(见bourne shell内建命令)。增加到这个数组的元素会出现在hash表中,在这个数组中删除的元素也从hash表中被删除。
BASH_COMMAND
当前正在执行的或者正要执行的命令,除非shell因为陷阱正在执行一条命令,在这种情况下是发生陷阱时正在执行的命令。
BASH_ENV
如果这个变量被设置,当Bash被调用去执行一个shell脚本时,它的值被扩展,并在脚本执行之前作为启动文件读取,见Bash启动文件。
BASH_EXECUTION_STRING
-c调用选项的命令参数。
BASH_LINENO
是一个数组变量,它的成员是源文件中的行号,每个行号对应被调用的FUNCNAME的成员。${BASH_LINENO[$i]} 是源文件 (${BASH_SOURCE[$i+1]})中,${FUNCNAME[$i]}被调用时的行号,(或者,如果在另一个shell函数中引用,是${BASH_LINENO[$i-1]})。使用LINENO获取当前的行号。
BASH_REMATCH
是一个数组变量,它的成员是使用 ‘=~’ 二进制操作符作用于 [[ 条件命令(见条件构造)的结果。索引0的元素是匹配整个正则表达式的那部分字符串。索引n的元素是匹配第n个括号子表达式的那部分字符串。此变量是只读的。
BASH_SOURCE
是一个数组变量,它的成员是源文件名,其中定义的的shell函数名对应于FUNCNAME数组变量。shell函数${FUNCNAME[$i]}在${BASH_SOURCE[$i]}文件中定义,并且从${BASH_SOURCE[$i+1]}调用。
BASH_SUBSHELL
每产生一个子shell或者子shell环境时,增加1。初始值是0。
BASH_VERSINFO
是一个只读数组变量(见数组),它的成员保存着当前Bash实例的版本信息。数组成员如下:
BASH_VERSINFO[0]
主要的版本号(发行版)。
BASH_VERSINFO[1]
次要的版本号(发行版)。
BASH_VERSINFO[2]
补丁号。
BASH_VERSINFO[3]
构造版本。
BASH_VERSINFO[4]
发行版状态(例如,beta1)。
BASH_VERSINFO[5]
MACHTYPE的值。
BASH_VERSION
当前Bash实例的版本号。
BASH_XTRACEFD
如果设置为对应于一个有效的文件描述符的一个整数,当‘set -x’ 启用时,Bash将把生成的跟踪输出到那个文件描述符。这样就可以把跟踪输出内容中的诊断和错误信息分开。当BASH_XTRACEFD被取消时,或者设置到一个新值时,该文件描述符被关闭。取消BASH_XTRACEFD或着设置为空串,会把跟踪输出发送到标准错误。注意,设置BASH_XTRACEFD到2(标准错误文件描述符),然后取消设置,会造成标准输出被关闭。
COLUMNS
当打印选择列表时,由select命令用来决定终端宽度。当收到SIGWINCH信号时,自动设置。
COMP_CWORD
COMP_LINE是一个索引,包含当前光标位置的字${COMP_WORDS}。这个变量仅在由可编程完成工具调用shell函数时可用。(见可编程完成)
当前命令行。这个变量仅在shell函数和外部命令是由可编程完成工具调用的情况下可用。(见可编程完成)COMP_POINT
当前命令开始时的当前光标位置。如果当前光标位置在当前命令的尾部,变量值等于${#COMP_LINE}。这个变量仅在shell函数和外部命令是由可编程完成工具调用的情况下可用。(见可编程完成)COMP_TYPE
设置为一个整数值,对应于试图完成的类型(该完成将调用一个完成函数):对于一般完成是TAB,对于后续tabs之后的列表完成是‘?’,对于部分字完成上的列表选择是‘!’,如果字未被修改则是列表完成,或者,对于菜单完成是 ‘%’。这个变量仅在shell函数和外部命令是由可编程完成工具调用的情况下可用。(见可编程完成)COMP_KEY
用来调用当前完成函数的键,(或者键序列的最后的键)。COMP_WORDBREAKS
一组字符,执行字完成时,被Readline库当作字分割符。如果COMP_WORDBREAKS取消设置,则它失去它的特殊属性,即使它随后被重置了。COMP_WORDS
是一个数组变量,由当前命令行中的独立字组成。该行按Readline分割方式,使用COMP_WORDBREAKS分割。这个变量仅在shell函数和外部命令是由可编程完成工具调用的情况下可用。(见可编程完成)COMPREPLY
是一个数组变量,Bash从中读取由shell函数和可编程完成工具调用产生的可能的完成。(见可编程完成)COPROC
是一个数组变量,用来保存用于输出和输入的未命名coprocess。(见协同进程)DIRSTACK
是一个数组变量,包含目录堆栈的当前内容。堆栈中出现的目录,按照dirs内建命令的显示结果顺序显示。给这个变量的成员赋值,可以用来修改堆栈中的目录,但是必须使用pushd和popd内建命令来增加和删除目录。对这个变量的赋值,不会改变当前的目录。如果DIRSTACK取消设置,则它失去它的特殊属性,即使它随后被重置了。EMACS
如果Bash在shell启动时,在环境中发现这个变量的值是 ‘t’,则会认为shell在Emacs shell缓冲区中运行,而禁止行编辑。ENV
类似于BASH_ENV,在shell以POSIX模式调用时使用。(见Bash POSIX模式)EUID
当前用户的数字形式的有效用户ID。这个变量是只读的。FCEDIT
内建命令fc带-e选项时的默认编辑器。FIGNORE
冒号分隔的后缀列表,该列表的内容在执行文件名完成时忽略。一个文件名的后缀匹配FIGNORE中的一个元素时,则该文件名从匹配文件名列表中排除。示例值:‘.o:~’。FUNCNAME
是一个数组变量,包含当前在执行调用堆栈中的所有shell函数。索引0的元素是任何当前正在执行的shell函数的名字。最底部(具有最大索引)的元素是 "main"。这个变量仅当shell函数执行时才存在。向FUNCNAME赋值没有效果,并且返回一个错误状态。如果FUNCNAME被取消设置,它失去它的特殊属性,即使随后被重新设定。
这个变量可以和BASH_LINENO与 BASH_SOURCE 同时使用。FUNCNAME的每个元素对应于BASH_LINENO与 BASH_SOURCE 的内容,以描述调用堆栈。例如,${FUNCNAME[$i]} 在文件 ${BASH_SOURCE[$i+1]} 中的行号 ${BASH_LINENO[$i]} 处被调用。内建命令caller使用这些信息,显示当前调用堆栈。FUNCNEST
如果设置一个大于0的数字,则定义了最大的函数嵌套层次。超过该值的函数调用将导致当前命令放弃执行。GLOBIGNORE
是一个冒号分隔的模式列表,定义了文件名扩展时忽略的文件名集合。如果一个文件名即匹配文件名扩展的模式,同时也匹配GLOBIGNORE中的一个模式,则它将从匹配列表中移除。GROUPS
是一个数组变量,包含当前用户所属组的列表。向GROUOS赋值没有效果,并且返回一个错误状态。如果GROUPS被取消设置,它失去它的特殊属性,即使随后被重新设定。histchars
最多3个字符,以控制历史扩展,快速替换,和标记化(见历史交互)。第一个字符是 历史扩展 字符,标志着历史扩展的开始,一般是 ‘!’。第二个字符标志着 快速替换——当它是一行中的第一个字符时,一般是‘^’。可选的第三个字符,标志着该行剩下的内容是注释——当它是一个字的第一个字符时,一般是‘#’。历史注释字符,使得历史替换跳过那一行上的剩余字。它不是必要的,因为shell解释器会把剩余的部分按注释处理。
HISTCMD
当前命令的命令历史的序号,或者在命令历史中的索引。如果HISTCMD被取消设置,即使重新设置,也失去其特殊属性。
HISTCONTROL
冒号分割的一组值的列表,用来控制命令在历史列表中的存储方式。如果列表中包含‘ignorespace’,则以空格开头的命令行不会被存储到命令历史中。‘ignooredups’导致和已经存储在历史中的命令匹配的命令行不会被存储。‘ignoreboth’是‘ignoredups’和‘ignorespace’的简写。‘erasedups’导致在存储命令行前,删除历史中那些匹配该命令行的命令。所有不在上述列表中的值都被忽略。如果HISTCONTROL被取消设置,或者没有包含有效值,所有shell解释器读入的命令行都被存储到历史列表中,除了HISTIGNORE中的值以外。多行命令的第二行及以后的行都不做检查,忽略HISTCONTROL的设置,而加入到命令历史中。
HISTFILE
存储命令历史的文件名。缺省值是 ~/.bash_history。
HISTFILESIZE
历史文件中包含的命令行数的最大值。当此变量被赋值时,如果有必要,删除历史文件中最旧的内容,以使总行数不超过该值。另外,当交互式shell退出时,也删除历史文件中的内容,以不超过该值。缺省值是500。
HISTIGNORE
冒号分割的模式列表,以确定哪个命令行应当存储到命令历史中。每一个模式都从行开头开始,并且必须匹配整个命令行(不追加隐含的‘*’)。每个模式检测,在完成HISTCONTROL测试之后进行。除了一般的shell模式匹配字符,‘&’匹配前一个历史命令行。‘&’可以使用反斜杠转义;在匹配之前,去掉反斜杠。多行命令的第二行及以后的行都不做检查,忽略HISTIGNORE的设置,而加入到命令历史中。
HISTIGNORE归入HISTCONTROL的函数。‘&’模式等同于‘ignoredups’,而‘[ ]*’等同于‘ignorespace’。组合这两个模式,并用冒号分割,就是‘ignoreboth’。
HISTSIZE
历史列表能存储的最大命令个数。缺省值是500。
HISTTIMEFORMAT
如果该变量被设置,且非空,则该值作为strftime的格式化字符串,用于在调用history内建命令时,在每个历史内容上,相应地打印时间戳。如果该变量被设置,则时间戳被写入到历史文件中,以使之可以在shell会话之间保持。使用历史注释字符区分时间戳和命令行。
HOSTFILE
包含一个文件的名字——此文件和/etc/hosts具有相同的格式,在shell完成一个hostname时,从此文件中读取信息。在shell运行时,hostname完成列表可能被改变;值被改变之后,在下一次试图进行hostname完成时,Bash把新文件的内容加入到现存的列表中。如果HOSTFILE被设置了,但是没有给定值,或者不是一个可读文件,Bash则试图读取/etc/hosts以获取hostname完成列表。当HOSTFILE被取消设置时,hostname列表被清除。
HOSTNAME
当前主机的名字。
HOSTTYPE
一个字符串,描述了Bash正在运行的机器。
IGNOREEOF
控制shell在遇到输入的独立的EOF字符时的动作。如果设置此变量,变量的值代表了,在shell退出前,从一个输入行中的开始位置,可以读入的连续的EOF字符的数量。如果变量存在,但是值不是数字类型的,或者没有值,则默认为10。如果此变量不存在,则EOF标志着对shell的输入结束。这个变量仅仅在交互式shell有效。
INPUTRC
Readline初始化文件的名字,覆盖默认的~/.inputrc。
LANG
LC_ALL
此变量指定的locale类别,覆盖LANG和所有其他LC_开头的变量的值。
LC_COLLATE
此变量决定文件名扩展结果的排序规则,和决定范围表达式的行为,等价类,和文件名扩展的排序序列和模式匹配(见 文件名扩展)。
LC_CTYPE
LC_MESSAGES
此变量决定用于翻译以'$'开头的双引号字符串时的locale。(见 locale翻译)
LC_NUMERIC
此变量决定数字格式的locale类别。
LINENO
当前在执行的脚本或者shell函数的行号。
LINES
命令select用来确定打印选择列表的列宽。收到SIGWINCH后,自动设置。
MACHTYPE
是一个字符串,描述了正在运行Bash的系统的类型,描述的格式符合GNU cpu-company-system 标准。
MAILCHECK
MAPFILE
是一个数组变量,当运行内建命令mapfile时未指定变量名时,自动创建此变量,并在其中存储mapfile读取的文本。
OLDPWD
由内建命令cd设定的前一个工作目录。
OPTERR
OSTYPE
PIPESTATUS
是一个数组变量(参见 数组 章节),包含一个退出状态值的列表,状态值来自最近执行的前端管道(可能仅含有一个简单命令)进程。
POSIXLY_CORRECT
如果当Bash启动时,环境中有这个变量,则shell在读入启动文件前,进入POSIX模式(见 Bash POSIX模式 章节),就如同带有 --posix 选项。如果在shell运行过程中设定该变量,则bash进入POSIX模式,如同执行了这个命令:
set -o posix
PPID
shell的父进程的进程ID。只读。
PROMPT_COMMAND
如果设置了,此变量的值被当成一个命令,在每次打印提示符($PS1)之前执行该命令。
PROMPT_DIRTRIM
PS3
PS4
当使用 -x 选项时,此变量的值用于在回显命令行之前打印提示。在有必要时,PS4的第一个字符被多次使用,以表明多层引用。默认值是'+'。
PWD
由内建命令cd设定的当前工作目录。
RANDOM
READLINE_LINE
Readline的行缓冲区的内容,结合命令 ‘bind -x’使用。(见 Bash内建命令)
READLINE_POINT
Readline的行缓冲区的插入点的位置,结合命令 ‘bind -x’使用。(见 Bash内建命令)
REPLY
内建命令read的默认变量。
SECONDS
这个变量扩展为shell启动后经过的秒数。赋值给这个变量会重置计数值到所赋的值,而扩展的值变成了所赋值加上从赋值时开始经历的秒数。
SHELL
SHELLOPTS
冒号分隔的启用的shell选项列表。列表中的每个字都是内建命令 set 的 -o 选项的有效参数(见 内建命令Set)。SHELLOPTS中出现的选项,是那些命令 ‘set -o’ 报告为 on 的选项。如果Bash启动时,环境中有此变量,则在读取启动文件前,列表里的每个shell选项都被启用。只读。
每次一个新的Bash实例启动时加1。代表了Bash的嵌套深度。
TIMEFORMAT
此变量的值用于格式化字符串,以确定如何显示时间信息——对于带有time保留字前缀的管道命令。‘%’字符引入一个逃逸序列,以扩展为时间值或者其他信息。逃逸序列和它们的含义如下,方括号表示可选部分。
%%
字符‘%’。
%[p][l]R
已经消耗的时间,以秒为单位。
%[p][l]U
%[p][l]S
系统模式的cpu的秒数。
%P
cpu百分比,等于(%U + %S) / %R。
如果此变量未设置,则Bash视作如下的值:
$'\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS'
TMOUT
如果设定值大于0,TMOUT被当作内建命令read的默认超时时间(见 Bash内建命令)。当输入来自终端时,如果超过TMOUT的秒数没有获得输入,则select 命令(见 条件结构)终止。
TMPDIR
如果设置,则Bash使用此值作为给shell创建临时文件的目录名。
UID
目录堆栈内建命令: 操作目录堆栈的Bash内建命令。
目录堆栈是最近访问的目录的列表。内建命令 pushd 在改变当前目录时,向堆栈增加目录,而内建命令 popd 从堆栈移除指定的目录,并改变当前目录到被移除的目录。内建命令 dirs 显示目录堆栈的内容。
dirs
dirs [+N | -N] [-clpv]
删除所有元素,以清除目录堆栈。
产生长列表;默认的列表格式中,使用波浪线代表home目录。
使dirs在每一行上显示一个目录堆栈中的元素。
popd [+N | -N] [-n]
从目录堆栈中移除顶端的元素,并 cd 到新的顶部目录。当没有参数时, popd 从堆栈顶部移除目录,并且执行 cd 命令到新的顶部目录。对于用dirs列出的内容,元素从0开始计数,例如: popd等价于 popd +0。
移除第 N个目录(当使用不带选项的 dirs 命令时,显示的命令列表,从左开始数),从0开始。
移除第 N 个目录(当使用不带选项的 dirs 命令时,显示的命令列表,从右开始数),从0开始。
在从堆栈中移除目录时,不执行改变目录的操作,即只操作堆栈。
pushd [-n] [+N | -N | dir ]
保存当前目录到目录堆栈的顶部,并 cd 到 dir。若没有参数,则 pushd 交换顶部的两个目录。
在向堆栈中增加目录时,不执行改变目录的操作,即只操作堆栈。
通过旋转堆栈,把第N个目录(当使用不带选项的 dirs 命令时,显示的命令列表,从左开始数,从0开始)带到列表顶部。
通过旋转堆栈,把第N个目录(当使用不带选项的 dirs 命令时,显示的命令列表,从右开始数,从0开始)带到列表顶部。
把当前工作目录放到堆栈顶部,并执行 ‘cd dir’,cd到dir目录。
6.9 控制提示符
Bash在每次打印提示符之前都检测变量 PROMPT_COMMAND 的值。如果 PROMPT_COMMAND 被设置,并且有非空值,则计算该值,并打印到命令行上。
此外,下面的表格描述了可以出现在提示符变量中的特殊字符:
\a
响铃字符。
\d
日期,格式是 "Weekday Month Date" ,(例如: Tue May 26)
\D{format}
format 被传送给 strftime(3),然后把结果插入到提示符字符串中,空的 format 的结果是环境的locale指定的格式。括号是必须出现的。
\e
逃逸字符。
\h
主机名,第一个 ‘.’ 字符之前的部分。
\H
主机名。
\j
shell当前管理的作业数目。
\l
shell终端设备名的基础名字。
\n
新行符号。
\r
回车换行符号。
\s
shell的名字,$0的基础名(最后的斜杠后面的部分)。
\t
时间,24小时格式:HH:MM:SS 。
\T
时间,12小时格式:HH:MM:SS 。
\@
时间,12小时格式:am/pm 。
\A
时间,24小时格式:HH:MM 。
\u
当前的用户名。
\v
Bash的版本。(例如 2.00)
\V
Bash的发行版,版本号+补丁号(例如 2.00.0)
\w
当前的工作目录,把$HOME缩写成波浪号(使用 $PROMPT_DIRTRIM 变量)。
\W
$PWD 的基础名,把$HOME缩写成波浪号。
\!
这个命令的历史号码。
\#
这个命令的命令号码。
\$
如果有效用户的uid是0,则是#,否则是 $。
\nnn
ASCII是8进制nnn的字符。
\\
反斜杠
\[
开始一段非打印字符。用于嵌入终端控制序列到提示符中。
\]
终止一段非打印字符。
命令号码和历史号码一般是不同的,命令的历史号码是它在历史列表中的位置,该列表是从历史文件中读取到的(见 Bash历史工具 章节),而命令号码是在当前shell会话中执行的命令序列中的位置。
字符串解码后,它要经过参数扩展,命令替换,算术表达,和移除引号,根据shell选项 promptvars的值(见 Bash内建命令 章节)。
6.10 限制shell
如果Bash使用rbash启动,或者调用时使用了 --restricted 或者 -r 选项,则shell变成受限制的shell。一个受限shell用于建立一个比标准shell更加受控制的环境。受限shell的行为除下列不允许的或者不执行的命令外,与bash完全一致:
* 使用内建命令 cd 改变目录。
* 设置或取消设置变量: SHELL,PATH,ENV,or BASH_ENV。
* 指定包含斜杠的命令名。
* 把包含斜杠的文件名作为内建命令 . 的参数。
* 把包含斜杠的文件名作为内建命令hash 的选项 -p 的参数。
* 在启动时,从shell环境导入函数定义。
* 在启动时,解析shell环境的 SHELLOPTS 的值。
* 使用 ‘>’,‘>|’,‘<>’,‘>&’,‘&>’,和 ‘>>’ 重定向操作符重定向输出。
* 使用内建命令 exec 用某个命令代替shell。
* 使用内建命令 enable 启用/禁止shell内建命令。
* 指定 -p 选项给内建命令 command。
* 使用 ‘set +r’ 或 ‘set +o restricted’ 关闭模式。
在读取启动文件后,这些限制被强制执行。
当被执行的命令是一个shell脚本时,(见 shell脚本),rbash 关闭所有为执行该脚本产生的shell限制。
6.11 Bash POSIX 模式
使用 --posix 命令行选项启动Bash,或者Bash运行时,执行 ‘set -o posix’ ,会引起Bash通过改变它的默认行为,使之更加符合POSIX 标准。
当使用 sh 调用时, Bash在读取启动文件后进入 POSIX 模式。
下表列出了 POSIX 模式生效时的那些变化。
1.当一条命令不在哈希表中时,Bash要重新搜索 $PATH ,以查找新的位置。也可以通过命令启用, ‘shopt -s checkhash’ 。
2.当一个作业以非0状态退出时,作业控制码和内建命令打印的消息是 ‘Done(状态码)’ 。
3.当一个作业以非0状态停止时,作业控制码和内建命令打印的消息是 ‘Stopped(signame)’ ,其中的 signame 是,类似 SIGTSTP的信号名字。
4.内建命令bg使用提供的格式来描述位于背景的每一个作业,不包括该作业是否是当前作业或者前一个作业的一个指示符。
5.内容中出现的能够被识别的保留字时,不执行别名扩展。
6.POSIX PS1 和 PS2 扩展 ‘!’ 为历史序号,扩展 ‘!!’ 为 ‘!’ ,并且,PS1 和 PS2 的值要执行参数扩展,而不管选项 promptvars 的设置值。
8.仅仅在一个命令名前的赋值中执行波浪线扩展,而非在该行所有赋值语句中执行。
9.默认历史文件是 ~/.sh_history 。(它是 $HISTFILE 的默认值)
10. ‘kill -l’ 的输出在单一行中打印所有的信号名,用空格分隔,不使用 ‘SIG’ 前缀。
11.内建命令 kill 不接受带 ‘SIG’ 前缀的信号名。
12.如果 . filename 的 filename 找不到,则非交互shell退出。
14.如果使用内建命令 . 或者 source 命令读取的脚本中,或者内建命令 eval 处理字符串时,发生错误,则非交互shell退出。
17.函数名必须是有效的shell 名字。即,不能包含除字母、数字、下划线以外的字符,不能以数字开头。在非交互式shell中,声明一个无效名字的函数,将导致致命的语法错误。
19.time保留字可以作为命令。当作为命令使用时,它显示对于shell和它已经完成的子shell的时间统计。TIMEFORMAT 变量控制了时间信息的格式。
20.当解析和扩展位于双引号中的 ${…} 表达式时,单引号不再保留特殊含义,且不能用于包括闭合的花括号,或者其他特殊字符,除非操作符是已经定义的执行模式移除的操作符之一。此时,单引号无需成对出现。
21.如果下一个字段以 ‘-’ 开头,则 time 不被认为是保留字。
22.如果一个 POSIX 特有的内建命令返回一个错误状态,则非交互shell退出。致命错误是那些列在POSIX标准的,以及包括传递错误的选项,重定向错误,命令名前面的赋值中的变量赋值错误,等等。
23.当没有命令名字跟在赋值语句后面时,如果发生一个变量赋值错误,则一个非交互shell会退出并且是错误状态。例如,当试图赋值给只读变量时,发生变量赋值错误。
24.当一个赋值语句后跟一个特有内建命令,但是没有其他简单命令时,如果发生一个变量赋值错误,则一个非交互shell会退出并且是错误状态。
25.当一个 for 语句中的循环变量 或者在 select 语句中的选择变量是一个只读变量时,一个非交互shell会退出并且是错误状态。
26.进程替换不可用。
27.POSIX特有内建命令前面的赋值语句,在内建命令完成后,在shell环境中保持效果。
28.shell函数调用前面的赋值语句,在shell函数返回后,在shell环境中保持效果,类似POSIX特有内建命令的情况。
31.内建命令 trap 对一个可能的信号说明不检查第一个参数,并且把对该信号的处理返还给原始的处理者,除非该参数只由数字组成,并且是有效的信号数。如果用户打算对给定信号重置处理器到原始的处理者,则需要使用 ‘-’ 作为第一个参数。
33.子shell产生的可执行命令替换,从父shell继承-e选项的值。当不在POSIX模式时,Bash在该子shell中清除 -e 选项。
34.别名扩展总是启用,即使在非交互shell。
38.当内建命令 cd 以 逻辑模式调用时,并且来自 $PWD和提供的目录名组成的 路径名作为参数,没有指向一个存在的路径, 则 cd 将失败,而不是回退到 物理模式。
39.内建命令 pwd 验证它打印的值和当前目录一致,即使不带-P选项。
41.fc的默认编辑器是ed。
42.内建命令 type 和 command 不会报告一个被找到的文件是非可执行文件,如果该文件是在 $PATH 中找到的唯一同名文件,而shell则试图执行该文件。
43.当运行 ‘v’ 命令时, vi 编辑模式会直接调用vi编辑器,而不是检查 $VISUAL和 $EDITOR。
44.当启用了 xpg_echo 选项时,Bash不再试图解释echo的参数为选项。在转义字符转换后,每个参数都显示。
45.内建命令 ulimit 对于 -c 和 -f 选项,使用512字节作为块大小。
还有一些其他的POSIX行为,Bash在默认情况下没有实现,即使在POSIX 模式下。特别地: 1.如果 FCEDIT 没有设置,则内建命令 fc 检查 $EDITOR 是否是编辑历史的命令,而不是默认地指向ed。如果 EDITOR 未设置,fc使用ed。 2.如上所述,Bash需要 xpg_echo 选项启用,以使内建命令echo 完全动作。 Bash可以配置成默认POSIX兼容模式,通过在编译时,给 configure 指定 --enable-strict-posix-default 选项。(见 可选特性 章节)46.当陷阱被设置成 SIGCHLD 时,信号SIGCHLD的到来,不会中断内建命令 wait,并导致立即返回。对于每个退出的子shell,trap命令都要运行一次。