这本书假定你没有任何关于脚本或一般程序的编程知识, 但是如果你具备相关的知识, 那么你将很容易就能够达到中高级的水平. . . 所有这些只是UNIX®浩瀚知识的一小部分. 你可以把本书作为教材, 自学手册, 或者是关于shell脚本技术的文档. 书中的练习和样例脚本中的注释将会与读者进行更好的互动, 但是最关键的前提是:想真正学习脚本编程的唯一途径就是亲自动手编写脚本.这本书也可作为教材来讲解一般的编程概念.
本文档的最新版本是作为一个归档文件bzip2-ed,"tar包"来发布的, 其中还包括SGML源代码和编译好的HTML版本. 读者可以从作者的主页上下载.pdf版本也可以从作者的主页上下载. 查看change log来查看校订历史.
目录序1.原书作者致中国读者(英文)2.原书作者致中国读者(译文)3.黄毅4.杨春敏第一部分.热身1.为什么使用shell编程?2.带着一个Sha-Bang出发(Sha-Bang指的是#!)2.1.调用一个脚本2.2.初步的练习第二部分.基本3.特殊字符4.变量和参数的介绍4.1.变量替换4.2.变量赋值4.3.Bash变量是不区分类型的4.4.特殊的变量类型5.引用5.1.引用变量5.2.转义6.退出和退出状态码7.条件判断7.1.条件测试结构7.2.文件测试操作符7.3.其他比较操作符7.4.嵌套的if/then条件测试7.5.检测你对测试知识的掌握情况8.操作符与相关主题8.1.操作符8.2.数字常量第三部分.进阶9.变量重游9.1.内部变量9.2.操作字符串9.3.参数替换9.4.指定变量的类型: 使用declare或者typeset9.5.变量的间接引用9.6.$RANDOM: 产生随机整数9.7.双圆括号结构10.循环与分支10.1.循环10.2.嵌套循环10.3.循环控制10.4.测试与分支(case与select结构)11.内部命令与内建命令11.1.作业控制命令12.外部过滤器, 程序和命令12.1.基本命令12.2.复杂命令12.3.时间/日期 命令12.4.文本处理命令12.5.文件与归档命令12.6.通讯命令12.7.终端控制命令12.8.数学计算命令12.9.混杂命令13.系统与管理命令13.1.分析一个系统脚本14.命令替换15.算术扩展16.I/O重定向16.1.使用exec16.2.代码块重定向16.3.重定向的应用17.Here Document17.1.Here String18.休息片刻第四部分.高级主题19.正则表达式19.1.一份简要的正则表达式介绍19.2.通配(globbing)20.子shell21.受限shell22.进程替换23.函数23.1.复杂函数和函数复杂性23.2.局部变量23.3.不使用局部变量的递归24.别名25.列表结构26.数组27./dev和/proc27.1./dev27.2./proc28.Zero与Null29.调试30.选项31.陷阱32.脚本编程风格32.1.非官方的Shell脚本编写风格33.杂项33.1.交互与非交互式的交互与非交互式的shell和脚本33.2.Shell包装33.3.测试和比较: 一种可选的方法33.4.递归33.5.将脚本"彩色化"33.6.优化33.7.各种小技巧33.8.安全问题33.9.可移植性问题33.10.Windows下的shell脚本34.Bash, 版本2与版本334.1.Bash, 版本234.2.Bash, 版本335.后记35.1.作者后记35.2.关于作者35.3.译者后记35.3.1.杨春敏35.3.2.黄毅35.4.在哪里可以获得帮助35.5.用来制作这本书的工具35.5.1.硬件35.5.2.软件与排版软件35.6.致谢35.7.译者致谢······························································································································································································································································································································参考文献A.捐献的脚本B.参考卡片C.一个学习Sed和Awk的小手册C.1.SedC.2.AwkD.带有特殊含义的退出码E.I/O和I/O重定向的详细介绍F.命令行选项F.1.标准命令行选项F.2.Bash命令行选项G.重要的文件H.重要的系统目录I.本地化J.历史命令K.一个简单的.bashrc文件L.将DOS批处理文件转换为Shell脚本M.练习M.1.分析脚本M.2.编写脚本N.修订记录O.翻译版修订记录P.镜像站点Q.To Do列表R.版权表格清单11-1.作业标识符30-1.Bash选项33-1.转义序列中颜色与数值的对应B-1.特殊的shell变量B-2.测试操作: 二元比较B-3.文件类型的测试操作B-4.参数替换和扩展B-5.字符串操作B-6.一些结构的汇总C-1.基本sed操作C-2.sed操作符举例D-1."保留的"退出码L-1.批处理文件关键字 / 变量 / 操作符, 和等价的shell符号L-2.DOS命令与UNIX的等价命令N-1.修订历史O-1.翻译版修订历史例子清单2-1.清除: 清除/var/log下的log文件2-2.清除:一个改良的清除脚本2-3.清除: 一个增强的和广义的删除logfile的脚本3-1.代码块和I/O重定向3-2.将一个代码块的结果保存到文件3-3.在后台运行一个循环3-4.备份最后一天所有修改的文件4-1.变量赋值和替换4-2.简单的变量赋值4-3.简单和复杂, 两种类型的变量赋值4-4.整型还是字符串?4-5.位置参数4-6.wh,whois节点名字查询4-7.使用shift命令5-1.echo出一些诡异变量5-2.转义符6-1.退出/退出状态码6-2.反转一个条件的用法!7-1.什么是真?7-2.test,/usr/bin/test,[ ], 和/usr/bin/[都是等价命令7-3.算术测试需要使用(( ))7-4.测试那些断掉的链接文件7-5.算术比较与字符串比较7-6.检查字符串是否为null7-7.zmore8-1.最大公约数8-2.使用算术操作符8-3.使用&&和||进行混合条件测试8-4.数字常量表示法9-1.$IFS与空白字符9-2.定时输入9-3.再来一个, 定时输入9-4.定时read9-5.我是root么?9-6.arglist: 通过$*和$@列出所有的参数9-7.$*
和$@
的不一致的行为9-8.当$IFS
为空时的$*
和$@
9-9.下划线变量9-10.在一个文本文件的段落之间插入空行9-11.转换图片文件格式, 同时更改文件名9-12.将音频流文件转换为ogg各式的文件9-13.模拟getopt9-14.提取字符串的另一种方法9-15.使用参数替换和错误消息9-16.参数替换和"usage"消息(译者注: 通常就是帮助信息)9-17.变量长度9-18.参数替换中的模式匹配9-19.修改文件扩展名:9-20.使用模式匹配来解析任意字符串9-21.对字符串的前缀和后缀使用匹配模式9-22.使用declare来指定变量的类型9-23.间接引用9-24.传递一个间接引用给awk9-25.产生随机整数9-26.从一幅扑克牌中取出一张随机的牌9-27.两个指定值之间的随机数9-28.用随机数来摇单个骰子9-29.重新分配随机数种子9-30.使用awk来产生伪随机数9-31.C语言风格的变量操作10-1.一个简单的for循环10-2.每个[list]元素中都带有两个参数的for循环10-3.文件信息:对包含在变量中的文件列表进行操作10-4.在for循环中操作文件10-5.在for循环中省略in [list]部分10-6.使用命令替换来产生for循环的[list]10-7.对于二进制文件的grep替换10-8.列出系统上的所有用户10-9.在目录的所有文件中查找源字串10-10.列出目录中所有的符号链接10-11.将目录中所有符号链接文件的名字保存到一个文件中10-12.一个C风格的for循环10-13.在batch mode中使用efax10-14.简单的while循环10-15.另一个while循环10-16.多条件的while循环10-17.C风格的while循环10-18.until循环10-19.嵌套循环10-20.break和continue命令在循环中的效果10-21.多层循环的退出10-22.多层循环的continue10-23.在实际的任务中使用"continue N"10-24.使用case10-25.使用case来创建菜单10-26.使用命令替换来产生case变量10-27.简单的字符串匹配10-28.检查输入字符是否为字母10-29.使用select来创建菜单10-30.使用函数中的select结构来创建菜单11-1.一个fork出多个自身实例的脚本11-2.使用printf的例子11-3.使用read来进行变量分配11-4.当使用一个不带变量参数的read命令时, 将会发生什么?11-5.read命令的多行输入11-6.检测方向键11-7.通过文件重定向来使用read命令11-8.管道输出到read中的问题11-9.修改当前工作目录11-10.使用"let"命令来做算术运算.11-11.展示eval命令的效果11-12.强制登出(log-off)11-13.另一个"rot13"版本11-14.在Perl脚本中使用eval命令来强制变量替换11-15.使用set命令来改变脚本的位置参数11-16.反转位置参数11-17.重新分配位置参数11-18."Unsett"一个变量11-19.使用export命令来将一个变量传递到一个内嵌awk的脚本中11-20.使用getopts命令来来读取传递给脚本的选项/参数11-21."includ"一个数据文件11-22.一个(没什么用的)source自身的脚本11-23.exec命令的效果11-24.一个exec自身的脚本11-25.在继续处理之前, 等待一个进程的结束11-26.一个结束自身的脚本程序12-1.使用ls命令来创建一个烧录CDR的内容列表12-2.到底是Hello还是Good-bye12-3.糟糕的文件名, 删除当前目录下文件名中包含一些糟糕字符(包括空白的文件.12-4.通过文件的inode号来删除文件12-5.Logfile: 使用xargs来监控系统log12-6.把当前目录下的文件拷贝到另一个文件中12-7.通过名字kill进程12-8.使用xargs分析单词出现的频率12-9.使用expr12-10.使用date命令12-11.分析单词出现的频率12-12.哪个文件是脚本?12-13.产生10-进制随机数12-14.使用tail命令来监控系统log12-15.在脚本中模拟"grep"的行为12-16.在19的韦氏词典中查找定义12-17.检查列表中单词的正确性12-18.转换大写: 把一个文件的内容全部转换为大写.12-19.转换小写: 将当前目录下的所有文全部转换为小写.12-20.Du: DOS到UNIX文本文件的转换.12-21.rot13: rot13, 弱智加密.12-22.产生"Crypto-Quote"游戏(译者: 一种文字游戏)12-23.格式化文件列表.12-24.使用column来格式化目录列表12-25.nl: 一个自己计算行号的脚本.12-26.manview: 查看格式化的man页12-27.使用cpio来拷贝一个目录树12-28.解包一个rpm归档文件12-29.从C文件中去掉注释12-30.浏览/usr/X11R6/bin12-31.一个"改进过"的strings命令12-32.在一个脚本中使用cmp命令来比较两个文件.12-33.basename和dirname12-34.检查文件完整性12-35.Uudecode编码后的文件12-36.查找滥用的链接来报告垃圾邮件发送者12-37.分析一个垃圾邮件域12-38.获得一份股票报价12-39.更新FC4(Fedora 4)12-40.使用ssh12-41.一个mail自身的脚本12-42.按月偿还贷款12-43.数制转换12-44.使用"here document"来调用bc12-45.计算圆周率12-46.将10进制数字转换为16进制数字12-47.因子分解12-48.计算直角三角形的斜边12-49.使用seq命令来产生循环参数12-50.字母统计12-51.使用getopt来分析命令行选项12-52.一个拷贝自身的脚本12-53.练习dd12-54.记录按键12-55.安全的删除一个文件12-56.文件名产生器12-57.将长度单位-米, 转化为英里12-58.使用m413-1.设置一个新密码13-2.设置一个擦除字符13-3.保密密码: 关闭终端对于密码的echo13-4.按键检测13-5.扫描远程机器上的identd服务进程13-6.使用pidof命令帮忙kill一个进程13-7.检查一个CD镜像13-8.在一个文件中创建文件系统13-9.添加一个新的硬盘驱动器13-10.用umask将输出文件隐藏起来13-11.killall, 来自于/etc/rc.d/init.d14-1.愚蠢的脚本策略14-2.将一个循环输出的内容设置到变量中14-3.找anagram(回文构词法, 可以将一个有意义的单词, 变换为1个或多个有意义的单词, 但是还是原来的子母集合)16-1.使用exec重定向stdin16-2.使用exec来重定向stdout16-3.使用exec在同一个脚本中重定向stdin和stdout16-4.避免子shell16-5.while循环的重定向16-6.重定向while循环的另一种形式16-7.重定向until循环16-8.重定向for循环16-9.重定向for循环(stdin和stdout都进行重定向)16-10.重定向if/then测试结构16-11.用于上面例子的"names.data"数据文件16-12.事件纪录17-1.广播: 将消息发送给每个登陆的用户17-2.虚拟文件: 创建一个2行的虚拟文件17-3.使用cat的多行消息17-4.带有抑制tab功能的多行消息17-5.使用参数替换的here document17-6.上传一个文件对到"Sunsite"的incoming目录17-7.关闭参数替换17-8.生成另外一个脚本的脚本17-9.Here document与函数17-10."匿名"的here Document17-11.注释掉一段代码块17-12.一个自文档化(self-documenting)的脚本17-13.在一个文件的开头添加文本17-14.分析一个邮箱20-1.子shell中的变量作用域20-2.列出用户的配置文件20-3.在子shell中进行并行处理21-1.在受限模式下运行脚本23-1.简单函数23-2.带参数的函数23-3.函数与传递给脚本的命令行参数23-4.将一个间接引用传递给函数23-5.对一个传递给函数的参数进行解除引用的操作23-6.再来一次, 对一个传递给函数的参数进行解除引用的操作23-7.取两个数中的最大值23-8.将阿拉伯数字转化为罗马数字23-9.测试函数最大的返回值23-10.比较两个大整数23-11.从username中取得用户的真名23-12.局部变量的可见范围23-13.使用局部变量的递归23-14.汉诺塔24-1.用在脚本中的别名24-2.unalias: 设置与删除别名25-1.使用"与列表"来测试命令行参数25-2.使用"与列表"来测试命令行参数的另一个例子25-3.将"或列表"和"与列表"结合使用26-1.简单的数组使用26-2.格式化一首诗26-3.多种数组操作26-4.用于数组的字符串操作26-5.将脚本的内容赋值给数组26-6.一些数组专用的小道具26-7.空数组与包含空元素的数组26-8.初始化数组26-9.拷贝和连接数组26-10.关于串联数组的更多信息26-11.一位老朋友:冒泡排序26-12.嵌套数组与间接引用26-13.复杂的数组应用:埃拉托色尼素数筛子26-14.模拟一个下推堆栈26-15.复杂的数组应用:探索一个神秘的数学序列26-16.模拟一个二维数组, 并使他倾斜27-1.利用/dev/tcp来检修故障27-2.找出与给定PID相关联的进程27-3.网络连接状态28-1.隐藏令人厌恶的cookie28-2.使用/dev/zero来建立一个交换文件28-3.创建一个ramdisk29-1.一个错误脚本29-2.缺少关键字29-3.test24, 另一个错误脚本29-4.使用"assert"来测试条件29-5.捕获exit29-6.Control-C之后, 清除垃圾29-7.跟踪一个变量29-8.运行多进程(在对称多处理器(SMP box)的机器上)31-1.数字比较与字符串比较并不相同31-2.子shell缺陷31-3.将echo的输出通过管道传递给read命令33-1.shell包装33-2.稍微复杂一些的shell包装33-3.一个通用的shell包装, 用来写日志文件33-4.包装awd脚本的shell包装33-5.另一个包装awd脚本的shell包装33-6.将Perl嵌入到Bash脚本中33-7.将Bash和Perl脚本写到同一个文件中33-8.递归调用自身的(没用的)脚本33-9.递归调用自身的(有用的)脚本33-10.另一个递归调用自身的(有用的)脚本33-11.一个"彩色的"地址数据库33-12.画一个盒子33-13.显示彩色文本33-14."赛马"游戏33-15.返回值小技巧33-16.返回多个值的技巧33-17.传递数组到函数, 从函数中返回数组33-18.anagram游戏33-19.从shell脚本中调用窗口部件34-1.字符串扩展34-2.间接变量引用 - 新方法34-3.使用间接变量引用的简单数据库应用34-4.使用数组和其他的小技巧来处理4人随机打牌A-1.mailformat: 格式化一个e-mail消息A-2.rn: 一个非常简单的文件重命名工具A-3.blank-rename: 重命名包含空白的文件名A-4.encryptedpw: 使用一个本地加密口令, 上传到一个ftp服务器.A-5.copy-cd: 拷贝一个数据CDA-6.Collatz序列A-7.days-between: 计算两个日期之间天数差A-8.构造一个"字典"A-9.Soundex转换A-10."Game of Life"A-11."Game of Life"的数据文件A-12.behead: 去掉信件与新消息的头A-13.ftpget: 通过ftp下载文件A-14.password: 产生随机的8个字符的密码A-15.fifo: 使用命名管道来做每日的备份A-16.使用模操作符来产生素数A-17.tree: 显示目录树A-18.string functions: C风格的字符串函数A-19.目录信息A-20.面向对象数据库A-21.hash函数库A-22.使用hash函数来给文本上色A-23.深入hash函数A-24.挂载USB keychain型的存储设备A-25.保存weblogA-26.保护字符串的字面含义A-27.不保护字符串的字面含义A-28.鉴定是否是垃圾邮件服务器A-29.垃圾邮件服务器猎手A-30.使得wget更易用A-31.一个"podcasting"(译者: 指的是在互联网上发布音视频文件, 并允许用户订阅并自动接收的方法)脚本A-32.基础回顾A-33.一个扩展的cd命令C-1.计算字符出现次数K-1..bashrc文件样本L-1.VIEWDATA.BAT: DOS批处理文件L-2.viewdata.sh: 转换自VIEWDATA.BAT的shell脚本Q-1.打印服务器环境