没有合适的资源?快使用搜索试试~ 我知道了~
首页深入学习高级Bash shell编程:Linux运维与开发宝典
深入学习高级Bash shell编程:Linux运维与开发宝典
需积分: 3 1 下载量 149 浏览量
更新于2024-07-18
收藏 2.03MB PDF 举报
"《高级shell编程》是一本专门针对Linux系统运维和开发者的实用指南,主要聚焦于Bash Shell的高级学习。Bash是目前最流行的shell,几乎覆盖所有Linux系统以及大部分UNIX环境,它作为系统与用户交互的核心工具,对于理解和掌握Linux/UNIX平台至关重要。作者Mendel Cooper的《Advanced Bash Scripting Guide》提供了丰富的内容,包括深入解析Bash的语法、技巧、调试方法,采用循序渐进的方式帮助读者逐步掌握其全部特性。 书中包含大量实例,通过实践操作让学习者加深理解,同时还设计了许多练习题,鼓励读者进行深入思考。无论你是shell编程新手,还是经验丰富的开发者,或者对其他编程语言有所了解,都能从中获益匪浅。此外,书中还涵盖了不少关于Linux/UNIX系统的基础知识以及对其他shell的介绍,使其成为一本全面的shell编程宝典。 本书的中文版由译者杨春敏和黄毅合作翻译完成,他们花费了大约6个月的业余时间翻译了这600多页的内容。在版权方面,英文版作者对版权有明确的规定,中文版在遵循英文版版权协议的前提下,允许在非盈利情况下保留译者署名和版权说明的情况下自由发布。任何商业用途的出版或使用需事先征得原文作者及译者的许可。 翻译者黄毅特别感谢了他的女朋友,因为他在翻译过程中牺牲了很多原本陪伴女友的时间,她的理解和包容使得这本书得以成形。《高级Bash脚本编程指南》是一本不可多得的资源,对于提升Linux系统管理技能和深化shell编程理解具有很高的价值。"
资源详情
资源推荐
Advance Bash Shell Guide
16
Good good study, day day up!!
################################Start Script#######################################
1 #!/bin/bash
2 # 清除, 版本 3
3
4 # Warning:
5 # -------
6 # 这个脚本有好多特征,这些特征是在后边章节进行解释的,大概是进行到本书的一半的
7 # 时候,
8 # 你就会觉得它没有什么神秘的了.
9 #
10
11
12
13 LOG_DIR=/var/log
14 ROOT_UID=0 # $UID 为 0 的时候,用户才具有根用户的权限
15 LINES=50 # 默认的保存行数
16 E_XCD=66 # 不能修改目录?
17 E_NOTROOT=67 # 非根用户将以 error 退出
18
19
20 # 当然要使用根用户来运行
21 if [ "$UID" -ne "$ROOT_UID" ]
22 then
23 echo "Must be root to run this script."
24 exit $E_NOTROOT
25 fi
26
27 if [ -n "$1" ]
28 # 测试是否有命令行参数(非空).
29 then
30 lines=$1
31 else
32 lines=$LINES # 默认,如果不在命令行中指定
33 fi
34
35
36 # Stephane Chazelas 建议使用下边
37 #+ 的更好方法来检测命令行参数.
38 #+ 但对于这章来说还是有点超前.
39 #
40 # E_WRONGARGS=65 # 非数值参数(错误的参数格式)
41 #
42 # case "$1" in
43 # "" ) lines=50;;
44 # *[!0-9]*) echo "Usage: `basename $0` file-to-cleanup"; exit $E_WRONGARGS;;
Advance Bash Shell Guide
17
Good good study, day day up!!
45 # * ) lines=$1;;
46 # esac
47 #
48 #* 直到"Loops"的章节才会对上边的内容进行详细的描述.
49
50
51 cd $LOG_DIR
52
53 if [ `pwd` != "$LOG_DIR" ] # 或者 if[ "$PWD" != "$LOG_DIR" ]
54 # 不在 /var/log 中?
55 then
56 echo "Can't change to $LOG_DIR."
57 exit $E_XCD
58 fi # 在处理 log file 之前,再确认一遍当前目录是否正确.
59
60 # 更有效率的做法是
61 #
62 # cd /var/log || {
63 # echo "Cannot change to necessary directory." >&2
64 # exit $E_XCD;
65 # }
66
67
68
69
70 tail -$lines messages > mesg.temp # 保存 log file 消息的最后部分.
71 mv mesg.temp messages # 变为新的 log 目录.
72
73
74 # cat /dev/null > messages
75 #* 不再需要了,使用上边的方法更安全.
76
77 cat /dev/null > wtmp # ': > wtmp' 和 '> wtmp'具有相同的作用
78 echo "Logs cleaned up."
79
80 exit 0
81 # 退出之前返回 0,返回 0 表示成功.
82 #
################################End Script#########################################
因为你可能希望将系统 log 全部消灭,这个版本留下了 log 消息最后的部分.你将不断地找到新的方法来完善
这个脚本,并提高效率.要注意,在每个脚本的开头都使用"#!",这意味着告诉你的系统这个文件的执行需要指定一
个解释器.#!实际上是一个 2 字节[1]的魔法数字,这是指定一个文件类型的特殊标记, 换句话说, 在这种情况下,指
的就是一个可执行的脚本(键入 man magic 来获得关于这个迷人话题的更多详细信息).在#!之后接着是一个路径
名.这个路径名指定了一个解释脚本中命令的程序,这个程序可以是 shell,程序语言或者是任意一个通用程序.这个
Advance Bash Shell Guide
18
Good good study, day day up!!
指定的程序从头开始解释并且执行脚本中的命令(从#!行下边的一行开始),忽略注释.[2]
如:
1 #!/bin/sh
2 #!/bin/bash
3 #!/usr/bin/perl
4 #!/usr/bin/tcl
5 #!/bin/sed -f
6 #!/usr/awk -f
上边每一个脚本头的行都指定了一个不同的命令解释器,如果是/bin/sh,那么就是默认 shell(在 Linux 系统中默认
是 Bash).[3]使用#!/bin/sh,在大多数商业发行的 UNIX 上,默认是 Bourne shell,这将让你的脚本可以正常的运行在
非 Linux 机器上,虽然这将会牺牲 Bash 一些独特的特征.脚本将与 POSIX[4] 的 sh 标准相一致.
注意: #! 后边给出的路径名必须是正确的,否则将会出现一个错误消息,通常是"Command not found",这将是你运
行这个脚本时所得到的唯一结果.当然"#!"也可以被忽略,不过这样你的脚本文件就只能是一些命令的集合,不能够
使用 shell 内建的指令了,如果不能使用变量的话,当然这也就失去了脚本编程的意义了.
注意:这个例子鼓励你使用模块化的方式来编写脚本,平时也要注意收集一些零碎的代码,这些零碎的代码可能用
在你将来编写的脚本中.这样你就可以通过这些代码片段来构造一个较大的工程用例. 以下边脚本作为序,来测试
脚本被调用的参数是否正确.
################################Start Script#######################################
1 E_WRONG_ARGS=65
2 script_parameters="-a -h -m -z"
3 # -a = all, -h = help, 等等.
4
5 if [ $# -ne $Number_of_expected_args ]
6 then
7 echo "Usage: `basename $0` $script_parameters"
8 # `basename $0`是这个脚本的文件名
9 exit $E_WRONG_ARGS
10 fi
################################End Script#########################################
大多数情况下,你需要编写一个脚本来执行一个特定的任务,在本章中第一个脚本就是一个这样的例子, 然后你会
修改它来完成一个不同的,但比较相似的任务.用变量来代替写死的常量,就是一个好方法,将重复的代码放到一个
函数中,也是一种好习惯.
2.1 调用一个脚本
编写完脚本后,你可以使用 sh scriptname,[5]或者 bash scriptname 来调用它.(不推荐使用 sh <scriptname,
因为这禁用了脚本从 stdin 中读数据的功能.)更方便的是让脚本本身就具有可执行权限,可通过 chmod 命令修改.
比如:
chmod 555 scriptname (允许任何人都具有 可读和执行权限) [6]
或:
chmod +rx scriptname (允许任何人都具有 可读和执行权限)
chmod u+rx scriptname (只给脚本的所有者 可读和执行权限)
既然脚本已经具有了可执行权限,现在你可以使用./scriptname.[7]来测试它了.如果这个脚本以一个"#!"行开头,那
Advance Bash Shell Guide
19
Good good study, day day up!!
么脚本将会调用合适的命令解释器来运行.
最后一步,在脚本被测试和 debug 之后,你可能想把它移动到/usr/local/bin(当然是以 root 身份),来让你的脚本
对所有用户都有用.这样用户就可以直接敲脚本名字来运行了.
注意事项:
[1] 那些具有 UNIX 味道的脚本(基于 4.2BSD)需要一个 4 字节的魔法数字,在#!后边需要一个
空格#! /bin/sh.
[2] 脚本中的#!行的最重要的任务就是命令解释器(sh 或者 bash).因为这行是以#开始的,
当命令解释器执行这个脚本的时候,会把它作为一个注释行.当然,在这之前,这行语句
已经完成了它的任务,就是调用命令解释器.
如果在脚本的里边还有一个#!行,那么 bash 将把它认为是一个一般的注释行.
1 #!/bin/bash
2
3 echo "Part 1 of script."
4 a=1
5
6 #!/bin/bash
7 # 这将不会开始一个新脚本.
8
9 echo "Part 2 of script."
10 echo $a # Value of $a stays at 1.
[3] 这里可以玩一些小技巧.
1 #!/bin/rm
2 # 自删除脚本.
3
4 # 当你运行这个脚本时,基本上什么都不会发生...除非这个文件消失不见.
5
6 WHATEVER=65
7
8 echo "This line will never print (betcha!)."
9
10 exit $WHATEVER # 没关系,脚本是不会在这退出的.
当然,你还可以试试在一个 README 文件的开头加上#!/bin/more,并让它具有执行权限.结果将是文档自
动列出自己的内容.(一个使用 cat 命令的 here document 可能是一个更好的选则,--见 Example 17-3).
[4] 可移植的操作系统接口,标准化类 UNIX 操作系统的一种尝试.POSIX 规范可以在
http://www.opengroup.org/onlinepubs/007904975/toc.htm 中查阅.
[5] 小心:使用 sh scriptname 来调用脚本的时候将会关闭一些 Bash 特定的扩展,脚本可能因此而调用失败.
[6] 脚本需要读和执行权限,因为 shell 需要读这个脚本.
[7] 为什么不直接使用 scriptname来调用脚本?如果你当前的目录下($PWD)正好有你想要执行的脚本,为什
么它运行不了呢?失败的原因是,出于安全考虑,当前目录并没有被加在用户的$PATH 变量中.因此,在当
前目录下调用脚本必须使用./scriptname 这种形式.
2.2 初步的练习
1. 系统管理员经常会为了自动化一些常用的任务而编写脚本.举出几个这种有用的脚本的实例.
2. 编写一个脚本,显示时间和日期,列出所有的登录用户,显示系统的更新时间.然后这个脚本将会把这些内容保存
到一个 log file 中.
Advance Bash Shell Guide
20
Good good study, day day up!!
第二部分 基本
++++++++++++++++
第 3 章 特殊字符
================
# 注释,行首以#开头为注释(#!是个例外).
1 # This line is a comment.
注释也可以存在于本行命令的后边.
1 echo "A comment will follow." # 注释在这里
2 # ^ 注意#前边的空白
注释也可以在本行空白的后边.
1 # A tab precedes this comment.
注意:命令是不能跟在同一行上注释的后边的,没有办法,在同一行上,注释的后边想要再使用命令,只能另
起一行.当然,在 echo 命令中被转义的#是不能作为注释的. 同样的,#也可以出现在特定的参数替换结构
中或者是数字常量表达式中.
1 echo "The # here does not begin a comment."
2 echo 'The # here does not begin a comment.'
3 echo The \# here does not begin a comment.
4 echo The # 这里开始一个注释
5
6 echo ${PATH#*:} # 参数替换,不是一个注释
7 echo $(( 2#101011 )) # 数制转换,不是一个注释
8
9 # Thanks, S.C.
标准的引用和转义字符("'\)可以用来转义#
; 命令分隔符,可以用来在一行中来写多个命令.
1 echo hello; echo there
2
3
4 if [ -x "$filename" ]; then # 注意:"if"和"then"需要分隔
5 # 为啥?
6 echo "File $filename exists."; cp $filename $filename.bak
7 else
8 echo "File $filename not found."; touch $filename
9 fi; echo "File test complete."
有时候需要转义
;; 终止"case"选项.
1 case "$variable" in
2 abc) echo "\$variable = abc" ;;
剩余544页未读,继续阅读
chokko乔
- 粉丝: 0
- 资源: 3
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- C语言快速排序算法的实现与应用
- KityFormula 编辑器压缩包功能解析
- 离线搭建Kubernetes 1.17.0集群教程与资源包分享
- Java毕业设计教学平台完整教程与源码
- 综合数据集汇总:浏览记录与市场研究分析
- STM32智能家居控制系统:创新设计与无线通讯
- 深入浅出C++20标准:四大新特性解析
- Real-ESRGAN: 开源项目提升图像超分辨率技术
- 植物大战僵尸杂交版v2.0.88:新元素新挑战
- 掌握数据分析核心模型,预测未来不是梦
- Android平台蓝牙HC-06/08模块数据交互技巧
- Python源码分享:计算100至200之间的所有素数
- 免费视频修复利器:Digital Video Repair
- Chrome浏览器新版本Adblock Plus插件发布
- GifSplitter:Linux下GIF转BMP的核心工具
- Vue.js开发教程:全面学习资源指南
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功