这本书假定你没有任何关于脚本或一般程序的编程知识, 但是如果你具备相关的知识, 那么你将很容易就能够达到中高级的水平. . . 所有这些只是UNIX®浩瀚知识的一小部分. 你可以把本书作为教材, 自学手册, 或者是关于shell脚本技术的文档. 书中的练习和样例脚本中的注释将会与读者进行更好的互动, 但是最关键的前提是: 想真正学习脚本编程的唯一途径就是亲自动手编写脚本.
这本书也可作为教材来讲解一般的编程概念.
本文档的最新版本是作为一个归档文件bzip2-ed, "tar包"来发布的, 其中还包括SGML源代码和编译好的HTML版本. 读者可以从作者的主页上下载. pdf版本也可以从作者的主页上下载. 查看change log来查看校订历史.
- 目录
- 序
-
- 1. 原书作者致中国读者(英文)
- 2. 原书作者致中国读者(译文)
- 3. 黄毅
- 4. 杨春敏
- 第一部分. 热身
- 第二部分. 基本
- 第三部分. 进阶
-
- 9. 变量重游
-
- 9.1. 内部变量
- 9.2. 操作字符串
- 9.3. 参数替换
- 9.4. 指定变量的类型: 使用declare或者typeset
- 9.5. 变量的间接引用
- 9.6. $RANDOM: 产生随机整数
- 9.7. 双圆括号结构
- 10. 循环与分支
-
- 10.1. 循环
- 10.2. 嵌套循环
- 10.3. 循环控制
- 10.4. 测试与分支(case与select结构)
- 11. 内部命令与内建命令
-
- 11.1. 作业控制命令
- 12. 外部过滤器, 程序和命令
- 13. 系统与管理命令
-
- 13.1. 分析一个系统脚本
- 14. 命令替换
- 15. 算术扩展
- 16. I/O重定向
- 17. Here Document
-
- 17.1. Here String
- 18. 休息片刻
- 第四部分. 高级主题
-
- 19. 正则表达式
-
- 19.1. 一份简要的正则表达式介绍
- 19.2. 通配(globbing)
- 20. 子shell
- 21. 受限shell
- 22. 进程替换
- 23. 函数
-
- 23.1. 复杂函数和函数复杂性
- 23.2. 局部变量
- 23.3. 不使用局部变量的递归
- 24. 别名
- 25. 列表结构
- 26. 数组
- 27. /dev和/proc
- 28. Zero与Null
- 29. 调试
- 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与版本3
- 35. 后记
-
- 35.1. 作者后记
- 35.2. 关于作者
- 35.3. 译者后记
- 35.4. 在哪里可以获得帮助
- 35.5. 用来制作这本书的工具
- 35.6. 致谢
- 35.7. 译者致谢
- ······························································································································································································································································································································
- 参考文献
- A. 捐献的脚本
- B. 参考卡片
- C. 一个学习Sed和Awk的小手册
- D. 带有特殊含义的退出码
- E. I/O和I/O重定向的详细介绍
- F. 命令行选项
- G. 重要的文件
- H. 重要的系统目录
- I. 本地化
- J. 历史命令
- K. 一个简单的.bashrc文件
- L. 将DOS批处理文件转换为Shell脚本
- M. 练习
- 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. 检查字符串是否为null
- 7-7. zmore
- 8-1. 最大公约数
- 8-2. 使用算术操作符
- 8-3. 使用&&和||进行混合条件测试
- 8-4. 数字常量表示法
- 9-1. $IFS与空白字符
- 9-2. 定时输入
- 9-3. 再来一个, 定时输入
- 9-4. 定时read
- 9-5. 我是root么?
- 9-6. arglist: 通过$*和$@列出所有的参数
-
9-7.
$*
和$@
的不一致的行为 -
9-8.
当
$IFS
为空时的$*
和$@
- 9-9. 下划线变量
- 9-10. 在一个文本文件的段落之间插入空行
- 9-11. 转换图片文件格式, 同时更改文件名
- 9-12. 将音频流文件转换为ogg各式的文件
- 9-13. 模拟getopt
- 9-14. 提取字符串的另一种方法
- 9-15. 使用参数替换和错误消息
- 9-16. 参数替换和"usage"消息(译者注: 通常就是帮助信息)
- 9-17. 变量长度
- 9-18. 参数替换中的模式匹配
- 9-19. 修改文件扩展名:
- 9-20. 使用模式匹配来解析任意字符串
- 9-21. 对字符串的前缀和后缀使用匹配模式
- 9-22. 使用declare来指定变量的类型
- 9-23. 间接引用
- 9-24. 传递一个间接引用给awk
- 9-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中使用efax
- 10-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. 多层循环的continue
- 10-23. 在实际的任务中使用"continue N"
- 10-24. 使用case
- 10-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-bye
- 12-3. 糟糕的文件名, 删除当前目录下文件名中包含一些糟糕字符(包括 空白的文件.
- 12-4. 通过文件的inode号来删除文件
- 12-5. Logfile: 使用xargs来监控系统log
- 12-6. 把当前目录下的文件拷贝到另一个文件中
- 12-7. 通过名字kill进程
- 12-8. 使用xargs分析单词出现的频率
- 12-9. 使用expr
- 12-10. 使用date命令
- 12-11. 分析单词出现的频率
- 12-12. 哪个文件是脚本?
- 12-13. 产生10-进制随机数
- 12-14. 使用tail命令来监控系统log
- 12-15. 在脚本中模拟"grep"的行为
- 12-16. 在1913年的韦氏词典中查找定义
- 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/bin
- 12-31. 一个"改进过"的strings命令
- 12-32. 在一个脚本中使用cmp命令来比较两个文件.
- 12-33. basename和dirname
- 12-34. 检查文件完整性
- 12-35. Uudecode编码后的文件
- 12-36. 查找滥用的链接来报告垃圾邮件发送者
- 12-37. 分析一个垃圾邮件域
- 12-38. 获得一份股票报价
- 12-39. 更新FC4(Fedora 4)
- 12-40. 使用ssh
- 12-41. 一个mail自身的脚本
- 12-42. 按月偿还贷款
- 12-43. 数制转换
- 12-44. 使用"here document"来调用bc
- 12-45. 计算圆周率
- 12-46. 将10进制数字转换为16进制数字
- 12-47. 因子分解
- 12-48. 计算直角三角形的斜边
- 12-49. 使用seq命令来产生循环参数
- 12-50. 字母统计
- 12-51. 使用getopt来分析命令行选项
- 12-52. 一个拷贝自身的脚本
- 12-53. 练习dd
- 12-54. 记录按键
- 12-55. 安全的删除一个文件
- 12-56. 文件名产生器
- 12-57. 将长度单位-米, 转化为英里
- 12-58. 使用m4
- 13-1. 设置一个新密码
- 13-2. 设置一个擦除字符
- 13-3. 保密密码: 关闭终端对于密码的echo
- 13-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.d
- 14-1. 愚蠢的脚本策略
- 14-2. 将一个循环输出的内容设置到变量中
- 14-3. 找anagram(回文构词法, 可以将一个有意义的单词, 变换为1个或多个有意义的单词, 但是还是原来的子母集合)
- 16-1. 使用exec重定向stdin
- 16-2. 使用exec来重定向stdout
- 16-3. 使用exec在同一个脚本中重定向stdin和stdout
- 16-4. 避免子shell
- 16-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 document
- 17-6. 上传一个文件对到"Sunsite"的incoming目录
- 17-7. 关闭参数替换
- 17-8. 生成另外一个脚本的脚本
- 17-9. Here document与函数
- 17-10. "匿名"的here Document
- 17-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. 隐藏令人厌恶的cookie
- 28-2. 使用/dev/zero来建立一个交换文件
- 28-3. 创建一个ramdisk
- 29-1. 一个错误脚本
- 29-2. 缺少 关键字
- 29-3. test24, 另一个错误脚本
- 29-4. 使用"assert"来测试条件
- 29-5. 捕获exit
- 29-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: 拷贝一个数据CD
- A-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. 保存weblog
- A-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. 打印服务器环境