UNIX/Linux系统管理技术手册-读书笔记-第七章
《UNIX/Linux系统管理技术手册-读书笔记-第七章
脚本编程与shell
1. 脚本化的哲学
| 原则 | 说明 | 能做什么 |
|---|---|---|
| 编写微型脚本(scriptlet) | 不为大型任务才写脚本,日常小痛点也用脚本解决 | 积累个人工具库(~/bin),提升日常效率 |
| 学好少数核心工具 | shell、文本编辑器、脚本语言应全面掌握 | 核心工具熟练度直接影响整体效率 |
| 全面自动化 | 不限于shell,办公软件、数据库、GUI应用都可脚本化 | 将重复操作自动化,降低出错率 |
| 不要过早优化 | 脚本优先考虑程序员效率和代码清晰,而非计算效率 | 快速交付可用脚本,避免过度工程化 |
| 拣选正确的脚本语言 | sh(轻量/可移植)、Python(通用首选)、Ruby(Web/DSL) | 根据任务选语言,避免用错工具 |
语言选择建议:
- 新项目首选Python 3(通用性最强、生态最广)
- 简单命令序列用Bash/sh(系统自带,可移植)
- 避免在新工作中使用Perl(已老态),PHP/JavaScript不适合系统管理
2. shell基础(Bash/sh)
2.1 命令行编辑
| 快捷键 | 功能 |
|---|---|
Ctrl+A / Ctrl+E |
行首/行尾 |
Ctrl+P / Ctrl+N |
上一条/下一条命令 |
Ctrl+R |
反向搜索历史 |
set -o vi |
启用vi模式(按Esc进入命令模式) |
2.2 管道与重定向
| 符号 | 功能 | 示例 |
|---|---|---|
< |
标准输入重定向 | sort < /etc/passwd |
> |
标准输出重定向(覆盖) | grep bash /etc/passwd > bash_users |
>> |
标准输出重定向(追加) | echo "new" >> file |
2> |
标准错误重定向 | find / -name core 2> /dev/null |
>& |
合并STDOUT和STDERR | cmd >& /tmp/out |
| |
管道(连接命令) | ps -ef | grep httpd |
&& |
前命令成功则执行后命令 | mkdir foo && cd foo |
|| |
前命令失败则执行后命令 | cd foo || echo "No such dir" |
; |
顺序执行(无关成败) | mkdir foo; cd foo; touch a |
文件描述符:STDIN=0,STDOUT=1,STDERR=2。
2.3 变量与引用
| 用法 | 示例 | 说明 |
|---|---|---|
| 赋值(无空格) | etcdir=/etc |
等号两边不能有空格 |
| 引用($前缀) | echo $etcdir |
|
| 花括号分隔 | echo "Saved ${rev}th" |
防止变量名与后续字符混淆 |
| 双引号 | echo "I speak $mylang" |
允许变量扩展 |
| 单引号 | echo 'I speak $mylang' |
禁止变量扩展 |
| 反引号(命令替换) | echo "Lines: \wc -l < /etc/passwd`"` |
执行命令并替换输出(推荐用$(...)替代) |
2.4 常用过滤命令
| 命令 | 功能 | 常用选项 |
|---|---|---|
cut |
提取列/字段 | -d: -f7(分隔符:第7字段) |
sort |
排序 | -n数值,-h人类可读,-k指定键,-u去重 |
uniq |
去重(需先排序) | -c计数,-d仅重复行 |
wc |
统计行/词/字符 | -l仅行数,-w仅词数 |
tee |
分流输出 | find ... | tee /dev/tty | wc -l |
head / tail |
头/尾几行 | -n 20;tail -f实时监视日志 |
grep |
文本搜索 | -i忽略大小写,-v反向匹配,-l仅文件名 |
3. sh脚本编程
3.1 脚本基本结构
执行方式:
chmod +x script && ./scriptsh scriptsource script(在当前shell中执行,用于设置环境变量)
3.2 输入与输出
3.3 命令行参数
| 变量 | 含义 |
|---|---|
$0 |
脚本名 |
$1, $2, ... |
第1、2…个参数 |
$# |
参数个数(不含$0) |
$@ / $* |
所有参数(作为列表/字符串) |
$? |
上一条命令的退出码 |
函数定义:
3.4 控制流程
if语句:
数值比较(使用-eq、-ne、-lt、-le、-gt、-ge):
字符串比较(使用=、!=、-z为空、-n非空):
文件测试:
case语句:
for循环:
while循环(读文件常用):
算术运算(Bash):
3.5 文件名中的空格处理
4. 正则表达式(核心元字符)
| 符号 | 含义 | 示例 |
|---|---|---|
. |
任意单个字符 | a.c匹配"abc" |
[chars] |
字符集合 | [aeiou]匹配任意元音 |
[^chars] |
排除字符集合 | [^0-9]匹配非数字 |
^ |
行首 | ^root匹配以root开头的行 |
$ |
行尾 | bash$匹配以bash结尾的行 |
\w |
单词字符 | [A-Za-z0-9_] |
\s |
空白字符 | 空格、Tab等 |
\d |
数字 | [0-9] |
| |
或 | (walrus|egg man) |
(expr) |
分组+捕获 | (\d{5})捕获5位数字 |
? |
0次或1次 | colou?r匹配"color"/“colour” |
* |
0次或多次 | a*b匹配"b",“ab”,“aab”… |
+ |
1次或多次 | a+b匹配"ab",“aab”… |
{n} |
精确n次 | \d{5}匹配5位数字 |
{min,max} |
min~max次 | \d{3,5}匹配3~5位数字 |
贪婪 vs 惰性:
.*贪婪:尽可能多匹配(可能造成灾难性回溯).*?惰性:尽可能少匹配- 最佳实践:能用具体字符类(如
[^>]*)就不用.*
5. Python编程(系统管理员首选)
5.1 Python 2 vs Python 3
- 新项目直接用Python 3(
/usr/bin/python3) - 现有代码沿用其原版本
- 大多数系统默认
python指向Python 2,但趋势是Python 3
5.2 快速入门
|
|
5.3 缩进规则(核心特性)
- 缩进级别决定代码块,不用花括号
- 绝不要混用制表符和空格(建议4空格缩进)
- 行尾冒号表示后续缩进块开始
5.4 常用语法
|
|
5.5 正则表达式(re模块)
6. Ruby编程
6.1 快速对比
| 特性 | Python | Ruby |
|---|---|---|
| 代码块界定 | 缩进 | do...end 或 {...} |
| 字符串插值 | f"{var}"(3.6+)或 %s |
"#{var}" |
| 一切皆对象 | ✅ | ✅(更纯粹) |
| 方法括号 | 必须 | 可选 |
| DSL能力 | 一般 | 强(如Chef/Puppet) |
| Web框架 | Django/Flask | Rails |
6.2 快速入门
6.3 命令行单行模式
7. Python/Ruby环境管理
7.1 包管理
| 语言 | 包管理器 | 安装 | 搜索 | 导出依赖 |
|---|---|---|---|---|
| Python | pip |
pip install package |
pip search keyword |
pip freeze > req.txt |
| Ruby | gem |
gem install package |
gem search regex |
gem list |
7.2 Python虚拟环境(virtualenv)
7.3 Ruby环境管理(Bundler + RVM)
Bundler(项目级依赖):
RVM(多Ruby版本管理):
8. Git版本控制
8.1 核心命令
|
|
8.2 关键概念
| 概念 | 说明 |
|---|---|
.git |
仓库元数据目录(不要删) |
| 索引(stage) | 待提交文件的暂存区 |
| 提交(commit) | 仓库中的一个版本快照 |
| master | 默认主分支 |
| HEAD | 当前分支的最新提交 |
8.3 Git社会化编程(GitHub/GitLab)
| 概念 | 说明 |
|---|---|
| fork | 仓库的个人副本 |
| pull request | 请求将分支变更合并到主仓库 |
| master分支 | 通常为稳定主线 |
| GitFlow | 广泛使用的分支管理模型 |
安全警告:
- Git不跟踪文件所有权和权限(仅可执行位)
- 绝不要把密码/密钥提交到Git仓库
- 适合跟踪:脚本、配置文件模板、文档、代码
9. 本章核心命令速查表
| 命令/概念 | 用途 |
|---|---|
chmod +x script |
使脚本可执行 |
./script / sh script |
执行脚本 |
source script |
在当前shell中执行(环境变量) |
cut -d: -f7 /etc/passwd |
提取passwd第7字段(shell) |
sort -nk3 -t: /etc/group |
按GID排序 |
uniq -c |
统计重复行 |
grep -i pattern file |
搜索(忽略大小写) |
tail -f /var/log/syslog |
实时监视日志 |
find . -print0 | xargs -0 |
处理含空格的文件名 |
python3 script.py |
执行Python3脚本 |
ruby script.rb |
执行Ruby脚本 |
pip install virtualenv |
安装Python虚拟环境 |
virtualenv venv && source venv/bin/activate |
创建并激活Python虚拟环境 |
gem install bundler |
安装Ruby依赖管理器 |
bundle install |
安装项目依赖 |
git init / add / commit |
Git基础命令链 |
git status / diff / log |
查看仓库状态 |
DBA视角补充:
- 脚本能力是DBA进阶运维的关键:备份脚本、巡检脚本、数据迁移脚本都离不开shell/Python。
- 环境管理尤为重要:同一台服务器可能有多个数据库版本(如MySQL 5.7和8.0)及其依赖的Python库,用
virtualenv隔离各工具环境,避免冲突。- Git管理SQL脚本:所有DDL、存储过程、迁移脚本都应纳入Git版本控制,配合CI/CD实现自动化数据库变更。
- 正则表达式在日志分析中高频使用:如从慢查询日志提取SQL,从错误日志提取特定错误码。
- 避免在生产库上直接测试脚本:先在测试环境验证,再用
cron/systemd timer调度,逐步推进到生产。
文章作者 会写代码的小郎中
上次更新 2011-06-17
许可协议 CC BY-NC-ND 4.0