分类:
2010-11-02 15:56:07
用在脚本和其他地方的特殊字符
注释. 行首以#()开头是注释.
1 # This line is a comment. |
注释也可以放在于本行命令的后边.
1 echo "A comment will follow." # 注释在这里. |
注释也可以放在本行行首的后面.
1 # A tab precedes this comment. |
命令是不能放在同一行上注释的后边的. 因为没有办法把注释结束掉, 好让同一行上后边的"代码生效". 只能够另起一行来使用下一个命令. |
当然, 在echo中转义的#是不能作为注释的. 同样的, #也可以出现在中, 或者是出现在中.
|
某些特定的也可以使用#.
命令分隔符[分号, 即;]. 可以在同一行上写两个或两个以上的命令.
1 echo hello; echo there |
注意一下";"某些情况下需要.
终止选项[双分号, 即;;].
1 case "$variable" in |
"点"命令[句点, 即.]. 等价于命令(参见 ). 这是一个bash的.
"点"作为文件名的一部分. 如果点放在文件名的开头的话, 那么这个文件将会成为"隐藏"文件, 并且命令将不会正常的显示出这个文件.
bash$ touch .hidden-file |
如果作为目录名的话, 一个单独的点代表当前的工作目录, 而两个点表示上一级目录.
bash$ pwd |
点经常会出现在文件移动命令的目的参数(目录)的位置上.
bash$ cp /home/bozo/current_work/junk/* . |
"点"字符匹配. 当用作的作用时, 通常都是作为的一部分来使用, "点"用来匹配任何的单个字符.
[双引号, 即"]. "STRING"将会阻止(解释)STRING中大部分特殊的字符. 参见.
[单引号, 即']. 'STRING'将会阻止STRING中所有特殊字符的解释. 这是一种比使用"更强烈的形式. 参见.
. 逗号操作符链接了一系列的算术操作. 虽然里边所有的内容都被运行了,但只有最后一项被返回.
1 let "t2 = ((a = 9, 15 / 3))" # Set "a = 9" and "t2 = 15 / 3" |
[反斜线, 即\]. 一种对单字符的引用机制.
\X将会"转义"字符X. 这等价于"X", 也等价于'X'. \通常用来转义"和', 这样双引号和但引号就不会被解释成特殊含义了.
参见来深入地了解转义符的详细解释.
文件名路径分隔符[斜线, 即/]. 分隔文件名不同的部分(比如 /home/bozo/projects/Makefile).
也可以用来作为除法.
. `command`结构可以将命令的输出赋值到一个变量中去. 我们在后边的或后置标记(backticks)中也会讲解.
空命令[冒号, 即:]. 等价于"NOP" (no op, 一个什么也不干的命令). 也可以被认为与shell的内建命令作用相同. ":"命令是一个bash的, 它的是"true"(0).
1 : |
死循环:
1 while : |
在if/then中的占位符:
1 if condition |
在一个二元命令中提供一个占位符, 具体参见, 和.
1 : ${username=`whoami`} |
在here document中提供一个命令所需的占位符. 参见.
使用来评估字符串变量 (参见).
1 : ${HOSTNAME?} ${USER?} ${MAIL?} |
.
在与>结合使用时, 将会把一个文件清空, 但是并不会修改这个文件的权限. 如果之前这个文件并不存在, 那么就创建这个文件.
1 : > data.xxx # 文件"data.xxx"现在被清空了. |
在与>>重定向操作符结合使用时, 将不会对预先存在的目标文件(: >> target_file)产生任何影响. 如果这个文件之前并不存在, 那么就创建它.
这只适用于正规文件, 而不适用于管道, 符号连接, 和某些特殊文件. |
也可能用来作为注释行, 虽然我们不推荐这么做. 使用#来注释的话, 将关闭剩余行的错误检查, 所以可以在注释行中写任何东西. 然而, 使用:的话将不会这样.
1 : This is a comment that generates an error, ( if [ $x -eq 3] ). |
":"还用来在/etc/passwd和变量中做分隔符.
bash$ echo $PATH |
取反操作符[叹号, 即!]. !操作符将会反转命令的的结果, (具体参见). 也会反转测试操作符的意义, 比如修改"等号"( )为"不等号"( != ). !操作符是Bash的.
在一个不同的上下文中, !也会出现在中.
在另一种上下文中, 如命令行模式下, !还能反转bash的历史机制 (参见). 需要注意的是, 在一个脚本中, 历史机制是被禁用的.
通配符[星号, 即*]. *可以用来做文件名匹配(这个东西有个专有名词叫)的"通配符". 含义是, 可以用来匹配给定目录下的任何文件名.
bash$ echo * |
*也可以用在中, 用来匹配任意个数(包含0个)的字符.
. 在算术操作符的上下文中, *号表示乘法运算.
如果要做求幂运算, 使用**, 这是.
测试操作符. 在一个特定的表达式中, ?用来测试一个条件的结果.
在一个中, ?就是C语言的三元操作符. 参见.
在表达式中, ?.
通配符. ?在中, 用来做匹配单个字符的"通配符", 在中, 也是用来.
(引用变量的内容).
1 var1=5 |
在一个变量前面加上$用来引用这个变量的值.
行结束符. 在, "$"表示行结束符.
.
.
退出状态码变量. 保存了一个命令, 一个, 或者是脚本本身的.
进程ID变量. 这个 保存了它所在脚本的进程 ID
命令组.
1 (a=hello; echo $a) |
在括号中的命令列表, 将会作为一个来运行. 在括号中的变量,由于是在子shell中,所以对于脚本剩下的部分是不可用的. 父进程, 也就是脚本本身, , 也就是在子shell中创建的变量.
|
初始化数组.
1 Array=(element1 element2 element3) |
大括号扩展.
1 cat {file1,file2,file3} > combined_file |
一个命令可能会对大括号 中的以逗号分割的文件列表起作用. ()将对大括号中的文件名做扩展.
在大括号中, 不允许有空白, 除非这个空白被引用或转义. echo {file1,file2}\ :{\ A," B",' C'} file1 : A file1 : B file1 : C file2 : A file2 : B file2 : C |
代码块[大括号, 即{}]. 又被称为内部组, 这个结构事实上创建了一个匿名函数(一个没有名字的函数). 然而, 与"标准"不同的是, 在其中声明的变量,对于脚本其他部分的代码来说还是可见的.
bash$ { local a; |
1 a=123 |
下边的代码展示了在大括号结构中代码的.
例子 3-1. 代码块和I/O重定向
1 #!/bin/bash |
例子 3-2. 将一个代码块的结果保存到文件
1 #!/bin/bash |
与上面所讲到的()中的命令组不同的是, {大括号}中的代码块将不会开启一个新的. |
路径名. 一般都在命令中使用. 这不是一个shell.
";"用来结束find命令序列的 |
条件测试.
表达式放在[ ]中. 值得注意的是[是shell内建test命令的一部分, 并不是/usr/bin/test中的外部命令的一个链接.
测试.
测试表达式放在[[ ]]中. (shell).
具体参见关于.
数组元素.
在一个结构的上下文中, 中括号用来引用数组中每个元素的编号.
1 Array[1]=slot_1 |
字符范围.
用作的一部分, 方括号描述一个匹配的.
整数扩展.
扩展并计算在(( ))中的整数表达式.
请参考关于的讨论.
.
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)
, "<"和">"可用来做 .
, "<"和">"可用来做 . 参见.
用在here document中的重定向.
用在中的重定向.
.
1 veg1=carrots |
中的 .
bash$ grep '\
管道. 分析前边命令的输出, 并将输出作为后边命令的输入. 这是一种产生命令链的好方法.
1 echo ls -l | sh |
管道是进程间通讯的一个典型办法, 将一个进程的stdout放到另一个进程的stdin中. 标准的方法是将一个一般命令的输出, 比如或者, 传递到一个 "过滤命令"(在这个过滤命令中将处理输入)中, 然后得到结果. cat $filename1 $filename2 | grep $search_word |
当然输出的命令也可以传递到脚本中.
1 #!/bin/bash |
bash$ ls -l | ./uppercase.sh |
管道中的每个进程的stdout比须被下一个进程作为stdin来读入. 否则, 数据流会阻塞, 并且管道将产生一些非预期的行为.
作为的运行的管道, 不能够改变脚本的变量.
如果管道中的某个命令产生了一个异常,并中途失败,那么这个管道将过早的终止. 这种行为被叫做broken pipe, 并且这种状态下将发送一个SIGPIPE . |
强制重定向(即使设置了 -- 就是-C选项). 这将强制的覆盖一个现存文件.
. 在一个中, 如果条件测试结构两边中的任意一边结果为true的话, ||操作就会返回0(代表执行成功).
后台运行命令. 一个命令后边跟一个& 表示在后台运行.
bash$ sleep 10 & |
在一个脚本中,命令和都可能运行在后台.
例子 3-3. 在后台运行一个循环
1 #!/bin/bash |
在一个脚本内后台运行一个命令,有可能造成这个脚本的挂起,等待一个按键 响应. 幸运的是, 我们有针对这个问题的. |
. 在一个中, 只有在条件测试结构的两边结果都为true的时候, &&操作才会返回0(代表sucess).
选项, 前缀. 在所有的命令内如果想使用选项参数的话,前边都要加上"-".
COMMAND -[Option1][Option2][...]
ls -al
sort -dfu $filename
set -- $variable
1 if [ $file1 -ot $file2 ] |
用于重定向stdin或stdout[破折号, 即-].
1 (cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xpvf -) |
1 bunzip2 -c linux-2.6.16.tar.bz2 | tar xvf - |
注意, 在这个上下文中"-"本身并不是一个Bash操作, 而是一个可以被特定的UNIX工具识别的选项, 这些特定的UNIX工具特指那些可以写输出到stdout的工具, 比如tar, cat, 等等.
bash$ echo "whatever" | cat - |
在需要一个文件名的位置, -重定向输出到stdout(有时候会在tar和cf中出现), 或者从stdin接受输入, 而不是从一个文件中接受输入. 这是在管道中使用文件导向(file-oriented)工具来作为过滤器的一种方法.
bash$ file |
添加一个"-"将得到一个更有用的结果. 这会使shell等待用户输入.
bash$ file - |
"-"可以被用来将stdout通过管道传递到其他命令中. 这样就允许使用的技巧.
使用命令来和另一个文件的某一段进行比较:
grep Linux file1 | diff file2 -
最后, 来展示一个使用-的命令的一个真实的例子.
例子 3-4. 备份最后一天所有修改的文件
1 #!/bin/bash |
以"-"开头的文件名在使用"-"作为重定向操作符的时候, 可能会产生问题. 应该写一个脚本来检查这个问题, 并给这个文件加上合适的前缀. 比如: ./-FILENAME, $PWD/-FILENAME, 或者 $PATHNAME/-FILENAME. 如果变量以-开头进行命名, 可能也会引起问题.
|
先前的工作目录. cd -将会回到先前的工作目录. 它使用了 .
不要混淆这里所使用的"-"和先前我们所讨论的"-"重定向操作符. 对于"-"的具体解释只能依赖于具体的上下文. |
减号. 减号属于.
等号.
1 a=28 |
在, "="也用来做操作.
加号. 加法.
在, +也是一种操作.
选项. 一个命令或者过滤器的选项标记.
某些命令使用+来打开特定的选项, 用-来禁用这些特定的选项.
. 取模(一次除法的余数).
在, %也是一种操作.
home目录[波浪号, 即~]. 相当于内部变量. ~bozo是bozo的home目录, 并且ls ~bozo将列出其中的内容. ~/就是当前用户的home目录, 并且ls ~/将列出其中的内容.
bash$ echo ~bozo |
当前工作目录. 相当于内部变量.
先前的工作目录. 相当于内部变量.
. 这个操作将会在版本的Bash部分进行讲解.
行首. 在中, "^"表示定位到文本行的行首.
修改终端或文本显示的行为. . 控制字符以CONTROL + key这种方式进行组合(同时按下). 控制字符也可以使用8进制或16进制表示法来进行表示, 但是前边必须要加上转义符.
控制字符在脚本中不能正常使用.
Ctl-B
退格(非破坏性的), 就是退格但是不删掉前面的字符.
Ctl-C
break. 终结一个前台作业.
Ctl-D
从一个shell中登出(与很相像).
"EOF"(文件结束). 这也能从stdin中终止输入.
在console或者在xterm窗口中输入的时候, Ctl-D将删除光标下字符. 当没有字符时, Ctl-D将退出当前会话, 在一个xterm窗口中, 则会产生关闭此窗口的效果.
Ctl-G
"哔" (beep). 在一些老式的打字机终端上, 它会响一下铃.
Ctl-H
"退格"(破坏性的), 就是在退格之后, 还要删掉前边的字符.
1 #!/bin/bash |
Ctl-I
水平制表符.
Ctl-J
重起一行(换一行并到行首). 在脚本中, 也可以使用8进制表示法 -- '\012' 或者16进制表示法 -- '\x0a' 来表示.
Ctl-K
垂直制表符.
当在console或者xterm窗口中输入文本时, Ctl-K将会删除从光标所在处到行为的全部字符. 在脚本中, Ctl-K的行为有些不同, 具体请参见下边的Lee Maschmeyer的例子程序.
Ctl-L
清屏(清除终端的屏幕显示). 在终端中, 与命令的效果相同. 当发送到打印机上时, Ctl-L会让打印机将打印纸卷到最后.
Ctl-M
回车.
1 #!/bin/bash |
Ctl-Q
恢复(XON).
在一个终端中恢复stdin.
Ctl-S
挂起(XOFF).
在一个终端中冻结stdin. (使用Ctl-Q可以恢复输入.)
Ctl-U
删除光标到行首的所有字符. 在某些设置下, 不管光标的所在位置Ctl-U都将删除整行输入.
Ctl-V
当输入字符时, Ctl-V允许插入控制字符. 比如, 下边的两个例子是等价的:
1 echo -e '\x0a' |
Ctl-V主要用于文本编辑.
Ctl-W
当在控制台或一个xterm窗口敲入文本时, Ctl-W将会删除当前光标到左边最近一个空格间的全部字符. 在某些设置下, Ctl-W将会删除当前光标到左边第一个非字母或数字之间的全部字符.
Ctl-Z
暂停前台作业.
用来分隔函数, 命令或变量. . 空白包含空格, tab, 空行, 或者是它们之间任意的组合体. 在某些上下文中, 比如, 空白是不被允许的, 会产生语法错误.
空行不会影响脚本的行为, 因此使用空行可以很好的划分独立的函数段以增加可读性.
特殊变量用来做一些输入命令的分隔符, 默认情况下是空白.
如果想在字符串或变量中使用空白, 那么应该使用.
PID, 或进程 ID, 是分配给运行进程的一个数字. 要想察看所有运行进程的PID可以使用命令. | ||
The shell does the brace expansion. The command itself acts upon the result of the expansion. | ||
例外: 在pipe中的一个大括号中的代码段可能运行在一个 中.
| ||
一个换行符("重起一行")也被认为是空白符. 这也就解释了为什么一个只包含换行符的空行也被认为是空白. |