高级Bash脚本编程指南

上传人:无*** 文档编号:114452565 上传时间:2022-06-28 格式:DOC 页数:84 大小:140KB
返回 下载 相关 举报
高级Bash脚本编程指南_第1页
第1页 / 共84页
高级Bash脚本编程指南_第2页
第2页 / 共84页
高级Bash脚本编程指南_第3页
第3页 / 共84页
点击查看更多>>
资源描述
高级Bash脚本编程指南正文 第一篇:高级Bash脚本编程指南译者序毫无疑问,UNIX/Linux 最重要的软件之一就是 shell,目前最流行的 shell 被称为 Bash(Bourne Again Shell),几乎所有的 Linux 和绝大部分的 UNIX 都可以使用 Bash。作为系统与用户之间的交互接口,shell 几乎是你在 UNIX 工作平台上最亲密的朋友,因此,学好 shell,是学习 Linux/UNIX 的的开始,并且它 会始终伴随你的工作学习。shell 是如此地重要,但令人惊奇的是,介绍 shell 的书没有真正令人满意的。所幸的是,我看到了 这本被人称为 abs 的书,这本书介绍了 bash 大量的细节和广阔的范围,我遇到的绝大部分的技术问题 -无论是我忘记的或是以前没有发现的-都可以在这本书里找到答案。这本使用大量的例子详细地介绍 了 Bash 的语法,各种技巧,调试等等的技术,以循序渐进的学习方式,让你了解 Bash 的所有特性, 在书中还有许多练习可以引导你思考,以得到更深入的知识。无论你是新手还是老手,或是使用其他 语言的程序员,我能肯定你能在此书用受益。而本书除了介绍 BASH 的知识之外,也有许多有用的关 于 Linux/UNIX 的知识和其他 shell 的介绍。在看到本书的英文版后,我决定把它翻译出来,在 Linuxsir 论坛上结识了译者之一杨春敏共同翻译这本书,600 多页的书是本大部头的书,我们花了 6 个月的业余时间才翻译完了。关于版权的问题,英文版的作者 Mendel Cooper 对英文版的版权做了详细的约定,请参考: Appendix Q. Copyright。中文版版权由译者杨春敏和黄毅共同所有,在遵守英文版版权相应条款的条 件下,欢迎在保留本书译者名字和版权说明以非盈利的方式自由发布此中文版,以盈利目的的所有行 为必须联系英文作者和两位中文译者以获得许可。本书得以成稿,我(黄毅)要多谢我的女朋友,本该给予她的时间我用来了翻译,多谢你的理解, 你是一个很棒的女朋友!译者 杨春敏 黄毅 2021.5.15Advanced Bash-Scripting Guide 一本深入学习 shell 脚本艺术的书籍2021/11/16作者:Mendel Coopermail:thegrendel这本书假定你没有任何脚本或一般程序的编程知识,但是如果你有相关的知识,那么你将很容易 达到中高级的水平.all the while sneaking in little snippets of UNIX? wisdom and lore(这句不知道怎么译).你可以把本书作为教材,自学手册,或者你获得 shell 脚本技术的文档. 书中的练习和例子脚本中的注释将会与读者有更好的互动,但是最关键的前提是: 想真正学习脚本编程的唯一途径就是编写脚本.这本书也可作为教材来讲解一般的编程概念.下载本书最新版本, 这是一个以 tar 和 bzip2 进行打包的,并且是以 HTML 来发行的.当然,你也可以获得本书的 pdf 版本 在 http:/www./LDP/abs/abs-guide.pdf.可以在 中查看修订历史.译者:杨春敏,黄毅mail:chu一直想好好学习一下 bash,可惜网上的资料都杂乱不堪,我还是喜欢通过一本书系统的学习.这本 书来得正是时候.本书的作者真是非常的严谨,从例子里的改进人名单就能看出来.可惜我水平真 的是非常有限,好多地方估计译得都有问题.希望阅读的朋友们多多提些修改建议.我会尽我的最 大努力去修正它.目录 + 第一部分. 热身1. 为什么使用2.1. 调用一个脚本2.2. 初步的练习 shell 编程2. 带着一个 Sha-Bang 出发(Sha-Bang 指的是#!) 第二部分. 基本3. 特殊字符4. 变量和参数的介绍4.1. 变量替换4.2. 变量赋值4.3. Bash 变量是不分类型的4.4. 特殊的变量类型5. 引用(翻译的可能有问题,特指引号)5.1. 引用变量5.2. 转义()6. 退出和退出状态7. Tests7.1. Test 结构7.2. 文件测试操作7.3. 其他比较操作7.4. 嵌套的8. 操作符和相关的主题8.1. 操作符8.2. 数字常量if/then 条件 test7.5. 检查你的 test 知识第三部分. 超越基本9. 变量重游9.1. 内部变量9.2. 操作字符串9.3. 参数替换9.4. 指定类型的变量:declare 或者9.5. 变量的间接引用9.6. $RANDOM: 产生随机整数9.7. 双圆括号结构10. 循环和分支10.1. 循环10.2. 嵌套循环10.3. 循环控制10.4. 测试与分支(case 和11. 内部命令与内建11.1. 作业控制命令12. 外部过滤器,程序和命令12.1. 基本命令12.2. 复杂命令12.3. 时间/日期typesetselect 结构)命令12.4. 文本处理命令12.5. 文件与归档命令12.6. 通讯命令12.7. 终端控制命令12.8. 数学计算命令12.9. 混杂命令13. 系统与管理命令13.1. 分析一个系统脚本14. 命令替换15. 算术扩展16. I/O 重定向16.1. 使用16.3. 应用exec16.2. 代码块的重定向17. Here Documents17.1. Here Strings18. 休息时间Part 4. 高级19. 正则表达式19.1. 一个简要的正则表达式介绍19.2. 通配2021子 shell(Subshells)21. 受限 shell(Restricted Shells)22. 进程替换23. 函数23.1. 复杂函数和函数复杂性23.2. 局部变量23.3. 不使用局部变量的递归24. 别名(Aliases)25. 列表结构26. 数组27. /dev 和 /proc27.1. /dev27.2. /proc28. 关于29. 调试30. 选项31. Gotchas32. 脚本编程风格32.1. 非官方的33. 杂项33.1. 交互式和非交互式的33.2. Shell 包装33.3. 测试和比较: 另一种方法33.4. 递归33.5. 彩色脚本 Zeros 和 NullsShell 脚本风格shells 和脚本33.6. 优化33.7. 各种小技巧33.8. 安全话题33.8.1.被感染的脚本 33.8.2. 隐藏 Shell 脚本源码33.9. 移植话题33.10. 在34.1. Bash, 版本34.2. Bash, 版本Windows 下进行 Shell 编程34. Bash, 版本 2 和 32 3 35. 后记35.1. 作者后记35.2. 关于作者35.3. 哪里可以取得帮助?35.4. 制作这本书的工具35.4.1. 硬件35.4.2. 软件和排版软件35.5. CreditsBibliographyA. Contributed Scripts B. Reference CardsC. A Sed and Awk Micro-PrimerC.1. SedC.2. AwkD. Exit Codes With Special MeaningsE. A Detailed Introduction to I/O and I/O Redirection F. Standard Command-Line Options G. Important Files H. Important System Directories I. Localization J. History Commands K. A Sample .bashrc FileL. Converting DOS Batch Files to Shell ScriptsM. ExercisesM.1. Analyzing ScriptsM.2. Writing ScriptsN. Revision History O. Mirror SitesP. To Do List Q. Copyright表格清单:11-1. 作业标识符30-1. Bash 选项33-1. 转义序列中数值和彩色的对应 B-1. Special Shell Variables B-2. TEST Operators: Binary Comparison B-3. TEST Operators: Files B-4. Parameter Substitution and Expansion B-5. String Operations B-6. Miscellaneous Constructs C-1. Basic sed operatorsC-2. Examples of sed operators D-1. Reserved Exit Codes L-1. Batch file keywords / variables / operators, and their shell equivalents L-2. DOS commands and their UNIX equivalents N-1. Revision History例子清单:2-1. 清除:清除/var/log 下的 log 文件 2-2. 清除:一个改良的清除脚本2-3. cleanup:一个增强的和广义的删除 logfile 的脚本 3-1. 代码块和 I/O 重定向3-2. 将一个代码块的结果保存到文件 3-3. 在后台运行一个循环3-4. 备份最后一天所有修改的文件. 4-1. 变量赋值和替换 4-2. 一般的变量赋值4-3. 变量赋值,一般的和比较特殊的 4-4. 整型还是 string? 4-5. 位置参数4-6. wh,whois 节点名字查询 4-7. 使用 shift5-1. echo 一些诡异的变量 5-2. 转义符6-1. exit/exit 状态6-2. 否定一个条件使用! 7-1. 什么情况下为真? 7-2. 几个等效命令 test,/usr/bin/test,和/usr/bin/ 7-3. 算数测试使用( ) 7-4. test 死的链接文件 7-5. 数字和字符串比较7-6. 测试字符串是否为 null 7-7. zmore 8-1. 最大公约数8-2. 使用算术操作符8-3. 使用&和|进行混合状态的 test 8-4. 数字常量的处理 9-1. $IFS 和空白 9-2. 时间输入9-3. 再来一个时间输入 9-4. Timed read 9-5. 我是 root?9-6. arglist:通过$*和$列出所有的参数 9-7. 不一致的$*和$行为 9-8. 当$IFS 为空时的$*和$ 9-9. 下划线变量9-10. 在一个文本文件的段间插入空行 9-11. 利用修改文件名,来转换图片格式 9-12. 模仿 getopt 命令9-13. 提取字符串的一种可选的方法 9-14. 使用参数替换和 error messages 9-15. 参数替换和usagemessages 9-16. 变量长度9-17. 参数替换中的模式匹配 9-18. 重命名文件扩展名9-19. 使用模式匹配来分析比较特殊的字符串 9-2021对字符串的前缀或后缀使用匹配模式 9-21. 使用 declare 来指定变量的类型 9-22. 间接引用9-23. 传递一个间接引用给 awk 9-24. 产生随机数9-25. 从一副扑克牌中取出一张随机的牌 9-26. 两个指定值之间的随机数 9-27. 使用随机数来摇一个骰子 9-28. 重新分配随机数种子 9-29. 使用 awk 产生伪随机数9-30. C 风格的变量处理 10-1. 循环的一个简单例子10-2. 每个list元素带两个参数的 for 循环10-3. 文件信息:对包含在变量中的文件列表进行操作 10-4. 在 for 循环中操作文件 10-5. 在 for 循环中省略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-2021break 和 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. Unset 一个变量11-18. 使用 export 命令传递一个变量到一个内嵌 awk 的脚本中 11-19. 使用 getopts 命令来读取传递给脚本的选项/参数. 11-2021Including一个数据文件11-21. 一个没什么用的,source 自身的脚本 11-22. exec 的效果11-23. 一个 exec 自身的脚本11-24. 在继续处理之前,等待一个进程的结束 11-25. 一个结束自身的脚本. 12-1. 使用 ls 命令来创建一个烧录 CDR 的内容列表12-2. Hello or Good-bye12-3. 删除当前目录下文件名中包含一些特殊字符(包括空白)的文件. 12-4. 通过文件的 inode 号来删除文件 12-5. Logfile: 使用 xargs 来监控系统 log 12-6. 把当前目录下的文件拷贝到另一个文件中 12-7. 通过名字 Kill 进程12-8. 使用 xargs 分析单词出现的频率 12-9. 使用 expr12-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-2021Du: DOS 到 UNIX 文本文件的转换. 12-21. rot13: rot13, 弱智加密. 12-22. Generating Crypto-Quote Puzzles 12-23. 格式化文件列表. 12-24. 使用 column 来格式化目录列表 12-25. nl: 一个自己计算行号的脚本. 12-26. manview: 查看格式化的 man 页 12-27. 使用 cpio 来拷贝一个目录树 12-28. 解包一个 rpm 归档文件 12-29. 从 C 文件中去掉注释12-30. Exploring /usr/X11R6/bin 12-31. 一个改进过的 strings 命令12-32. 在一个脚本中使用 cmp 来比较 2 个文件.12-33. basename 和 dirname 12-34. 检查文件完整性12-35. Uudecod 编码后的文件12-36. 查找滥用的连接来报告垃圾邮件发送者 12-37. 分析一个垃圾邮件域 12-38. 获得一份股票报价 12-39. 更新Fedora Core 412-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. Checking a remote server for identd 13-6. pidof 帮助杀掉一个进程 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(回文构词法, 可以将一个有意义的单词, 个或多个有意义的单词, 但 是还是原来的子母集合) 16-1. 使用 exec 重定向标准输入 16-2. 使用 exec 来重定向 stdout 16-3. 使用 exec 在同一脚本中重定向 stdin 和 stdout变换为 116-4. 避免子 shell 16-5. while 循环的重定向16-6. 另一种 while 循环的重定向 16-7. until 循环重定向 16-8. for 循环重定向16-9. for 循环重定向 loop (将标准输入和标准输出都重定向了) 16-10. 重定向 if/then 测试结构16-11. 用于上面例子的names.data数据文件 16-12. 记录日志事件17-1. 广播: 发送消息给每个登录上的用户 17-2. 仿造文件: 创建一个两行的仿造文件 17-3. 使用 cat 的多行消息17-4. 带有抑制 tab 功能的多行消息 17-5. 使用参数替换的 here document17-6. 上传一个文件对到Sunsite的 incoming 目录 17-7. 关闭参数替换17-8. 一个产生另外一个脚本的脚本 17-9. Here documents 与函数 17-10. 匿名 here Document 17-11. 注释掉一段代码块17-12. 一个自文档化(self-documenting)的脚本 17-13. 在一个文件的开头添加文本 2021. 子 shell 中的变量作用域 2021. 列出用户的配置文件2021. 在子 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. 用户名的真实名 23-12. 局部变量的可见范围 23-13. 用局部变量来递归 23-14. 汉诺塔 24-1. 脚本中的别名24-2. unalias: 设置和删除别名25-1. 使用与列表(and list)来测试命令行参数 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. 丢失关键字(keyword) 29-3. 另一个错误脚本29-4. 用assert测试条件 29-5. 捕捉 exit29-6. 在 Control-C 后清除垃圾 29-7. 跟踪变量29-8. 运行多进程(在多处理器的机器里) 31-1. 数字和字符串比较是不相等同的 31-2. 子 SHELL 缺陷31-3. 把 echo 的输出用管道输送给 read 命令 33-1. shell 包装33-2. 稍微复杂一些的 shell 包装 33-3. 写到日志文件的 shell 包装 33-4. 包装 awk 的脚本33-5. 另一个包装 awk 的脚本 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. 整型还是 string? 33-17. 传递和返回数组 33-18. anagrams 游戏33-19. 在 shell 脚本中调用的窗口部件 34-1. 字符串扩展34-2. 间接变量引用. ) | (cd /dest/directory & tar xpvf -)2 # 从一个目录移动整个目录树到另一个目录3 # courtesy Alan Cox , with a minor change 45 # 1) cd /source/directory源目录6 # 2) &与操作,如果cd 命令成功了,那么就执行下边的命令7 # 3) tar cfx解档,p保证所有权和文件属性, 15 # v发完整消息到 stdout 16 #f后边跟-,从 stdin 读取数据 17 # 18 #注意:x 是一个命令, p, v, f 19 # Whew! 2021212223 # 更优雅的写法应该是 24 #cd source/directory 25 #tar cf2 # -未解压的 tar 文件-| -然后把它传递到tar中- 3 # 如果 tar 没能够正常的处理bunzip2, 4 # 这就需要使用管道来执行 2 个单独的步骤来完成它. 5 # 这个练习的目的是解档bzipped的 kernel 源文件.#End Script# 注意:在上边这个例子中-不太象是 bash 的操作符,而更像是 tar 的参数. bash$echo whatever |catabcstandard input:ASCII textbash$file最后,一个真实世界的使用 tar 命令的例子.Example 3-4. 备份最后一天所有修改的文件.#Start Script# 1 #!/bin/bash 23 # 在一个tarball中(经过 tar 和 gzip 处理过的文件) 4 #+ 备份最后 24 小时当前目录下 d 所有修改的文件. 56 BACKUPFILE=backup-$(date +%m-%d-%Y)7 #在备份文件中嵌入时间.8 #Thanks, Joshua Tschida, for the idea.9 archive=$1:-$BACKUPFILE 10 #如果在命令行中没有指定备份文件的文件名, 11 #+ 那么将默认使用backup-MM-DD-YYYY.tar.gz. 1213 tar cvf - find . -mtime -1 -type f -print $archive.tar 14 gzip $archive.tar 15 echo Directory $PWD backed up in archive file $archive.tar.gz.161718 #Stephane Chazelas 指出上边代码, 19 #+ 如果在发现太多的文件的时候,或者是如果文件 2021+ 名包括空格的时候,将执行失败. 2122 # Stephane Chazelas 建议使用下边的两种代码之一23 # - 24 #find . -mtime -1 -type f -print0 | xargs -0 tar rvf $archive.tar 25 #使用 gnu 版本的 find. 262728 #find . -mtime -1 -type f -exec tar rvf $archive.tar ; 29 #对于其他风格的UNIX 便于移植,但是比较慢. 30 # - 313233 exit 0#End Script#注意:以-开头的文件名在使用-作为重定向操作符的时候,可能会产生问题. 应该写一个脚本来检查这个问题,并给这个文件加上合适的前缀.如: ./-FILENAME, $PWD/-FILENAME,或$PATHNAME/-FILENAME.如果变量的值以-开头,可能也会引起问题. 1 var=-n 2 echo$var 3 #具有echo -n的效果了,这样什么都不会输出的.-之前工作的目录.cd -将回到之前的工作目录,具体请参考$OLDPWD环境变量. 注意:一定要和之前讨论的重定向功能分开,但是只能依赖上下文区分.- 算术减号.=算术等号,有时也用来比较字符串. 1 a=282 echo $a# 28+ + 算术加号,也用在正则表达式中. 选项,对于特定的命令来说使用+来打开特定的选项,用-来关闭特定的选项. 算术取模运算.也用在正则表达式中. %home 目录.相当于$HOME 变量.bozo 是 bozo 的 home 目录,并且 ls bozo 将列出其中的内容. /就是当前用户的 home 目录,并且 ls /将列出其中的内容,如: bash$ echo bozo /home/bozobash$ echo /home/bozobash$ echo / /home/bozo/bash$ echo : /home/bozo:bash$ echo nonexistent-user nonexistent-user+当前工作目录,相当于$PWD 变量. 之前的工作目录,相当于$OLDPWD 内部变量. 用于正则表达式,这个操作将在正则表达式匹配部分讲解,只有 version3 才支持. 行首,正则表达式中表示行首.定位到行首. -=控制字符修改终端或文本显示的行为.控制字符以 CONTROL + key 组合. 控制字符在脚本中不能正常使用. Ctl-B 光标后退,这应该依赖于 bash 输入的风格,默认是 emacs 风格的. Ctl-C Break,终止前台工作. Ctl-D 从当前 shell 登出(和 exit 很像) EOF(文件结束符).这也能从 stdin 中终止输入. 在 console 或者在 xterm window 中输入的时候,Ctl-D 将删除光标下字符. 当没有字符时,Ctrl-D 将退出当前会话.在 xterm window 也有关闭窗口 的效果. Ctl-G beep.在一些老的终端,将响铃. Ctl-H backspace,删除光标前边的字符.如:1 #!/bin/bash2 # 在一个变量中插入 Ctl-H4 a=HH# 两个 Ctl-H (backspaces).5 echo abcdef# abcdef6 echo -n abcdef$a# abcdf7 # 注意结尾的空格 两个 twice.8 echo -n abcdef$a# abcdef没有 backspace 的效果了(why?). 10# 结果并不像期望的那样 11 echo; echoCtl-I 就是 tab 键. Ctl-J 新行. Ctl-K 垂直 tab.(垂直 tab?新颖,没听过) 作用就是删除光标到行尾的字符. Ctl-L clear,清屏. 回车 Ctl-M#Start Script#9 #结尾没有空格1 #!/bin/bash2 # Thank you, Lee Maschmeyer, for this example. 34 read -n 1 -s -p $Control-M leaves cursor at beginning of this line. Press Enter. x0d#当然,0d就是二进制的回车. 6 echo &2# -s参数使得任何输入都不将回显出来#+ 所以,明确的重起一行是必要的. 89 read -n 1 -s -p $Control-J leaves cursor on next line. x0a 10 echo &2# Control-J 1112 # 13是换行. 14 read -n 1 -s -p $And Control-Kx0bgoes straight down. 15 echo &2# Control-K 是垂直制表符. 1617 # 关于垂直制表符效果的一个更好的例子见下边: 1819 var=$x0aThis is the bottom linex0bThis is the top linex0a 2021cho $var 21 #这句与上边的例子使用的是同样的办法,然而: 22 echo $var | col 23 #这将造成垂直制表符右边的部分在左边部分的上边. 24 #这也解释了为什么我们要在行首和行尾加上一个换行符- 25 #+ 来避免一个混乱的屏幕输出. 2627 # Lee Maschmeyer 的解释: 28 # - 29 #In the first vertical tab example . . . the vertical tab 29 #在这里第一个垂直制表符的例子中 . . . 这个垂直制表符30 #+ makes the printing go straight down without a carriage return. 31 #This is true only on devices, such as the Linux console, 32 #+ that cant go backward. 33 #The real purpose of VT is to go straight UP, not down. 34 #It can be used to print superscripts on a printer.34 #它可以用来在一个打印机上打印上标. 35 #col 的作用,可以用来模仿 VT 的合适的行为. 3637 exit 0#End Script# Ctl-Q Ctl-S Ctl-U Ctl-VCtl-WCtl-Z继续(等价于 XON 字符),这个继续的标准输入在一个终端里挂起(等价于 XOFF 字符),这个被挂起的 stdin 在一个终端里,用 Ctl-Q 恢复 删除光标到行首的所有字符,在某些设置下,删除全行. 当输入字符时,Ctl-V 允许插入控制字符.比如,下边 2 个例子是等价的 echo -e x0aecho Ctl-V 在文本编辑器中十分有用,在 vim 中一样. 删除当前光标到前边的最近一个空格之间的字符. 在某些设置下,删除到第一个非字母或数字的字符. 终止前台工作. 空白部分分割命令或者是变量.包括空格,tab,空行,或任何它们的组合. 在一些特殊情况下,空白是不允许的,如变量赋值时,会引起语法错误. 空白行在脚本中没有效果. $IFS,对于某些命令输入的特殊变量分割域,默认使用的是空白. 如果想保留空白,使用引用.注意事项: 12 shell 做大括号的命令扩展.但是命令本身需要对扩展的结果作处理. 例外:在 pipe 中的一个大括号中的代码段可能运行在一个子 shell 中. 1 ls | read firstline; read secondline; 2 #错误,在打括号中的代码段,将运行到子 shell 中. 3 #+ 所以 ls 的输出将不能传递到代码块中. 4 echo First line is $firstline; second line is $secondline#不能工作356 # Thanks, S.C.换行符也被认为是空白.这也解释了为什么一个空行也会被认为是空白. 第 4 章 变量和参数的介绍=4.1 变量替换 - 变量替换操作符 $ 只有在变量被声明,赋值,unset 或 exported 或者是在变量代表一个 signal 的时候, 变量才会是以本来的面目出现在脚本里.变量在被赋值的时候,可能需要使用=, read 状态或者是在循环的头部. 在中还是会发生变量替换,这被叫做部分引用,或叫弱引用.而在中就不会发生变 量替换,这叫做全引用,也叫强引用.具体见第 5 章的讨论.注意:$var 与$var的区别,不加,在某些上下文将引起错误,为了安全,使用 2. 具体见 9.3 节 参数替换.Example 4-1. 变量赋值和替换#Start Script# 1 #!/bin/bash 23 # 变量赋值和替换45 a=375 6 hello=$a78 #-9 # 强烈注意,在赋值的前后一定不要有空格. 10 # 如果有空格会发生什么? 1112 #如果VARIABLE =value,13 #14 #+ 脚本将尝试运行一个VARIABLE的命令,带着一个=value参数. 1516 #如果VARIABLE= value, 17 #18 #+ script tries to run value command with18 #+ 脚本将尝试运行一个value的命令,带着19 #+ the environmental variable VARIABLE set to . 19 #+ 一个被赋成值的环境变量VARIABLE. 2021-212223 echo hello# 没有变量引用,不过是个 hello 字符串 2425 echo $hello 26 echo $hello # 同上2728 echo $hello 29 echo $hello 3031 echo 3233 hello=A B CD 34 echo $hello# A B C D 35 echo $hello # A BCD 36 # 就象你看到的 echo $hello和echo $hello将给出不同的结果. 37 #38 # Quoting a variable preserves whitespace. 38 # 引用一个变量将保留其中的空白,当然,如果是变量替换就不会保留了. 3940 echo 4142 echo $hello# $hello 43 # 44 # 全引用的作用45 #+ 将导致$变成一个单独的字符. 4647 # 注意两种引用不同的效果 484950 hello=# 设置为空值51 echo $hello (null value) = $hello 52 #注意设置一个变量为空,与 unset 它,不是一回事,虽然看起来一样 53 # 5455 # 5657 #可以在同一行上设置多个变量. 58 #+ 要以空白分隔59 #小心,这会降低可读性,和可移植性. 6061 var1=21 var2=22 var3=$V3 62 echo 63 echo var1=$var1var2=$var2var3=$var3 6465 # 在老版本的sh上,可能会有问题. 6667 # 6869 echo; echo7071 numbers=one two three 72 #73 other_numbers=1 2 3 74 # 75 #如果变量中有空白,那么引用就必要了. 76 # 77 echo numbers = $numbers 78 echo other_numbers = $other_numbers# other_numbers = 1 2 3 79 echo 8081 echo uninitialized_variable = $uninitialized_variable 82 # Uninitialized 变量为空值(根本就没赋值).83 uninitialized_variable=# 声明,但是没被初始化84#+ 其实和前边设置为空值得作用是一样的. 85 echo uninitialized_variable = $uninitialized_variable 86# 还是一个空值8788 uninitialized_variable=23# 赋值 89 unset uninitialized_variable# Unset it. 90 echo uninitialized_variable = $uninitialized_variable 91# 还是空值92 echo 9394 exit 0#End Script# 注意: 一个空值变量,或者是根本就没声明的变量,在赋值之前使用它可能会引起问题. 但是还是可以用来做算术运算#Start Script# 1 echo $uninitialized# (blank line) 2 let uninitialized += 5# Add 5 to it. 3 echo $uninitialized# 545 #结论: 6 #对于一个空值变量在做算术操作的时候,就好像它的值为 0 一样. 8 #This is undocumented (and probably non-portable) behavior. 7 #这并没被文档化(可能是不可移植)的行为.#End Script# 具体参考 Example 11-214.2 变量赋值- = 赋值操作符(前后都不能有空白) 不要与-eq 混淆,那个是 test,并不是赋值. 注意,=也可被用来做 test 操作,这依赖于上下文.Example 4-2. 一般的变量赋值#Start Script# 1 #!/bin/bash2 # 裸体变量4 echo 56 # 变量什么时候是裸体的,比如前边少了$的时候. 7 # 当它被赋值的时候,而不是被引用的时候. 89 # 赋值 10 a=879 11 echo The value of a is $a. 1213 # 使用 let 赋值 14 let a=16+5 15 echo The value of a is now $a. 1617 echo 1819 # 在 for 循环中2021cho -n Values of a in the loop are:21 for a in 7 8 9 1122 do 23echo -n $a24 done 2526 echo 27 echo 2829 # 在 read 命令状态中 30 echo -n Enter a31 read a 32 echo The value of a is now $a. 3334 echo 3536 exit 0#End Script#Example 4-3. 变量赋值,一般的和比较特殊的#Start Script# 1 #!/bin/bash 23 a=23# Simple case4 echo $a 5 b=$a 6 echo $b 78 # 现在让我们来点小变化910 a=echo Hello!# 把 echo 命令的结果传给变量 a 11 echo $a 12 #注意,如果在命令扩展结构中使用一个(!)的话,在命令行中将不能工作 13 #+ 因为这触发了 Bash 的历史机制. 14 #但是,在校本里边使用的话,历史功能是被关闭的,所以就能够正常运行. 15 1617 a=ls -l# 把 ls -l 的结果给 a 18 echo $a# 别忘了,这么引用的话,ls 的结果中的所有空白部分都没了(包括换行) 19 echo 2021cho $a# 这么引用就正常了,保留了空白 21# (具体参阅章节引用) 2223 exit 0#End Script# 使用$(.)机制进行的变量赋值(除去使用来赋值的另外一种新方法).事实上这两种方法都是 命令替换的一种形式. # 来自于/ect/rc.d/rc.local R=$(cat /ect/redhat-release) arch=$(uname -m)4.3 Bash 变量是不分类型的- 不像其他程序语言一样,Bash 并不对变量区分类型.本质上,Bash 变量都是字符串. 但是依赖于上下文,Bash 也允许比较操作和算术操作.决定这些的关键因素就是,变量中的值 是否只有数字.Example 4-4 整型还是 string?#Start Script# 1 #!/bin/bash2 # int-or-string.sh: 整形还是 string? 34 a=2334# 整型5 let a += 1 6 echo a = $a # a = 23357 echo# 还是整型910 b=$a/23/BB# 将23 替换成 BB# 这将把 b 变量从整型变为 string 12 echo b = $b# b = BB35 13 declare -i b# 即使使用 declare 命令也不会对此有任何帮助,9.4 节有解释 14 echo b = $b# b = BB35 1516 let b += 1# BB35 + 1 = 17 echo b = $b# b = 118 echo 192021=BB34 21 echo c = $c# c = BB34 22 d=$c/BB/23# S 将 BB 替换成 23 23# 这使得$d 变为一个整形24 echo d = $d# d = 2334 25 let d += 1# 2334 + 1 = 26 echo d = $d# d = 2335 27 echo 2829 # 关于空变量怎么样? 30 e= 31 echo e = $e# e =32 let e += 1# 算术操作允许一个空
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 管理文书 > 施工组织


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!