1.用在脚本和其他地方的特殊字符 #
注释. 行首以#(#!是个例外)开头是注释.
注释也可以放在于本行命令的后边.
注释也可以放在本行行首空白的后面.
标准的引用和转义字符(" ' \)可以用来转义#.
某些特定的模式匹配操作也可以使用#.
2.命令分隔符[分号, 即;].
可以在同一行上写两个或两个以上的命令.
注意一下";"某些情况下需要转义
3.终止case选项[双分号, 即;;].
1) echo $a ;;
4."点"命令[句点, 即.]. 等价于source命令. 这是一个bash的内建命令.
"点"作为文件名的一部分. 如果点放在文件名的开头的话, 那么这个文件将会成为"隐藏"文件, 并且ls命令将不会正常的显示出这个文件.
如果作为目录名的话, 一个单独的点代表当前的工作目录, 而两个点表示上一级目录.
"点"字符匹配. 当用作匹配字符的作用时, 通常都是作为正则表达式的一部分来使用, "点"用来匹配任何的单个字符
5.部分引用[双引号, 即"]. "STRING"将会阻止(解释)STRING中大部分特殊的字符.但$ \ 除外
6.全引用[单引号, 即']. 'STRING'将会阻止STRING中所有特殊字符的解释
7.逗号操作符[即,]. 逗号操作符链接了一系列的算术操作. 虽然里边所有的内容都被运行了,但只有最后一项被返回.
8.转义符[反斜线, 即\]. 一种对单字符的引用机制.
\通常用来转义"和', 这样双引号和但引号就不会被解释成特殊含义了.
9.文件名路径分隔符[斜线, 即/]. 分隔文件名不同的部分(比如 /home/bozo/projects/Makefile).
也可以用来作为除法算术操作符.
10.命令替换[即`]. `command`结构可以将命令的输出赋值到一个变量中去.
11.空命令[冒号, 即:]. 等价于"NOP" (no op, 一个什么也不干的命令). 也可以被认为与shell的内建命令true作用相同. ":"命令是一个bash的内建命令, 它的退出码(exit status)是"true"(0).
:还有很多功能,需注意。
12.取反操作符[叹号, 即!]. !操作符将会反转命令的退出码的结果,也会反转测试操作符的意义,!操作符是Bash的关键字. 在一个不同的上下文中, !也会出现在变量的间接引用中. 在另一种上下文中, 如命令行模式下, !还能反转bash的历史机制 (参见Appendix J). 需要注意的是, 在一个脚本中, 历史机制是被禁用的.
13.通配符[星号, 即*]. *可以用来做文件名匹配(这个东西有个专有名词叫globbing)的"通配符".
*也可以用在正则表达式中, 用来匹配任意个数(包含0个)的字符.
*算术操作符. 在算术操作符的上下文中, *号表示乘法运算.
如果要做求幂运算, 使用**, 这是求幂操作符.
14.测试操作符.[即?] 在一个特定的表达式中, ?用来测试一个条件的结果.
在一个双括号结构中, ?就是C语言的三元操作符. 参见例子 9-31.
在参数替换表达式中, ?用来测试一个变量是否被set了
通配符. ?在通配(globbing)中, 用来做匹配单个字符的"通配符", 在正则表达式中, 也是用来表示一个字符
15.变量替换[$](引用变量的内容).
在一个变量前面加上$用来引用这个变量的值.
$行结束符. 在正则表达式中, "$"表示行结束符.
16.${}参数替换.
$*, $@位置参数.
$?退出状态码变量. $? 变量 保存了一个命令, 一个函数, 或者是脚本本身的退出状态码.
$$进程ID变量. 这个$$ 变量 保存了它所在脚本的进程 ID [1]
17.命令组()
在括号中的命令列表, 将会作为一个子shell来运行
初始化数组. Array=(element1 element2 element3)
18.大括号扩展{xxx,yyy,zzz,...}
在大括号中, 不允许有空白, 除非这个空白被引用或转义.
代码块[大括号, 即{}]. 又被称为内部组, 这个结构事实上创建了一个匿名函数(一个没有名字的函数). 然而, 与"标准"函数不同的是, 在其中声明的变量,对于脚本其他部分的代码来说还是可见的.
19.路径名{} \;
一般都在find命令中使用. 这不是一个shell内建命令.
";"用来结束find命令序列的-exec选项. 它需要被保护以防止被shell所解释.
20.条件测试[ ]
条件测试表达式放在[ ]中. 值得注意的是[是shell内建test命令的一部分, 并不是/usr/bin/test中的外部命令的一个链接.
[[ ]]测试.
测试表达式放在[[ ]]中. (shell关键字). 具体参见关于[[ ... ]]结构的讨论.
[ ]数组元素.
在一个array结构的上下文中, 中括号用来引用数组中每个元素的编号.
[ ]字符范围.
用作正则表达式的一部分, 方括号描述一个匹配的字符范围.
21.整数扩展(( ))
扩展并计算在(( ))中的整数表达式.
请参考关于(( ... )) 结构的讨论.
22.重定向> &> >& >> < <>
scriptname >filename 重定向scriptname的输出到文件filename中. 如果filename存在的话, 那么将会被覆盖.
command &>filename 重定向command的stdout和stderr到filename中.
command >&2 重定向command的stdout到stderr中.
scriptname >>filename 把scriptname的输出追加到文件filename中. 如果filename不存在的话, 将会被创建.
[i]<>filename 打开文件filename用来读写, 并且分配文件描述符i给这个文件. 如果filename不存在, 这个文件将会被创建.
进程替换. (command)> <(command)
在一种不同的上下文中, "<"和">"可用来做 字符串比较操作.
在另一种上下文中, "<"和">"可用来做 整数比较操作. 参见例子 12-9.
<<用在here document中的重定向.
<<<用在here string中的重定向.
23.<, >ASCII comparison.
1 veg1=carrots
2 veg2=tomatoes
3 if [[ "$veg1" < "$veg2" ]]
24.\<, \>正则表达式中的单词边界 .
bash$ grep '\' textfile
25.|管道. 分析前边命令的输出, 并将输出作为后边命令的输入.
1 cat *.lst | sort | uniq
2 # 合并和排序所有的".lst"文件, 然后删除所有重复的行.
管道是进程间通讯的一个典型办法, 将一个进程的stdout放到另一个进程的stdin中. 标准的方法是将一个一般命令的输出, 比如cat或者echo, 传递到一个 "过滤命令"(在这个过滤命令中将处理输入)中, 然后得到结果. cat $filename1 $filename2 | grep $search_word
现在让我们输送ls -l的输出到一个脚本中. bash$ ls -l | ./uppercase.sh
-RW-RW-R-- 1 BOZO BOZO 109 APR 7 19:49 1.TXT
-RW-RW-R-- 1 BOZO BOZO 109 APR 14 16:48 2.TXT
-RW-R--R-- 1 BOZO BOZO 725 APR 20 20:56 DATA-FILE
管道中的每个进程的stdout比须被下一个进程作为stdin来读入. 否则, 数据流会阻塞, 并且管道将产生一些非预期的行为.作为子进程的运行的管道, 不能够改变脚本的变量. 如果管道中的某个命令产生了一个异常,并中途失败,那么这个管道将过早的终止. 这种行为被叫做broken pipe, 并且这种状态下将发送一个SIGPIPE 信号.
26.强制重定向>|
(即使设置了noclobber选项 -- 就是-C选项). 这将强制的覆盖一个现存文件.
27.或-逻辑操作||
在一个条件测试结构中, 如果条件测试结构两边中的任意一边结果为true的话, ||操作就会返回0(代表执行成功).
28.&后台运行命令. 一个命令后边跟一个& 表示在后台运行.
bash$ sleep 10 &
29.&&与-逻辑操作. 在一个条件测试结构中, 只有在条件测试结构的两边结果都为true的时候, &&操作才会返回0(代表sucess).
30.-选项, 前缀. 在所有的命令内如果想使用选项参数的话,前边都要加上"-".
COMMAND -[Option1][Option2][...]
ls -al
sort -dfu $filename
set -- $variable
31.-用于重定向stdin或stdout[破折号, 即-].
1 (cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xpvf -)
2 # 从一个目录移动整个目录树到另一个目录
使用diff命令来和另一个文件的某一段进行比较:
grep Linux file1 | diff file2 -
以"-"开头的文件名在使用"-"作为重定向操作符的时候, 可能会产生问题. 应该写一个脚本来检查这个问题, 并给这个文件加上合适的前缀. 比如: ./-FILENAME, $PWD/-FILENAME, 或者 $PATHNAME/-FILENAME. 如果变量以-开头进行命名, 可能也会引起问题.
32.-先前的工作目录. cd -将会回到先前的工作目录. 它使用了$OLDPWD 环境变量.
对于"-"的具体解释只能依赖于具体的上下文.
33.-减号. 减号属于算术操作.
34.=等号. 赋值操作
1 a=28
2 echo $a # 28
在另一种上下文环境中, "="也用来做字符串比较操作.
35.+加号. 加法算术操作.
在另一种上下文环境中, +也是一种正则表达式操作.
+选项. 一个命令或者过滤器的选项标记.
某些命令内建命令使用+来打开特定的选项, 用-来禁用这些特定的选项.
36.%取模. 取模(一次除法的余数)算术操作.
在不同的上下文中, %也是一种模式匹配操作.
37.~home目录[波浪号, 即~]. 相当于$HOME内部变量. ~bozo是bozo的home目录, 并且ls ~bozo将列出其中的内容. ~/就是当前用户的home目录, 并且ls ~/将列出其中的内容. bash$ echo ~bozo
38.~+当前工作目录. 相当于$PWD内部变量.
~-先前的工作目录. 相当于$OLDPWD内部变量.
=~正则表达式匹配. 这个操作将会在version 3版本的Bash部分进行讲解.
^行首. 在正则表达式中, "^"表示定位到文本行的行首.
控制字符
修改终端或文本显示的行为. . 控制字符以CONTROL + key这种方式进行组合(同时按下). 控制字符也可以使用8进制或16进制表示法来进行表示, 但是前边必须要加上转义符.
控制字符在脚本中不能正常使用.
39.Ctl-B退格(非破坏性的), 就是退格但是不删掉前面的字符.
40.Ctl-Cbreak. 终结一个前台作业.
41.Ctl-D从一个shell中登出(与exit很相像).
"EOF"(文件结束). 这也能从stdin中终止输入.
在console或者在xterm窗口中输入的时候, Ctl-D将删除光标下字符. 当没有字符时, Ctl-D将退出当前会话, 在一个xterm窗口中, 则会产生关闭此窗口的效果.
42.Ctl-G"哔" (beep). 在一些老式的打字机终端上, 它会响一下铃.
43.Ctl-H"退格"(破坏性的), 就是在退格之后, 还要删掉前边的字符.
44.Ctl-I水平制表符.
45.Ctl-J重起一行(换一行并到行首).
在脚本中, 也可以使用8进制表示法 -- '\012' 或者16进制表示法 -- '\x0a' 来表示.
46.Ctl-K垂直制表符.
当在console或者xterm窗口中输入文本时, Ctl-K将会删除从光标所在处到行为的全部字符. 在脚本中, Ctl-K的行为有些不同, 具体请参见下边的Lee Maschmeyer的例子程序.
47.Ctl-L清屏(清除终端的屏幕显示).
在终端中, 与clear命令的效果相同. 当发送到打印机上时, Ctl-L会让打印机将打印纸卷到最后.
48.Ctl-M回车.
49.Ctl-Q恢复(XON).
在一个终端中恢复stdin.
50.Ctl-S挂起(XOFF).
在一个终端中冻结stdin. (使用Ctl-Q可以恢复输入.)
51.Ctl-U删除光标到行首的所有字符.
在某些设置下, 不管光标的所在位置Ctl-U都将删除整行输入.
52.Ctl-V
当输入字符时, Ctl-V允许插入控制字符.
比如, 下边的两个例子是等价的:
1 echo -e '\x0a'
2 echo
Ctl-V主要用于文本编辑.
53.Ctl-W
当在控制台或一个xterm窗口敲入文本时, Ctl-W将会删除当前光标到左边最近一个空格间的全部字符. 在某些设置下, Ctl-W将会删除当前光标到左边第一个非字母或数字之间的全部字符.
54.Ctl-Z暂停前台作业.
55.空白
用来分隔函数, 命令或变量. . 空白包含空格, tab, 空行, 或者是它们之间任意的组合体. [4] 在某些上下文中, 比如变量赋值, 空白是不被允许的, 会产生语法错误.
空行不会影响脚本的行为, 因此使用空行可以很好的划分独立的函数段以增加可读性.
特殊变量$IFS用来做一些输入命令的分隔符, 默认情况下是空白.
如果想在字符串或变量中使用空白, 那么应该使用引用.