//www.gnu.org/licenses/>.
第一部分词法预览
1.控制字符
||&&&;;;()||&
2.元字符
元字符在没有引用时具有特殊含义
|&;()<>spacetab
3.保留字
!
casedodoneelifesacfiforfunctionifin
selectthenuntilwhile{}time[[]]
注:
保留字除其特有含义之外,不能另作他用。
4.注释
Shell中的注释以#开头,在#之后同行上的所有字符序列都将被shell忽略。
#能在非交互式shell(如脚本)中正常使用,没有什么限制;但在交互式shell中有限制。
要在交互式shell中使用#进行注释,必须启用interactive_comments选项;若没有启动该选项,交互式shell不允许进行注释。
在交互式shell中,interactive_comments选项默认被启用。
第二部分shell语法
5.变量
在bash中,我们可以认为变量是没有类型的(这么说其实并不准确)。
Bash变量是不区分类型的。
本质上,bash变量都是字符串。
实际上,我们并不需要为变量事先定义类型。
默认情况下,所有变量都被看作字符串并以字符串来存储,即使它们被赋值为数值时也是如此。
Shell和一些工具程序会在需要时把数值型字符串置换为对应的数值以对它们进行操作。
变量其实是一个指向实际数据的指针。
5.1自定义变量
5.1.1变量名
标识符是一串字符序列,该字符序列以一个字母或下划线开头,其后是任意长度的字母、数字或下划线字符。
Bash变量名是一个标识符。
变量名的字符长度并无限制。
Shell变量可用来保存字符串值,所能保存的字符数同样没有限制。
5.1.2变量的声明与赋值
在bash里,使用变量之前通常并不需要事先为它们做出声明。
我们只是简单地通过使用它们(比如当我们给它们赋初值时)来创建它们。
变量赋值的方式为:
先写变量名称,紧接着写=字符,最后是新值(一般不需要引号,默认为字符串)。
等号两边不能有任何空格。
当所赋予的值内含有空白时,应加上引号。
变量值可以是(而且通常是)空值,也就是不含任何字符。
空值就是null。
一个未初始化的变量将会是“null”值——就是未赋值。
空值不代表就是0。
在给变量赋值之前就使它,通常都会引起问题。
5.1.3 变量的使用
在引用变量,变量前要加上美元符号($)。
作为可选,也可以把变量放在大括号({})里。
一般而言,我们首先使用前一种,只有当变量名必须与其后的字符串区分开来时,才再加上大括号,以便区分出变量名。
但这不是必须的,只要不出现错误就行。
区别:
加上大括号是通用的,去掉大括号后是有限制的。
默认时,变量只有在执行该语句的shell自身内部才是可见的,对父shell和子shell是不可见的;可以把变量传递给在shell内调用的另一个程序(子shell),参见export内置命令。
一旦一个变量被设置,只能使用unset内建命令来取消。
6.简单命令
待写。
7.管道
command1|command2command2的标准输入是command1的标准输出
8.列表(lists)
被;&&&||连接的一连串命令序列被称为“list”(列表)。
语法 作用
cmd1;cmd2 在同一行上从左到右依次执行多条cmd;只有前条
命令执行完毕后(不管是否执行成功),才能执行
后一条命令。
它的返回值是最后一条被执行的命令
的退出状态。
Cmd&把命令cmd放到后台执行;各个在后台执行的命令
互不影响。
它的返回值是0。
Cmd1&&cmd2 逻辑与(AND)。
当且仅当cmd1执行成功(退出状态
为0)时,才会执行cmd2。
它的返回值是最后一条
被执行的命令的退出状态。
Cmd1||cmd2逻辑或(OR)。
当且仅当cmd1执行失败(退出状态为
非零)时,才会执行cmd2.它的返回值是最后一条被
执行的命令的退出状态。
9.复合命令
复合命令有(){}(())[[]]selectcaseifforwhile
until等几种。
其中,后6种在其他编程语言中又称为“控制结构/语句“。
9.1()命令
语法:
(lists)
语义:
该命令将引发当前shell产生一个子shell,该命令列表(lists)将在该子shell中执行。
在命令完成之后,所有影响shell环境的变量参数和内建命令都不再继续有效。
它的返回值就是命令列表的退出状态。
9.2{}命令
语法:
{lists;}
语义:
该命令组成一个命令块,该命令块在当前shell中执行。
在大括号中的命令块必须以一个新行或分号来结束。
它的返回值是命令块中最后一条被执行的命令的退出状态。
元字符“{”与“}”是保留字,且必须出现在一个保留字被允许、被许可的地方。
9.3(())命令
语法:
((expression))
语义:
根据“算术运算”规则对expression进行计算。
如果计算的结果是个非零值,则它的返回状态是0;否则,为1。
该命令等价于let“expression”。
小括号的两个左(右)部分之间不能有空白。
9.4[[]]命令
语法:
[[expression]]
语义:
根据条件表达式expression的计算结果,返回一个0或1。
说明:
单词拆分与路径名扩展在[[]]中不被执行。
使用[[时,大于操作符(>)、小于操作符(<)将根据本地区域设置进行逻辑排序。
使用==和!
=操作符时,操作符右边的字符串被认为是一个匹配模式,并根据模式匹配规则进行匹配。
如果nocasematch选项被启用,匹配将不区分字母大小写。
如果比较成立,则返回值为0;否则,返回值为1。
匹配模式的任何一部分都应引起来,以促使它作为一个字符串进行匹配。
9.5 if语句
9.5.1语法一:
ifcondition;then
lists
fi
语义:
如果条件表达式condition为真,则执行lists;否则,执行if语句后的命令。
9.5.2语法二:
ifcondition;then
lists_1
else
lists_2
fi
语义:
如果条件表达式condition为真,则执行lists_1;否则执行lists_2.
9.5.3语法三:
ifcondition_1;then
lists_1
elifcondition_2;then
lists_2
elifcondition_3;then
lists_3
.............
elifcondition_n;then
lists_n
else
lists_n+1
fi
语义:
如果condition_1为真,则执行lists_1;
否则,判断condition_2,如果condition_2为真,则执行lists_2;
否则,判断condition_3,如果condition_3为真,则执行lists_3;
否则,.......依次类推;
否则,判断condition_n,如果condition_n为真,则执行lists_n;
否则,执行lists_n+1。
说明:
整个if.......fi语句的返回值就是在then或else后面的最后一个被执行的命令的退出状态。
如果无任何命令执行,则返回值为0。
在if后面不一定非得是test命令或者昌用于条件判断的中括号结构([]或[[]]),只要能判断“真”“假”就行。
“ifCOMMAND”结构将会返回COMMAND的退出状态码。
9.6for语句
9.6.1语法一:
forloop_variableinargument_list
do
lists
done
语义:
for循环依次从argument_list参数列表中取出值赋值给loop_variable,然后执行lists;依次循环,直到argument_list中的参数被取完。
For循环里的in列表是可选的。
如果省略,shell循环会遍历整个命令行参数。
返回值是最后一个被执行的命令的退出状态。
如果argument_list为空,就不会执行任何命令,返回值为0.
9.6.2语法二:
for((expr1;expr2;expr3))
do
lists
done
语义:
首先,根据“算术运算”规则计算算术表达式expr1的值;
然后,计算算术表达式expr2的值;
如果expr2的值为非0(即为真),就执行循环主体lists;否则,结束for循环;
计算算术表达式expr3;
重复执行上述四步操作,直到for循环结束。
如果算术表达式被省略了,则它的值就如同等于1(即为真)。
返回值是循环主体中最后一条被执行的命令的退出状态。
如果expr1,expr2,expr3中任何一个表达式无效,则返回值为false。
9.7while语句
语法:
whilecondition
do
lists
done
语义:
while首先会检测condition的逻辑值,如果逻辑值为真,则执行lists;否则,退出while循环,执行while循环后的语句。
重复上述操作,直到退出while循环。
9.8until语句
语法:
untilcondition
do
lists
done
语义:
until同while,区别之处在于:
当condition为假时,while继续循环;当condition为真时,until退出循环。
9.9case语句
语法:
case$variablein
match_1)
lists_1
;;
match_2)
lists_2
;;
......
match_n)
lists_n
;;
*)#匹配其他所有模式
Lists_n+1
;;
esac
语义:
首先,$variable将先被扩展;然后,从前到后(先列出的在前,后列出的在后)依次匹配给出的模式。
如果找到了匹配,将执行相应的命令组,且不再匹配其他任何模式,即不执行其他匹配模式下的命令组。
如果启用nocasematch选项,则匹配规则不再区分大小写;否则,严格区分大小写。
如果使用;;操作符,在第一个匹配成功之后,
如果使用;&来替换;;,将继续执行下一个匹配模式的命令组;
如果使用;;&来替换;;,将引发shell去测试下一个匹配模式;若匹配成功,将执行与之关联的命令组。
说明:
1、多个模式可以用“|”字符加以分隔以合并成一个模式
2、最后一个模式是可选的,它的表示除列出之外其他的所有情况。
3、如果找到一个匹配之后,不会再尝试其后的匹配。
如果有匹配,整个case语句的返回值为执行序列中最后执行的命令的返回值;如果没有模式匹配,则返回值为0.
9.10select语句
语法:
select$variable[inword]
do
lists
done
语义:
待写。
9.11控制流命令
有时需要从某个for或while循环中中断(break)或者继续(continue)执行下一个代码块,或者退出(exit)整个脚本,或者将函数执行结果返回(return)给调用函数的脚本。
9.11.1break语句用于结束包含该语句的循环或case语句。
9.11.2continue语句用于中断当前循环,将控制权转换移动下一次循环。
9.11.3exit语句将退出整个脚本或shell环境。
可以在exit命令之后加上一个整数,该整数将作为返回代码发送给系统。
9.11.4return语句用于在函数中将数据返回,或返回一个结果或代码给调用脚本。
9.11.5true和false分别表示真、假。
9.11.6shift命令用于将位置参数向左移动。
如$1替换成$2,$3替换成$2,......依次类推。
注:
break、continue和shift都可以接受一个可选的整数参数,分别用来指出要中断继续、循环的层数或左移的个数;默认值均是1位。
10函数
10.1语法
functionfunction_name
{
lists
}
或
function_name()
{
lists
}
10.2语义
函数名的限制同变量名,参见“标识符”。
当在脚本中编写函数时,必须记住要在使用之前对其进行声明或定义。
函数部分必须在调用函数的命令语句之前。
不能调用尚不存在的函数。
在函数体中,位置参数($1、$2、......、$9、$#、$*、$@)都是函数的参数。
父脚本的参数则临时地被函数参数所掩盖或隐藏。
$0依旧是父脚本的名称。
当函数完成时,原来的命令行参数会恢复。
基于历史原因,当它超过9时,就应该用大括号把数字括起来。
函数的执行是在当前的shell脚本当中,而不是再另创建一个子shell。
函数(至少在POSIXshell里)没有提供局部变量。
因此所有的函数都与父脚本共享变量。
如果在函数中声明的变量前加上locale,则该变量只能在该函数和它的调用者之间共享。
在shell函数里,return和exit都可以退出函数。
其中,exit会退出整个shell脚本;return会返回一个退出值给调用者,而不是直接退出整个shell脚本。
函数会返回整数的退出状态值:
零表示成功,非零表示失败。
如果要返回其他的值,函数应设置一个全局性shell变量,或是利用父脚本捕捉它。
函数可以递归的,且没有限制。
第三部分引用
11引用
11.1单引号(')
语法作用
''除了另有一个'之外,在'和'之间的所有字符按原样取出。
11.2反斜杠(\)
语法作用
\c对\后的特殊字符c进行转义,即对c按字面意思进行解释。
11.3双引号(”)
语法作用
““除了下列字符保持其特殊含义之外,在”和”之间的所有字
符都按原样取出。
$将发生变量置换
`将发生变量置换
\只有当其后跟着$、`、“、\或时,
“\”才保留它的特殊含义。
说明:
如果历史机制被启用,除非在双引号中的!
被反斜杠转义字符(\)转义,否则历史扩展将完成。
$'sting'被特殊对待,它将扩展成string,其中的反斜杠转义字符将被C标准指定的代替。
$”string”将引发字符串被转换,根据当前区域设置(“本地化”)。
如果当前区域设置是C或POSIX,美元符号($)将被忽略。
如果字符串被替换,则替换部分被双引号所引住。
特殊字符*与@在双引号中有特殊含义(位置参数)。
12反斜杠转义字符序列
语法语义
\aalert(bell)响铃
\bbackspace退格
\eanescapecharacter字符ESC
\fformfeed换页
\nnewline换行
\rcarriagereturn回车
\vverticaltab垂直制表符
\thorizontaltab水平制表符
\\backslash反斜杠
\'singlequote单引号
\”doublequote双引号
\nnn一个八比特字符(n为八进制数)
\xHHH是十六进制值
\cx一个Ctrl-x字符
第四部分算术计算
13运算符
bash使用来自C程序设计语言的算术运算符,优先级及使用方法等同于在C中。
下面运算符的优先级依次从高到低(使用小括号时可不考虑优先级)。
运算符含义结合顺序
id++id--后置递增;后置递减从左到右
++id--id前置递增;后置递减从右到左
+-一元加号(即正);
一元减号(即负)从右到左
!
~逻辑非;二进制