简单命令(simple command):可选的变量赋值序列,空白(blank)分隔的单词和重定向(redirection),由控制操作符(control operator)结束。第一个单词指明了将要执行的命令,被传递给参数0($0)。其他单词被传递给命令的参数。
简单命令的返回值是它的退出状态,如果命令由信号n结束,则是128+n。
管道(pipeline):由控制字符|或|&分隔的命令序列。
[time [-p]] [! ]command [ [| | |&]command2 ... ]
command的标准输出经由管道连接到command2的标准输入。这种连接发生在任何的重定向之前。如果是|&,command的标准错误连接到command2的标准输入,它是2>&1 |的简写。这意味着标准错误的重定向发生在其他重定向之后。
管道的返回状态是最后的命令的退出状态。如果启用了pipefail选项,管道的返回状态是最右边的命令的退出状态值,或者是0如果所有命令都成功退出。如果管道前面有保留字!,管道退出状态是上述描述逻辑取反。shell在返回一个值之前会等待管道中的所有命令结束。
如果管道前面有保留字time,当管道结束时会报告经过的时间(elapsed tiime)及由于执行所消耗的用户时间(user time)和系统时间(system time)。-p选项改变输出格式为POSIX的格式。TIMEFORMAT变量可以设置成格式字符串,它指明了时间信息如何被显示。
管道中的每个命令都在独立的进程中执行(即子shell)。
列表(list):管道序列,由操作符;,&, &&或者||分隔,可选的由;,&或者<newline>结束。
在这些列表操作符中,&&和||有相同的优先权,然后是;和&,它们也有相同的优先权。
多个newline可以出现在列表中,用来代替分号(;)来分开命令。
如果一个命令由控制操作符&结束,shell将会在子shell中后台(background)执行它。shell不会等待命令结束,返回状态是0。由;分隔的命令会依次执行;shell依次等待每个命令结束。返回状态是最后执行的命令的结束状态。
与(AND)和或(OR)列表分别是由控制操作符&&和||分隔的管道序列。AND和OR列表执行时具有左结合性。
AND列表具有command1 && command2的形式,当且仅当command1返回0的退出状态(执行成功)时,command2才执行。
OR列表具有command1 || command2的形式,当且仅当command1返回非0的退出状态(执行失败)时,command2才执行。
AND和OR列表的返回状态是列表中最后执行命令的退出状态。
复合命令(compound command)包括:
在子shell环境中执行list。命令结束后,变量赋值和影响shell环境的内置命令的效果将会消失。返回状态是list的退出状态。
list在当前shell环境中执行。list必须由newline或者分号(;)结束。也被认作是命令组(group command)。返回状态是list的退出状态。注意:不象元字符(和),{和}是保留字,必须出现在保留字允许被识别的地方。由与它们不会分隔单词,它们和list必须由空白或者其他元字符隔开。
expression按照算术演算方式进行演算。如果expression的值是非0,返回状态就是0;否则就是1。等同于let "expression"。
依赖条件表达式expression的演算,返回状态0或者1。[[和]]之间的单词不进行单词分离和路径名扩展;波浪字符扩展,变量扩展(parameter和variable),算术扩展,命令替换,进程替换和引用移除被执行。为了将条件操作符如-f识别为原语(primary),它们必须是未被引用的。
当和[[一起使用时,<和>操作符使用当前的区域设置按字典序进行排序。
当使用==和!=操作符的时候,操作符右边的字符串被认为是个模式(pattern),按照模式匹配(pattern matching)的规则进行匹配。如果启用了shell选项nocasematch,匹配时不考虑字母字符的大小写。如果字符串匹配模式(==的情形)或者不匹配模式(!=的情形),返回0;否则是1。模式的任意部分可以被引用起来以强制当作字符串来匹配。
有个额外的二元操作符=~可用,它和==和!=有相同的优先权。使用时,操作符右边的字符串被认为是个扩展的正则表达式,按regex(3)进行匹配。如果字符串匹配模式,返回值是0,否则是1。如果正则表达式语法不正确,条件表达式的返回值是2。如果启用了shell选项nocasematch,匹配时不考虑字母字符的大小写。模式的任意部分可以被引用起来以强制当作字符串来匹配。正则表达式中的()匹配到的子字符串保存在数组变量BASH_REMATCH中。BASH_REMATCH元素0保存的是匹配整个正则表达式的字符串部分。第n个BASH_REMATCH元素保存第n个()匹配到的字符串部分。
表达式可以使用如下操作符进行组合,优先权由高到低:
( expression )
返回expression的值。用来改变操作符常规的优先权顺序。
! expression
取反。
expression1 && expression2
逻辑与。
expression1 || expression2
逻辑或。
&&和||是短路求值的。
in后面的单词列表被扩展,生成一个项目列表。变量name被依次设置成这个列表的每一个元素,同时list被执行。如果in word被省略,for命令对每一个设置的位置变量执行list。返回状态是最后执行的命令的退出状态。如果in后面的项目扩展产生空列表,将不执行命令,返回状态是0。
首先,算术表达式expr1被演算。然后重复演算算术表达式expr2直到产生0。每次expr2产生非0值,list被执行并且算术表达式expr3被演算。如果任意一个表达式被省略,它演算出1。返回值是list中最后执行的命令的退出状态,如果任意一个表达式不合法,返回false。
in后面的单词列表被扩展,生成一个项目列表。被扩展的单词集合被打印到标准错误,没个前面有个数字。如果in word被省略,位置变量被打印。显示提示符PS3并从标准输入读入一行。如果读入的行是显示的单词对应的数字,name的值被设置成相应的单词。如果是空行,重新显示单词和提示符。如果读入EOF,命令完成。任何其他的读入值将使得name被置成null。读入行保存在变量REPLY中。每次选择后list被执行,直到break命令被执行。select的退出状态是list中最后执行的命令的退出状态,如果没有命令被执行则是0。
case命令首先扩展word,并依次尝试去和每个pattern匹配。扩展word使用波浪符号扩展,变量扩展(parameter和variable),算术替换,命令替换,进程替换和引用移除。每个被检查的pattern被扩展,使用波浪符号扩展,变量扩展,算术替换,命令替换和进程替换。如果启用了shell选项nocasematch,执行匹配时不考虑字母字符的大小写。如果匹配,对应的list被执行。如果使用操作符;;,第一次匹配之后不再进行后续的匹配。使用;&导致继续执行下一组模式关联的list。使用;;&导致shell测试下一个模式,如果成功执行关联的list。如果没有模式匹配,退出状态是0。否则,退出状态是list中最后执行的命令的退出状态。
执行if list。如果退出状态是0,执行then list。否则,依次执行每个elif list,且如果它的退出状态是0,执行对应的then list然后命令完成。否则执行else list(如果有的话)。退出状态是最后执行的命令的退出状态,如果没有条件测试成true,是0。
while命令不停的执行do list,只要while list中的最后的命令返回退出状态0。until命令与while命令相同,除了测试是否定的;执行do list,只要until list中的最后的命令返回非0的退出状态。while和until命令的退出状态是最后执行的do list的退出状态,如果没有命令被执行,是0。
协进程(coprocess):shell命令,前面有coproc保留字。协进程在子shell中异步执行,好象命令由控制操作符&结束,正在执行的shell和协进程之间建立有双向的管道。
格式:coproc [NAME] command [redirections]
创建一个名为NAME的协进程。如果没有NAME,默认名为COPROC。如果command是简单命令,必须不能提供NAME;否则会被当成是简单命令的第一个单词。当协进程执行时,shell在当前shell的上下文中创建一个名为NAME的数组变量。command的标准输出经由管道连接到当前shell的文件描述符,赋给NAME[0]。command的标准输入经由管道连接到当前shell的文件描述符,赋给NAME[1]。管道建立在命令中任何的重定向之前。文件描述符能被用作shell命令和重定向的参数(使用标准单词扩展)。shell产生的用于执行协进程的进程id保存于变量NAME_PID。wait内置命令能用于等待协进程的结束。
协进程的返回状态是command的退出状态。
shell函数是一个对象,可以像调用简单命令一样调用它,调用时有新的位置变量集合,并且执行复合命令。如下声明shell函数:
[ function ] name () compound-command [redirection]
定义一个名为name的函数。保留字function是可选的。如果提供了function保留字,括号(())是可选的。函数体(body)是复合命令compound-command。这个命令通常是在{和}之间的命令list,但是可以是任何的复合命令。当name被指明为简单命令的名字时,compound-command被执行。函数定义时任何指明的重定向在函数执行时被执行。函数定义的退出状态是0,除非有语法错误或者同名的只读函数已经存在。执行时,函数的退出状态是函数体中最后执行的命令的退出状态。