Linux
文件权限
setuid — 为文件授予特殊权限,当用户运行该文件时可以使用所有者权限
chown –授予文件或目录权限
4 读 2写 1执行
chgrp 更改目录组
umask 预先设置屏蔽位,设置权限时会减去umask的值
sgid 将权限提升至目录所属组,新文件会强制继承组 chown filename 2775 2为sgid的标识符
find和xargs
find
find 路径 匹配条件 执行动作
-name 按后缀名称匹配
-perm 按权限匹配
-group 按组名搜索
-nouser,-nogroup 查找无有效属主/组文件
-mtime 按修改时间
-newer 查找比指定文件更新的文件
-type 按文件类型搜索
-size 按文件大小搜索
xargs
xargs主要是接受上一段指令拿到的结果作为参数
find 。-name “.tmp” | xargs rm -f
后台执行命令
cron
cron 周期性运行任务
crontab 用来自定义周期任务
at
在指定时间运行一次性任务
&
&将命令放入后台执行,不占用终端
nohup
用户退出后仍保持进程运行,适用于持久化任务
文件名置换总结
*匹配任意字符串
?匹配单个字符
[…]匹配括号内任一字符
[!…]匹配不在括号内的字符
shell输出与输入
一、核心概念与命令
-
标准输入/输出/错误 • 标准输入(stdin):文件描述符为
0,默认来源是键盘。• 标准输出(stdout):文件描述符为
1,默认输出到屏幕。• 标准错误(stderr):文件描述符为
2,默认输出到屏幕,用于错误信息。 -
重定向 通过符号改变输入/输出的来源或目标: •
>:覆盖输出到文件(如command > file)。•
>>:追加输出到文件(如command >> file)。•
2>:重定向标准错误(如command 2> error.log)。•
&>或>&:合并标准输出和错误(如command &> output.log)。
二、关键命令详解
-
echo• 功能:显示文本或变量,支持转义字符。• 选项:
◦
-e:启用转义(如\n换行,\t制表符)。◦
-n:禁止末尾换行(如echo -n "Enter name: ")。• 示例:
echo "Hello\nWorld" # 输出两行(需 -e) echo -e "Path: \$PATH" # 显示变量,转义 $ echo "Message" > file.txt # 输出到文件 -
read• 功能:从标准输入读取数据,赋值给变量。• 用法:
◦ 单变量读取全部输入:
read var。◦ 多变量按空格分隔:
read var1 var2,多余内容赋给最后一个变量。• 示例:
read name # 输入 "Alice Bob",name="Alice Bob" read first last # 输入 "Alice Bob",first="Alice", last="Bob" -
cat• 功能:显示文件内容、创建文件或合并文件。• 选项:
◦
-v:显示控制字符(如^M)。• 示例:
cat file.txt # 显示文件内容 cat file1 file2 > merged # 合并文件 cat > newfile <<EOF # 交互式创建文件 -
管道
|• 功能:将前一个命令的输出作为后一个命令的输入。• 示例:
ls | grep ".txt" # 列出所有.txt文件 who | awk '{print $1}' # 提取登录用户名 -
tee• 功能:将输入同时输出到屏幕和文件。• 选项:
◦
-a:追加而非覆盖。• 示例:
ls | tee files.log # 显示并保存结果 command | tee -a log.txt # 追加到日志
三、高级重定向技巧
-
合并标准输出与错误
command > output.log 2>&1 # 覆盖写入 command &>> output.log # 追加写入(等效于 >> output.log 2>&1) -
输入重定向与 Here Document
sort < input.txt # 从文件读取输入 mail user <<END # 多行输入直到END Hello, this is a message. END -
文件描述符操作 • 自定义描述符(3-9):
exec 3< input.txt # 打开文件描述符3读取 read -u 3 line # 从描述符3读取 exec 3<&- # 关闭描述符3
四、特殊场景处理
-
错误处理 • 忽略错误:
command 2> /dev/null。• 分离输出与错误:
command > output.log 2> error.log -
exec命令 • 替换当前Shell:exec new_command。• 操作文件描述符:
exec 4>&1 # 保存标准输出到描述符4 exec 1> log.txt # 重定向标准输出到文件 echo "Logging..." # 输出到log.txt exec 1>&4 # 恢复标准输出
五、注意事项与技巧
• 转义字符:在echo中需用 -e 启用(Linux),双引号需转义:echo "\"Hello\""。
• 输入分隔:read 按空格分割变量,多余内容合并到末变量。
• 管道链:可串联多个命令,如 df | awk '{print $1}' | grep -v "Filesystem"。
六、总结图表
| 操作 | 命令示例 | 说明 |
|---|---|---|
| 输出重定向 | echo "text" > file |
覆盖写入文件 |
| 追加输出 | echo "text" >> file |
追加到文件末尾 |
| 错误重定向 | command 2> error.log |
保存错误信息 |
| 合并输出与错误 | command &> output.log |
输出和错误写入同一文件 |
| 多行输入(Here Doc) | cat <<EOF > file |
交互式输入直到EOF |
| 管道 | ls | grep ".txt" |
|
| 同时输出与保存 | ls | tee files.log |
第6章命令执行顺序总结
核心内容
本章重点讲解如何根据前序命令的执行结果(成功或失败)控制后续命令的执行逻辑,通过操作符和命令组合实现条件化脚本流程。
一、逻辑控制操作符:&& 和 ||
-
&&(逻辑与)-
功能:前序命令成功(退出状态码为0),才执行后续命令。
-
语法:
命令1 && 命令2 -
应用场景
:
-
确保关键步骤成功后再执行后续操作。
-
示例:
bash
复制
cp file.txt backup/ && echo "备份成功" # 拷贝成功才输出提示 sort data.txt > sorted.txt && lp sorted.txt # 排序成功再打印
-
-
-
||(逻辑或)-
功能:前序命令失败(退出状态码非0),才执行后续命令。
-
语法:
命令1 || 命令2 -
应用场景
:
-
错误处理或备用方案触发。
-
示例:
bash
复制
comet script.sh || (echo "脚本执行失败" | mail admin; exit 1) # 失败则发邮件并退出
-
-
二、命令组合:() 与 {}
-
圆括号
():子Shell执行-
功能:在子Shell中执行组合命令,环境变量修改不影响当前Shell。
-
语法:
(命令1; 命令2; ...) -
示例
:
bash
复制
(cd /tmp; ls) # 子Shell中切换目录并列出文件,当前目录不变
-
-
花括号
{}:当前Shell执行-
功能:在当前Shell中执行组合命令,需注意格式(空格和分号)。
-
语法:
{ 命令1; 命令2; ...; } -
示例
:
bash
复制
{ echo "开始时间: $(date)"; sort data.txt; echo "结束时间: $(date)"; } > log.txt # 记录命令执行时间到日志
-
三、组合命令与逻辑控制结合
-
复杂条件执行
-
通过组合命令和逻辑操作符,实现多步骤条件控制。
-
示例
:
bash
复制
sort file.txt > sorted.txt && { cp sorted.txt /backup/ lp sorted.txt } || echo "排序失败,无法打印" | mail admin- 若排序成功,则备份并打印;失败则发邮件通知。
-
-
错误处理链
-
结合多个
&&和||构建健壮的流程。 -
make build && make test || { echo "编译或测试失败"; exit 1 }
-
四、关键注意事项
-
退出状态码
- 每个命令的退出状态码决定逻辑操作符的行为,组合命令的退出码为最后一个命令的结果。
-
子Shell与当前Shell的影响
-
()中的变量修改不影响当前Shell,{}中的修改会保留。 -
(a=1; echo $a) # 输出1,但当前Shell中a未定义 { a=1; echo $a; } # 输出1,且当前Shell中a=1
-
-
格式规范
{}需内部命令以分号结尾,且括号与命令间有空格。- 错误示例:
{ cmd1 cmd2 }→ 正确写法:{ cmd1; cmd2; }
五、应用总结
- 脚本健壮性:通过条件执行避免数据丢失或无效操作(如删除前确认备份成功)。
- 错误处理:及时通知失败并终止流程(如
||结合exit)。 - 复杂流程:组合命令实现多任务原子操作(如日志记录、资源清理)。
通过灵活使用&&、||和命令组合,可编写出高效、安全的Shell脚本,精确控制命令执行顺序和错误处理逻辑。
正则表达式核心总结
一、正则表达式简介
正则表达式(RE)是用于文本匹配的强大工具,通过元字符组合描述字符串模式,广泛应用于UNIX/Linux环境中的文本过滤(如grep、sed、awk)。
二、基本元字符及用法
-
行首与行尾匹配 •
^:匹配行首。◦ 例:
^d匹配以d开头的行(如drwxrwxrw-)。•
$:匹配行尾。◦ 例:
trouble$匹配以trouble结尾的行;^$匹配空行。 -
通配符 •
.:匹配任意单个字符。◦ 例:
beg.n可匹配begin、beg3n等。 -
重复匹配 •
*:匹配前一个字符的零次或多次出现。◦ 例:
compu*t匹配computer、compuuuut等。•
{}:精确控制重复次数(需转义\)。◦
pattern\{n\}:恰好出现n次(例:A\{2\}匹配AA)。◦
pattern\{n,\}:至少出现n次(例:A\{4,\}匹配AAAA或AAAAA)。◦
pattern\{n,m\}:出现n到m次(例:A\{2,4\}匹配AA、AAA、AAAA)。 -
字符集 •
[]:匹配括号内任意单个字符,支持范围表示(如[0-9])。◦ 例:
[Cc]omputer匹配Computer或computer;[^0-9]匹配非数字字符。 -
转义符 •
\:屏蔽元字符的特殊含义。◦ 例:
\.匹配字面句点;\*匹配字面*。
三、常见匹配模式示例
| 模式 | 含义 | 示例匹配 |
|---|---|---|
^[the] |
以t、h或e开头的行 |
the start |
[Ss]ystem\. |
匹配System.或system. |
System.、system. |
^[A-Za-z]*$ |
仅包含字母的行 | Hello |
[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\} |
日期格式YYYY-MM-DD |
2023-10-05 |
[0-9]\{3\}\.[0-9]\{3\}\.[0-9]\{3\}\.[0-9]\{3\} |
IP地址格式(nnn.nnn.nnn.nnn) |
192.168.1.1 |
^d..x..x..x |
具有可执行权限的目录(drwxr-xr-x) |
drwxr-xr-x |
[ou].*t |
以o或u开头、t结尾的单词(如shout) |
shout、bought |
四、高级技巧与注意事项
- 组合使用元字符 • 例:
^...1匹配行首第4个字符为1的字符串(如0011XA9912)。 - 排除匹配 • 使用
[^]排除字符。例:[^a-z]匹配非小写字母。 - 特殊字符转义 • 需转义的字符包括:
$、.、*、[、]、^、\等。例:\$\$匹配字面$$。 - 匹配任意字符串 •
.*表示匹配零个或多个任意字符(贪婪匹配)。
五、应用场景
正则表达式在以下场景中尤为关键:
- 过滤日志:提取特定格式的日志行(如时间戳、错误代码)。
- 验证输入格式:检查日期、邮箱、IP地址等合法性。
- 批量文本处理:使用
sed替换文本,awk提取字段,grep搜索模式。
通过掌握这些元字符和模式,可以高效处理复杂的文本匹配任务,为后续学习grep、sed和awk等工具打下基础。
第8章 grep家族详细总结
一、grep家族概述
grep是UNIX/Linux中用于文本模式匹配的核心工具,包含三种变形:
- grep:支持基本正则表达式(BRE),用于快速模式查找。
- egrep(扩展grep):支持扩展正则表达式(ERE),提供更灵活的模式匹配(如
|多选分支)。 - fgrep(快速grep):仅匹配固定字符串,适合无正则表达式的快速搜索。
注意:GNU grep整合了三者功能,但需通过选项(如 -E、-F)切换模式。
二、grep基础用法
- 命令格式
bash
复制
grep [选项] "模式" [文件]
- 关键选项 • -c:统计匹配行数。
• -i:忽略大小写。
• -n:显示匹配行及其行号。
• -v:反向匹配(显示不包含模式的行)。
• -l/-L:仅输出包含/不包含模式的文件名。
• -h:多文件搜索时不显示文件名。
• -s:静默模式(抑制错误信息)。
- 引号使用规则 • 双引号:包裹含空格或变量的模式(如
grep "$VAR" file)。
• 单引号:包裹含正则元字符的模式(如 grep '^start' file)。
- 多文件搜索
bash
复制
grep "pattern" *.txt # 当前目录所有.txt文件
grep "sort it" * # 所有文件中匹配"sort it"
三、正则表达式技巧
- 精确匹配 • 单词边界:使用
\<和\>(或\b)。
bash
复制
grep '\<48\>' data.f # 精确匹配"48"而非"483"
- 行首/行尾匹配 •
^匹配行首,$匹配行尾。
bash
复制
grep '^48' data.f # 行首为48的行
grep 'end$' file # 行尾为"end"的行
- 字符范围与类 • 范围:
[0-9]匹配数字,[A-Za-z]匹配字母。
• 预定义类名(需双括号):
bash
复制
grep '[[:upper:]]' file # 匹配大写字母(等价[A-Z])
grep '5[[:upper:]]\{2\}' data.f # 5后跟两个大写字母(如5AP)
- 重复与次数 •
\{n\}精确重复n次,\{n,\}至少n次,\{n,m\}重复n到m次。
bash
复制
grep '9\{3\}' data.f # 匹配"999"
grep '8\{2,6\}3' file # 8重复2-6次后接3(如8883)
- 特殊字符转义 • 使用
\转义.、*、$等元字符。
bash
复制
grep '\.' file # 匹配含句点的行
四、高级应用案例
- 日期与IP匹配 • 日期格式(如YYYY或年份末两位):
bash
复制
grep '199[68]' data.f # 匹配1996或1998
• IP地址匹配:
bash
复制
grep '[0-9]\{3\}\.[0-9]\{3\}\.' ipfile # 匹配nnn.nnn.格式的IP
- 结合系统命令 • 查找进程:
bash
复制
ps ax | grep 'named' | grep -v "grep" # 排除grep自身进程
• 用户查询:
bash
复制
who | egrep 'louise|pauline' # 匹配多个用户
- 多模式文件(egrep -f) • 创建模式文件
grep_patterns.txt:
plaintext
复制
484
47
• 执行多模式搜索:
bash
复制
egrep -f grep_patterns.txt data.f
五、egrep扩展功能
• 多选分支 |:
bash
复制
egrep '(3ZL|2CC)' data.f # 匹配3ZL或2CC
• 可选字符 ?:
bash
复制
egrep 'reboot(s)?' * # 匹配"reboot"或"reboots"
六、实用场景总结
- 日志分析:快速定位错误信息(如
grep "ERROR" app.log)。 - 配置检查:搜索配置文件中的参数(如
grep "Port" /etc/ssh/sshd_config)。 - 数据清洗:提取特定格式数据(如IP、日期)。
- 进程管理:结合
ps监控服务状态。 - 用户管理:在
/etc/passwd中查找用户信息。
七、注意事项
• 性能:避免过于宽泛的模式(如 .*),优先精确匹配。
• 跨平台差异:不同系统(如BSD/macOS与Linux)的grep选项可能不同。
• 正则表达式类型:明确使用BRE(默认)或ERE(-E),避免语法混淆。
通过灵活结合grep家族与正则表达式,可高效处理文本处理任务,成为Shell脚本和日常系统管理的利器。
AWK 第9章内容总结
1. AWK简介
• 用途:AWK是一种强大的文本处理工具,适用于格式化报文、抽取数据,擅长文本浏览和数据操作。
• 特点:语法较复杂,但结合grep、sed等工具可提升Shell编程效率。支持自解释的编程语言特性。
2. 调用AWK的方式
• 命令行调用:
bash
复制
awk [-F 分隔符] '命令' 输入文件
• -F指定域分隔符(默认空格)。
• 示例:处理passwd文件(冒号分隔):
```bash
awk -F: 'commands' /etc/passwd
```
• 脚本文件调用:
• 将AWK命令写入文件,首行添加#!/bin/awk -f,赋予执行权限后直接运行。
• 或通过-f选项指定脚本:
```bash
awk -f 脚本文件 输入文件
```
3. AWK脚本结构
• 模式与动作:
• 模式:条件语句或正则表达式,决定何时触发动作。特殊模式BEGIN(处理前执行)和END(处理后执行)。
• 动作:用{}包裹的操作,如打印、计算等。若省略模式,默认处理所有行。
• 示例:打印表头和表尾:
```bash
awk 'BEGIN{print "Header"} {print $0} END{print "Footer"}' file.txt
```
4. 域与记录处理
• 域(Field):默认以空格分隔,通过$1, $2, ..., $n访问。$0表示整条记录。
• 记录(Record):默认以换行符分隔,可通过内置变量RS修改。
• 示例:
• 提取名字和级别(第1、4域):
```bash
awk '{print $1, $4}' grade.txt
```
• 添加表头和Tab分隔:
```bash
awk 'BEGIN{print "Name\tBelt"} {print $1 "\t" $4}' grade.txt
```
5. 正则表达式与条件操作
• 正则匹配:
• 使用~匹配正则,!~不匹配。
• 示例:匹配级别包含Brown的记录:
```bash
awk '$4 ~ /Brown/ {print $0}' grade.txt
```
• 条件操作符:
• 比较:<, <=, ==, !=, >=, >。
• 逻辑:&&(与)、||(或)、!(非)。
• 示例:查找年龄小于10岁的学生:
```bash
awk '$5 < 10' grade.txt
```
6. 内置变量
| 变量 | 描述 |
|---|---|
NR |
已读记录数(行号) |
NF |
当前记录的域个数 |
FS |
输入域分隔符(默认空格) |
OFS |
输出域分隔符(默认空格) |
FILENAME |
当前处理的文件名 |
RS |
记录分隔符(默认换行) |
• 示例:
• 统计文件行数:
```bash
awk 'END{print NR}' grade.txt
```
• 显示文件名和每行域数:
```bash
awk '{print FILENAME, NR, NF}' grade.txt
```
7. 字符串处理函数
• 常用函数:
• gsub(r,s):全局替换正则r为s。
• index(s,t):返回子串t在s中的位置。
• length(s):返回字符串长度。
• split(s,a,sep):按sep分割s到数组a。
• substr(s,p,n):从位置p提取长度为n的子串。
• 示例:
• 替换文本中的数字:
```bash
awk '{gsub(/48/, "49"); print $0}' grade.txt
```
• 提取子串:
```bash
awk '{print substr($1, 3, 5)}' grade.txt # 提取第1域第3字符后的5个字符
```
8. 格式化输出(printf)
• 格式控制符:
• %s(字符串)、%d(整数)、%f(浮点数)、%c(字符)等。
• 修饰符:-(左对齐)、宽度、.精度。
• 示例:
bash
复制
awk '{printf "%-15s %10d\n", $1, $6}' grade.txt # 左对齐名字,右对齐分数
9. 数组应用
• 数组操作:
• 无需预先声明,自动创建。
• 遍历数组:for (key in array) print array[key]。
• 示例:
• 统计不同级别的数量:
```bash
awk -F# '{color[$1]++} END{for (c in color) print c, color[c]}' data.txt
```
• 分割字符串到数组:
```bash
awk '{split($0, arr, "#"); print arr[1]}' input.txt
```
10. 实际应用案例 • 统计学生总分:
bash
复制
awk '{sum += $6} END{print "总分:", sum}' grade.txt
• 分析系统磁盘空间:
bash
复制
df -k | awk '$4 < 50000 {print $6 " 空间不足: " $4}'
• 处理passwd文件:
bash
复制
awk -F: '{print "用户:" $1, "UID:" $3}' /etc/passwd
11. 错误处理与调试 • 常见错误:
• 引号不匹配、括号缺失、域编号错误。
• 错误示例:awk: cmd. line:1: unterminated string(未闭合字符串)。
• 调试技巧:
• 使用print语句输出中间变量。
• 通过tee命令同时输出到屏幕和文件:
```bash
awk '{print $0}' grade.txt | tee output.txt
```
总结 AWK的核心功能在于灵活处理结构化文本,通过模式匹配、域操作、内置函数和数组实现复杂的数据处理任务。掌握其基本语法(如模式-动作结构、正则表达式、内置变量)后,可高效完成日志分析、数据统计、格式化输出等需求。结合Shell脚本与其他工具(如sed、grep),能进一步提升文本处理能力。
第10章 sed用法详解总结
一、sed基础概念
-
非交互式文本编辑器 • 操作文件或标准输入(键盘、重定向、管道等)的文本拷贝,不直接修改原文件。
• 适合自动化处理,一次性处理所有修改,效率高。
• 与Vi不同,无需用户交互,适用于脚本化任务。
-
核心功能 • 文本抽取、正则表达式匹配、域比较、增删改操作。
• 支持行号或正则表达式定位文本,支持多命令组合。
二、调用sed的三种方式
-
命令行直接调用
bash
复制
sed [选项] '命令' 输入文件• 命令需用单引号包裹,如
sed 's/old/new/' file.txt。 -
脚本文件调用
bash
复制
sed -f 脚本文件 输入文件• 脚本文件中写入sed命令,如
#!/bin/sed -f /pattern/d。 -
可执行脚本 • 脚本首行指定解释器:
#!/bin/sed -f,赋予执行权限后直接运行。
三、常用选项
• -n:抑制默认输出(仅打印明确指定的行)。
• -e:允许多个编辑命令,如 sed -e 's/a/A/' -e 's/b/B/'。
• -f:指定包含sed命令的脚本文件。
• -i(未提及但常用):直接修改文件(注意备份)。
四、文本定位与基本命令
-
定位方式 • 行号:
x(单行)、x,y(范围)、$(最后一行)。• 正则表达式:
/pattern/或混合模式如3,/pattern/(第3行到匹配行)。 -
基本命令
命令 功能 示例 p打印行 sed -n '2p' file(打印第2行)d删除行 sed '1,3d' file(删除1-3行)a\行后追加 sed '/pattern/a\新文本' filei\行前插入 sed '3i\新文本' filec\替换行 sed '/pattern/c\新行' files替换文本 sed 's/old/new/g' file(全局替换)r读取文件插入 sed '/pattern/r other.txt' filew写入文件 sed '/pattern/w output.txt' file
五、正则表达式应用
-
元字符处理 • 需转义特殊字符,如
\$表示$,\.匹配句点。• 示例:
sed -n '/\$/p' file(匹配含$的行)。 -
模式匹配 • 任意字符:
.*(如.*ing匹配以ing结尾的单词)。• 行首/行尾:
^(行首)、$(行尾),如sed 's/^#//g'删除行首的#。
六、高级操作与脚本示例
-
多命令组合
bash
复制
sed -e 's/old/new/' -e '/pattern/d' file -
控制字符处理 • 显示控制字符:
sed -n 'l' file(显示如\033的八进制码)。• 删除行尾
^M:sed 's/^M//g' file(需输入实际控制符)。 -
文本转换示例 • 去除行首数字:
sed 's/^[0-9]*//' file。• 附加文本到行尾:
sed 's/$/ Passed/' file。• 替换路径分隔符:
echo "/usr/local" | sed 's/^\///'。
七、实用技巧与一行命令
-
快速处理 • 删除空行:
sed '/^$/d' file。• 压缩多个空格:
sed 's/ \+/ /g' file。• 删除行首空格:
sed 's/^ *//' file。 -
变量传递 • Shell变量传递到sed(双引号允许变量扩展):
bash
复制
REPLACE="NEW"; sed "s/OLD/$REPLACE/g" file -
结果保存与设置变量 • 保存输出:
sed 's/old/new/' file > output。• 设置Shell变量:
NEW=$(sed 's/old/new/' file)。
八、典型应用场景
-
日志处理 • 提取特定时间段日志:
sed -n '/2023-10-01 12:00/,/2023-10-01 13:00/p' log.txt。 -
数据清洗 • 删除控制字符、格式化CSV文件。
-
批量重命名 • 结合管道与循环,如批量修改文件名后缀:
bash
复制
ls *.txt | sed 's/\.txt$//' | xargs -I {} mv {}.txt {}.bak
九、注意事项
- 备份原文件:脚本处理前建议备份,避免误操作。
- 分步测试:复杂任务分解为多个步骤,逐步验证结果。
- 性能优化:避免在超大文件中使用全局替换(
g),优先指定范围。
通过本章学习,读者可掌握sed的核心功能,灵活运用其非交互式特性处理文本,结合正则表达式实现高效自动化操作。
第11章 合并与分割工具总结
1. sort:文本排序
用途:按指定规则对文件行排序,支持多域排序、数值排序、逆序等。 核心选项: • -c:检查文件是否已排序。
• -u:去除重复行(仅保留唯一行)。
• -n:按数值排序(避免按字符排序导致错误)。
• -r:逆序排序。
• -t:指定分隔符(如-t:表示冒号分隔)。
• -k:指定排序键(如-k3按第3域排序)。
• -o:指定输出文件。
示例: • 按第3域数值排序(冒号分隔):
bash
复制
sort -t: -k3n video.txt
• 合并已排序文件:
bash
复制
sort -m sorted1.txt sorted2.txt
• 检查文件是否排序:
bash
复制
sort -c video.txt && echo "已排序" || echo "未排序"
2. uniq:处理重复行
用途:过滤或统计连续重复行。 核心选项: • -u:仅显示不重复行。
• -d:仅显示重复行(每组显示一次)。
• -c:统计每行重复次数。
• -f N:忽略前N个域进行比较。
示例: • 统计重复次数:
bash
复制
uniq -c myfile.txt
• 显示重复行:
bash
复制
uniq -d myfile.txt
• 忽略前2域比较:
bash
复制
uniq -f2 data.txt
3. join:连接两个文件
用途:基于公共域合并两个已排序文件,类似SQL的JOIN操作。 核心选项: • -a N:显示第N个文件的不匹配行(如-a1显示文件1未匹配行)。
• -o:指定输出格式(如1.1,2.2输出文件1第1域和文件2第2域)。
• -t:指定分隔符(默认空格/Tab)。
• -j:指定连接域(如-j1 3 -j2 2连接文件1第3域和文件2第2域)。
示例: • 合并姓名和地址文件(冒号分隔):
bash
复制
join -t: names.txt town.txt
• 显示文件1未匹配行:
bash
复制
join -a1 names.txt town.txt
4. cut:剪切列或域
用途:从文件或输入中提取指定列或域。 核心选项: • -d:指定分隔符(如-d:)。
• -f:选择域(如-f1,3或-f1-3)。
• -c:按字符位置剪切(如-c1-5剪切前5字符)。
示例: • 提取/etc/passwd的用户名和家目录:
bash
复制
cut -d: -f1,6 /etc/passwd
• 剪切文件名中的特定字符:
bash
复制
ls *.log | cut -c4-6
5. paste:合并行
用途:水平合并多个文件的行,默认用Tab分隔。 核心选项: • -d:指定分隔符(如-d@用@分隔)。
• -s:将文件合并为单行(垂直转水平)。
示例: • 合并两列数据(冒号分隔):
bash
复制
paste -d: pas1.txt pas2.txt
• 将文件内容转为单行:
bash
复制
paste -s data.txt
6. split:分割大文件
用途:将大文件按行数或大小分割为小文件。 语法:
bash
复制
split [-l 行数] 输入文件 [输出前缀]
示例: • 每1000行分割文件:
bash
复制
split -l 1000 bigfile.txt part_
• 生成的文件名格式为part_aa, part_ab等。
关键注意事项
- 预处理:使用
join前需确保文件已排序;uniq仅处理连续重复行。 - 分隔符:明确使用
-t或-d指定分隔符(如-t:处理冒号分隔数据)。 - 数值排序:对数字列排序时务必用
-n,避免字符排序导致错误。 - 输出控制:灵活使用重定向(
>)和管道(|)组合工具(如sort | uniq -c)。
通过掌握这些工具,可高效处理文本数据的排序、合并、去重、分割等操作,提升数据处理效率。
第12章 tr 命令总结
1. 基本功能
tr(translate)用于从标准输入中通过替换或删除操作进行字符转换,主要功能包括:
- 字符替换:将字符串1中的字符映射到字符串2中的字符进行转换。
- 删除字符:使用
-d选项删除指定字符。 - 压缩重复字符:使用
-s选项将重复字符压缩为单个字符。
2. 命令格式
bash
复制
tr [选项] "字符串1" "字符串2" < 输入文件 > 输出文件
常用选项:
-c:使用字符串1的补集(ASCII字符集的补集)。-d:删除字符串1中的字符。-s:压缩重复字符。
3. 字符范围与表示
-
字符范围
:
[a-z]:小写字母。[A-Z]:大写字母。[0-9]:数字。- 八进制表示:如
\012表示换行符。 - 重复模式:
[O*2]匹配OO。
-
字符类
:
[:lower:]:小写字母。[:upper:]:大写字母。[:digit:]:数字。[:space:]:空白字符(如空格、制表符、换行)。
4. 常用操作示例
4.1 压缩重复字符
bash
复制
# 将重复字母压缩为单个(如 "cowwwws" → "cows")
tr -s "[a-z]" < oops.txt
4.2 删除空行
bash
复制
# 使用换行的八进制表示或速记符
tr -s "[\012]" < plane.txt # 或 tr -s "\n"
4.3 大小写转换
bash
复制
# 大写转小写
echo "HELLO" | tr "[A-Z]" "[a-z]" # 输出:hello
# 小写转大写(使用字符类)
echo "world" | tr "[:lower:]" "[:upper:]" # 输出:WORLD
4.4 删除指定字符
bash
复制
# 删除所有数字(结合 -c 和 -s)
tr -cs "[a-zA-Z]" "[\n*]" < diary.txt # 仅保留字母并压缩换行
4.5 控制字符处理
bash
复制
# 转换 DOS 换行符(^M)为 UNIX 换行符
tr -s "\r" "\n" < dos_file.txt
# 删除所有控制字符(如 ^Z)
tr -d "[\032]" < input.txt
4.6 快速替换
bash
复制
# 替换冒号为制表符(用于增强可读性)
tr ":" "\t" < passwd.txt
# 替换多个连续0为星号(如 "0000" → "****")
tr "[0 * 4]" "*" < hdisk.txt
5. 高级技巧
-
补集操作
:使用
-c反向匹配字符。
bash
复制
# 删除所有非字母字符(保留字母并压缩换行) tr -cs "[:alpha:]" "[\n]" < file.txt -
文件处理
:通过重定向保存结果。
bash
复制
tr "[A-Z]" "[a-z]" < input.txt > output.txt -
组合选项
:同时使用
-d和
-s。
bash
复制
# 删除所有数字并压缩空格 tr -ds "[0-9]" " " < data.txt
6. 特殊控制字符速查表
| 速记符 | 含义 | 八进制表示 |
|---|---|---|
\a |
响铃 | \007 |
\b |
退格 | \010 |
\f |
换页 | \014 |
\n |
换行 | \012 |
\r |
回车 | \015 |
\t |
制表符 | \011 |
\v |
垂直制表符 | \013 |
7. 注意事项
- 参数顺序:字符串1为被替换字符,字符串2为目标字符,长度需一致(若字符串2较短,会重复最后一个字符)。
- 特殊字符转义:使用反斜杠转义特殊字符(如
\*表示星号)。 - 效率:
tr处理速度优于sed,适合简单字符操作。
8. 典型应用场景
- 数据清洗:去除文件中的控制字符或非法字符。
- 格式转换:DOS/UNIX 换行符转换、CSV 分隔符替换。
- 日志处理:压缩重复空格或空行,提升可读性。
通过灵活组合选项和字符范围,tr 可高效完成文本处理任务,是 Shell 脚本中不可或缺的工具之一。
总结:UNIX登录环境与配置文件
1.登录过程的核心步骤
• 验证用户身份:系统通过检查/etc/passwd文件验证用户名和加密密码。
• 初始化环境:依次执行全局配置文件/etc/profile和用户个人配置文件$HOME/.profile。
2./etc/passwd文件解析
• 文件结构:7个字段,以冒号分隔:
- 登录名(如
kvp) - 加密密码(如
JFqMmk9.uRioA) - 用户ID(如
405) - 组ID(如
413) - 用户全名(如
K.V.Pally) - 用户根目录(如
/home/sysdev/kvp) - 默认Shell(如
/bin/sh) • 注意事项:直接修改需谨慎,某些系统可能将密码移至/etc/shadow。
3.全局配置文件/etc/profile
• 作用:为所有用户设置全局环境。
• 关键功能:
• 环境变量:如LOGNAME、MANPATH、PATH。
• 终端设置:通过TERM=vt220定义默认终端类型。
• 安全策略:设置umask 022(文件默认权限为755)。
• 系统消息:显示/etc/motd(登录当天的消息)。
• 登录限制:检查用户登录次数(示例中限制最多2次)。
• 日志记录:使用logger记录登录/退出事件。
• 示例功能:设置PS1提示符、限制核心转储(ulimit -c 0)。
4.用户个人配置文件$HOME/.profile
• 作用:覆盖或补充全局配置,定制用户专属环境。
• 常见定制内容:
• 路径扩展:添加个人bin目录到PATH(如PATH=$PATH:$HOME/bin)。
• 环境变量:设置编辑器(EDITOR=vi)、终端类型(TERM=vt100)。
• 提示符定制:动态显示主机名或当前目录(如PS1="$(hostname)> ")。
• 实用命令:登录时显示在线用户数(echo "$(who | wc -l) users are on today")。
• 生效方式:退出重新登录,或执行. .profile(或source .profile)。
5.stty终端设置
• 核心功能:配置终端输入/输出行为。
• 常用操作:
• 查看设置:stty -a。
• 退格键修复:stty erase ^?(设置为^?)或stty erase ^H(需在输入时使用Ctrl-V转义)。
• 保存/恢复设置:
```bash
SAVEDSTTY=$(stty -g) # 保存当前设置
stty -echo # 关闭回显(如输入密码)
# ...执行操作...
stty $SAVEDSTTY # 恢复原始设置
```
• 信号控制:禁用Ctrl+C终止(stty intr undef)。
6.创建.logout文件(Bourne Shell)
• 实现原理:通过trap捕获退出信号0。
• 配置步骤:
-
在
.profile末尾添加:
bash
复制
trap "$HOME/.logout" 0 -
创建
.logout文件,定义退出时执行的操作:
bash
复制
# 示例:清理临时文件并显示退出消息 rm -f $HOME/*.log $HOME/*.tmp echo "Bye...bye $LOGNAME"
小结
- 登录流程:身份验证→加载全局配置→加载用户配置。
- 配置文件层级:
/etc/profile(全局)→$HOME/.profile(用户级)。 - 核心配置项:环境变量(
PATH、TERM)、终端行为(stty)、安全策略(umask)。 - 终端调试:使用
stty解决退格键等问题,保存/恢复终端状态。 - 扩展功能:通过
.logout实现退出时的自定义清理或通知。
通过合理配置这些文件,用户可高效定制UNIX环境,提升安全性和使用体验。
第14章 环境与Shell变量总结
一、Shell变量概述
• 作用:定制用户环境,保存路径、文件名、数值等信息,均为文本字符串。
• 分类:
• 本地变量:仅当前Shell进程有效,子进程无法继承。
• 环境变量:可传递给子进程,需用export导出。
• 特殊变量:只读,用于传递参数(如位置参数和特定变量)。
二、本地变量
-
设置与使用: • 语法:
变量名=值(等号两侧无空格,值含空格需引号)。• 示例:
GREAT_PICTURE="die hard",通过${变量名}引用。 -
操作: • 显示:
echo ${变量名}。• 清除:
unset 变量名。• 拼接:直接并列变量,如
${FIRST}${LAST}。 -
测试与默认值: •
${变量:-默认值}:变量未设置时使用默认值。•
${变量:=默认值}:变量未设置时赋值默认值。•
${变量:?错误信息}:变量未设置时报错退出。 -
只读变量: • 设置:
readonly 变量名,不可修改或清除。• 查看:
readonly命令列出所有只读变量。
三、环境变量
-
设置与导出: • 方式一:
变量名=值; export 变量名。• 方式二:分两步(
变量名=值后export)。 -
常用环境变量: • PATH:命令搜索路径,格式为冒号分隔的目录列表。
• HOME:用户主目录,
cd命令的默认目标。• PS1/PS2:主/次提示符(如
PS1="\u@\h:\w\$ ")。• TERM:终端类型(如
vt100)。• LANG/LC_*:语言和区域设置。
• USER/LOGNAME:当前用户名。
-
其他变量: • EDITOR:默认编辑器(如
vi)。• PAGER:分页程序(如
more或less)。• MANPATH:手册页搜索路径。
-
查看与清除: • 显示所有环境变量:
env或printenv。• 清除:
unset 变量名。
四、变量替换与扩展
• 替换模式:
• ${变量:-值}:变量未定义时返回默认值。
• ${变量:=值}:变量未定义时赋值默认值并返回。
• ${变量:+值}:变量已定义时返回指定值。
• ${变量:?信息}:变量未定义时报错并显示信息。
• 示例:
bash
复制
echo ${COLOR:-red} # 未定义COLOR时输出red
echo ${COLOR:=blue} # 未定义则赋值blue并输出
五、位置参数与特定变量
-
位置参数: •
$0:脚本名称。•
$1-$9:第1到第9个参数。•
$#:传递的参数个数。•
$*和$@:所有参数($*合并为单字符串,$@保留分隔)。 -
特定变量: •
$$:当前进程ID。•
$!:后台最后一个进程的ID。•
$?:上一个命令的退出状态(0为成功,非0为失败)。•
$-:当前Shell选项(如set -x的跟踪模式)。 -
应用示例:
bash
复制
# 脚本中检查参数个数 if [ $# -eq 0 ]; then echo "Usage: $0 <file>" exit 1 fi # 检查命令是否成功 cp file.txt /backup/ && echo "备份成功" || echo "备份失败: $?"
六、向脚本传递参数
• 脚本内使用参数:
bash
复制
echo "脚本名: $0"
echo "第一个参数: $1"
echo "所有参数: $*"
• 结合系统命令:
bash
复制
grep $1 /etc/passwd # 将第一个参数作为搜索关键字
七、最佳实践
- 变量命名:环境变量使用大写,本地变量小写。
- 错误处理:利用
$?检查命令执行结果。 - 默认值:脚本中为关键变量设置默认值,避免未定义错误。
- 只读保护:关键变量设为只读(如
readonly PATH)。
八、示例汇总
bash
复制
# 本地变量与环境变量
name="Alice"
export name # 导出为环境变量
# 使用位置参数
echo "脚本名: $0, 参数1: $1, 参数总数: $#"
# 检查文件存在性
FILE=${1:-default.txt}
if [ -f "$FILE" ]; then
echo "处理文件: $FILE"
else
echo "文件不存在: $FILE"
fi
# 退出状态检查
tar -czf backup.tar.gz /data
if [ $? -ne 0 ]; then
echo "压缩失败!"
exit 1
fi
通过掌握这些概念,能够有效管理Shell脚本中的变量,提升脚本的灵活性和健壮性。
第15章 引号 总结
1. 引用的必要性
• 问题背景:Shell在解析脚本时会对特殊字符(如*、$、空格等)进行解释,可能导致意外行为。例如,未加引号的*会被展开为文件列表,变量$VAR会被替换为值。
• 解决方案:使用引号包裹字符串或变量,阻止Shell错误解释特殊字符。
• 示例:
bash
复制
# 未引用时,*被展开为文件列表
echo Hit the star button to exit* # 输出意外结果
# 双引号包裹后,*被当作普通字符
echo "Hit the star button to exit*" # 正确输出
2. 双引号(")
• 作用:允许变量替换($VAR)和命令替换(),但屏蔽大部分特殊字符(如*、?等)。
• 示例:
bash
复制
STRING="MAY DAY, MAY DAY"
echo "$STRING" # 正确输出变量值
MYDATE="date" # MYDATE保存字符串"date",而非执行命令
grep "Davey Wire" /etc/passwd # 正确搜索含空格的字符串
• 变量替换:
bash
复制
BOY="boy"
echo "The $BOY did well" # 输出:The boy did well
echo "The \$BOY did well" # 输出:The $BOY did well(屏蔽$)
3. 单引号(')
• 作用:完全屏蔽所有特殊字符,包括变量和命令替换,内容按字面输出。
• 示例:
bash
复制
GIRL='girl'
echo 'The $GIRL did well' # 输出:The $GIRL did well
4. 反引号()
• 作用:执行命令并将输出结果作为变量值(命令替换)。现代脚本推荐使用$()。
• 示例:
bash
复制
mydate=`date +"%A the %e of %B %Y"` # 保存格式化日期
echo "Today is `date`" # 嵌入命令输出
echo "Users: `who | wc -l`" # 统计当前用户数
5. 反斜线(\)
• 作用:转义单个字符,屏蔽其特殊含义(如$、*、空格)。
• 关键场景:
• 输出特殊字符:
```bash
echo "Price: \$19.99" # 输出:Price: $19.99
echo "Copyright sign: \251" # 需配合`echo -e`显示ASCII字符
```
• 避免语法错误:
```bash
expr 12 \* 12 # 正确计算乘法(未转义*会报错)
```
6. 常见错误与处理
• 未引用含空格的字符串:
bash
复制
grep Davey Wire /etc/passwd # 错误:Wire被视为文件名
grep "Davey Wire" /etc/passwd # 正确
• 混合引号与变量:
bash
复制
# 单引号内变量不会展开
echo 'Today is $MYDATE' # 输出:Today is $MYDATE
# 双引号内需转义$以输出字面值
echo "Today is \$MYDATE" # 输出:Today is $MYDATE
7. 经验法则
- 默认使用双引号:处理字符串时优先使用双引号,允许变量替换且避免多数意外展开。
- 灵活切换引用方式:若双引号不适用(如需完全屏蔽变量),尝试单引号或反斜线转义。
总结表格
| 引用类型 | 语法 | 作用 | 示例 |
|---|---|---|---|
| 双引号 | "..." |
允许变量和命令替换,屏蔽除$、、\外的特殊字符 |
echo "Value: $VAR" |
| 单引号 | '...' |
完全屏蔽所有特殊字符,按字面输出 | echo 'Value: $VAR' |
| 反引号 | ... |
执行命令并替换为输出结果 | mydate=date“ |
| 反斜线 | \ |
转义单个字符,屏蔽其特殊含义 | echo "Price: \$10" |
通过正确使用引号,可精确控制Shell对字符串、变量和命令的解释,避免脚本中的常见错误。
第四部分基础shell编程 第16章总结
一、使用Shell脚本的原因
-
自动化与效率 • 处理重复性任务或复杂操作时,通过脚本批量执行命令,节省手动输入时间。
• 支持组合多个命令,处理文件分类、文本插入、日志清理等系统管理任务。
-
灵活性与功能扩展 • 支持变量、条件判断、算术运算和循环,增强任务处理能力。
• 可通过接收命令行参数动态调整行为。
-
跨系统适应性 • Shell脚本本身可移植性较好,但需注意不同UNIX/Linux系统的命令差异(如选项、路径等)。
二、Shell脚本基本元素
-
脚本结构 • Shebang行:首行必须为
#!/bin/sh,指定使用Bourne Shell解释器。• 注释:以
#开头,建议第二行注释注明脚本名称及功能。 -
执行逻辑 • 按顺序逐行解释执行命令,无需编译。
• 需赋予执行权限:
chmod u+x 脚本名。 -
编写原则 • 优先追求简洁和高可读性,避免过度复杂化。
• 保留调试基础:即使结果异常,也应保存脚本以便修改。
三、运行Shell脚本的步骤
-
创建与权限设置
bash
复制
# 示例脚本 cleanup #!/bin/sh # name: cleanup # 功能:清理日志和系统消息文件 echo "starting cleanup...wait" rm /usr/local/apps/log/*.log # 删除日志文件 tail -40 /var/adm/messages > /tmp/messages # 保留最新40行消息 rm /var/adm/messages mv /tmp/messages /var/adm/messages # 恢复截断后的消息文件 echo "finished cleanup"• 添加执行权限:
bash
复制
chmod u+x cleanup -
运行方式 • 直接运行(需在PATH中):
./cleanup。• 若提示“command not found”,需设置脚本路径:
bash
复制
mkdir ~/bin # 创建用户可执行目录(若不存在) mv cleanup ~/bin/ # 移动脚本到可执行目录 echo 'export PATH=$PATH:$HOME/bin' >> ~/.profile # 添加PATH变量 source ~/.profile # 重新加载配置
四、常见问题与解决
-
路径问题 • 确保脚本所在目录(如
~/bin)已加入PATH环境变量。 -
权限问题 • 检查脚本是否具有可执行权限(
ls -l查看权限位含x)。 -
脚本调试 • 执行时逐行检查错误输出,定位命令失败位置。
• 保留中间结果(如
/tmp/messages)辅助排查问题。
第17章条件测试总结
核心内容 本章主要讲解在Shell脚本中如何使用test和expr命令进行条件测试,涵盖文件状态、字符串、数值的测试方法,以及逻辑操作符的应用。测试结果通过退出状态$?判断(0表示成功,非0表示失败),为后续条件控制结构(如if、case)提供基础。
1. 文件状态测试
• 语法格式:
bash
复制
test condition 或 [ condition ] # 方括号两侧必须有空格
• 常用测试选项:
| 选项 | 含义 | 示例 | 结果判断 |
|---|---|---|---|
-d |
是否为目录 | [ -d appsbin ] |
存在目录返回0 |
-f |
是否为普通文件 | [ -f scores.txt ] |
是文件返回0 |
-r |
是否可读 | [ -r file ] |
可读返回0 |
-w |
是否可写 | [ -w scores.txt ] |
可写返回0 |
-x |
是否可执行 | [ -x script.sh ] |
可执行返回0 |
-u |
是否有suid位 | [ -u xab ] |
设置suid返回0 |
-s |
文件非空 | [ -s data.txt ] |
非空返回0 |
• 示例:
bash
复制
$ [ -w scores.txt ]; echo $? # 测试可写性,返回0表示可写
$ [ -x scores.txt ]; echo $? # 测试可执行性,返回1表示不可执行
$ [ -d appsbin ]; echo $? # 测试是否为目录,返回0表示存在
2. 逻辑操作符
• 操作符:
• -a:逻辑与(两条件均真)
• -o:逻辑或(任一条件为真)
• !:逻辑非(取反)
• 示例:
bash
复制
# 测试两个文件均可写
$ [ -w file1 -a -w file2 ]; echo $? # 返回0表示均满足
# 测试文件是否可写且可执行
$ [ -w script.sh -a -x script.sh ]; echo $? # 返回0表示满足
# 测试文件是否不可读
$ [ ! -r secret.txt ]; echo $? # 不可读返回0
3. 字符串测试
• 测试操作符:
• =:相等
• !=:不等
• -z:空字符串
• -n:非空字符串
• 示例:
bash
复制
$ [ -z "$EDITOR" ]; echo $? # 测试变量是否为空,返回1表示非空
$ [ "$EDITOR" = "vi" ]; echo $? # 测试变量是否为vi,返回0表示是
$ [ "$TAPE" != "$TAPE2" ]; echo $? # 测试变量不等,返回0表示不等
• 注意:变量需用双引号包裹,避免空格或特殊字符导致错误。
4. 数值测试
• 操作符:
| 操作符 | 含义 | 示例 | 结果判断 |
|---|---|---|---|
-eq |
等于 | [ "$a" -eq 10 ] |
相等返回0 |
-ne |
不等于 | [ "$a" -ne 5 ] |
不等返回0 |
-gt |
大于 | [ "$a" -gt 100 ] |
大于返回0 |
-lt |
小于 | [ "$a" -lt 50 ] |
小于返回0 |
-ge |
大于等于 | [ "$a" -ge 99 ] |
满足返回0 |
-le |
小于等于 | [ "$a" -le 200 ] |
满足返回0 |
• 示例:
bash
复制
$ [ "$NUMBER" -eq 130 ]; echo $? # 测试等于130,返回0
$ [ "$SOURCE_COUNT" -lt "$DEST_COUNT" ]; echo $? # 测试小于,返回0
$ [ "990" -le "995" -a "123" -gt "33" ]; echo $? # 组合测试,返回0
5. expr命令
• 功能:数值计算、字符串操作、模式匹配。
• 数值运算:
bash
复制
$ expr 30 \* 3 # 乘法需转义,输出90
$ expr $LOOP + 1 # 增量计数
• 数值测试:
bash
复制
$ expr "$VALUE" + 0 >/dev/null 2>&1 # 测试是否为数值
$ echo $? # 返回0表示是数值,非0表示非数值
• 字符串模式匹配:
bash
复制
$ expr "$VALUE" : '.*\.doc' # 提取文件名中的.doc后缀
$ expr length=$(expr "$STR" : '.*') # 计算字符串长度
6. 注意事项
-
空格与引号: •
[ condition ]中的条件两侧必须有空格。• 变量比较时需用双引号包裹,避免未定义变量或含空格导致错误。
-
退出状态: •
test和expr的退出状态$?需反向理解:0表示成功(真),非0为失败(假)。 -
逻辑操作符限制: • 逻辑操作符需在单层方括号内使用,如
[ cond1 -a cond2 ],避免多层括号导致语法错误。
7. 应用场景
• 文件检查:确保文件存在、可读写后再进行操作。
• 输入验证:检查用户输入是否为空或符合格式。
• 循环控制:通过expr实现计数器或数值条件判断。
• 脚本健壮性:通过测试避免因文件不存在、权限不足等问题导致脚本中断。
本章内容为Shell脚本的流程控制打下基础,结合后续的if、case等结构,可实现复杂的逻辑判断与自动化操作。
第18章 控制流结构总结
一、退出状态
-
概念:每个命令执行后返回退出状态,
0表示成功,非0表示失败。 -
获取状态:通过
$?获取上一个命令的退出状态。 -
脚本退出:使用
exit n指定退出码,建议在脚本中显式处理错误并返回合适状态。 •0:成功•
1:常见错误
二、控制结构
- 流控制 • if-then-else
• 语法:
```sh
if condition; then
commands
elif condition2; then
commands
else
commands
fi
```
• 用例:
◦ 测试变量是否为空:`if [ -z "$var" ]`
◦ 文件存在性检查:`if [ -f "file.txt" ]`
◦ 数值比较:`if [ "$a" -lt "$b" ]`
• case语句
• 语法:
```sh
case $var in
pattern1) commands ;;
pattern2) commands ;;
*) default commands ;;
esac
```
• 用例:
◦ 处理用户输入选项(如菜单选择)
◦ 匹配文件名模式(如`.txt`, `.sh`)
- 循环结构
• for循环
• 语法:
```sh
for var in list; do
commands
done
```
• 用例:
◦ 遍历文件列表:`for file in *.txt; do ...`
◦ 处理命令行参数:`for param in "$@"; do ...`
• while循环
• 语法:
```sh
while condition; do
commands
done
```
• 用例:
◦ 逐行读取文件:`while read line; do ... done < file`
◦ 持续监控条件(如进程运行状态)
• until循环
• 语法:
```sh
until condition; do
commands
done
```
• 用例:
◦ 等待文件被删除:`until [ ! -f lockfile ]; do sleep 1; done`
◦ 等待服务启动
三、循环控制
• break:立即退出循环。
sh
复制
while :; do
if condition; then break; fi
done
• continue:跳过当前迭代,进入下一次循环。
sh
复制
for i in {1..5}; do
if [ "$i" -eq 3 ]; then continue; fi
echo $i
done
四、菜单实现
• 结构:结合while循环和case语句。
• 关键点:
• 无限循环:while :; do ...
• 显示选项,捕获用户输入。
• 处理退出选项(q或Q)。
• 示例:
while :; do
clear
echo "1. Option 1"
echo "2. Option 2"
echo "Q. Quit"
read -p "Choice: " choice
case $choice in
1) command1 ;;
2) command2 ;;
q|Q) exit 0 ;;
*) echo "Invalid option"; sleep 1 ;;
esac
done
五、实用技巧
-
测试命令: • 文件测试:
-f(存在)、-d(目录)、-r(可读)。• 字符串比较:
=(相等)、!=(不等)。• 数值比较:
-eq(等于)、-lt(小于)。 -
错误处理: • 输出错误信息到标准错误:
echo "Error" >&2• 退出时返回状态码:
exit 1 -
输入处理: • 使用
read捕获输入,处理默认值:read -p "Enter [default]: " var || var="default"• 屏蔽输入回显(密码):
stty -echo; read pass; stty echo -
环境变量与IFS: • 修改
IFS处理字段分隔(如逐行解析逗号分隔文件)。• 临时变量保存环境:
OLD_IFS=$IFS; IFS=','; ...; IFS=$OLD_IFS
六、典型用例
• 备份文件:
for file in *.doc; do
cp "$file" "${file}.bak"
done
• 监控磁盘空间:
df命令用来查看磁盘相关内容
while true; do
usage=$(df / | awk '{print $5}' | tr -d '%')
[ "$usage" -ge 90 ] && echo "Disk full!" | mail admin
sleep 3600
done
七、注意事项
• 语法细节:
• if条件方括号内需空格:[ "$a" -eq 1 ]
• case语句每个模式以;;结束。
• 引号使用:变量引用加双引号避免空格问题:"$var"
• 调试:使用set -x启用调试模式,显示执行命令。
通过掌握这些控制流结构,可以编写出灵活、健壮的Shell脚本,有效处理条件判断、循环任务和用户交互。
第19章 Shell函数详细总结
一、Shell函数基础概念
-
作用与优势 • 将重复代码块封装为可重用单元,提升代码复用性、可维护性和可读性。
• 函数执行时保留当前Shell环境(变量、状态),而外部脚本会启动新Shell。
-
函数结构 • 标题:函数名,需唯一。
• 函数体:包含具体命令的代码块。
• 定义格式:
bash
复制
函数名() { 命令; } # 或 function 函数名() { 命令; }
二、函数定义与调用
-
定义位置 • 必须在脚本顶部或调用前定义,确保解析器可识别。
-
简单示例
bash
复制
hello() { echo "Hello, today's date is $(date)"; } # 调用 hello• 输出示例:
Hello, today's date is Sun Jun 6 10:46:59 GMT 1999
三、参数传递与返回值
-
参数传递 • 使用位置参数(
$1, $2...)接收传入值。• 最佳实践:将参数赋值给本地变量(如
_VAR=$1)以避免副作用。 -
返回值处理 •
return语句:返回状态码(0成功,非0错误)。• 获取返回值:通过
$?或直接作为条件判断。• 示例:
bash
复制
check_dir() { [ -d "$1" ] && return 0 || return 1 } if check_dir "/path"; then echo "存在"; else echo "不存在"; fi
四、高级函数技巧
-
函数文件管理 • 创建函数文件(如
functions.sh)集中存放常用函数。• 加载函数:通过
. ./functions.sh或source命令导入当前Shell。• 查看/删除函数:
set显示已加载函数,unset 函数名删除。 -
错误处理与交互 • 统一错误提示函数:封装错误消息格式(如带蜂鸣声)。
bash
复制
error_msg() { echo -e "\a$@\a"; }• 用户输入验证:循环提示直至输入合法(如字母检查)。
bash
复制
while :; do read -p "输入姓名:" NAME char_name "$NAME" && break || error_msg "非法字符!" done
五、实用函数示例
-
目录检查
bash
复制
is_dir() { [ -d "$1" ] && return 0 || return 1; } -
字符串处理 • 大小写转换:
bash
复制
to_upper() { echo "$@" | tr '[:lower:]' '[:upper:]'; } to_lower() { echo "$@" | tr '[:upper:]' '[:lower:]'; }• 长度检查:
bash
复制
check_len() { [ ${#1} -le $2 ] && return 0 || return 1; } -
交互式提示
bash
复制
confirm() { read -p "$1 [Y/N](默认:$2): " ans case "${ans:-$2}" in [Yy]*) return 0;; *) return 1;; esac } -
文件行号显示
bash
复制
number_lines() { local line=1 while IFS= read -r content; do echo "$line: $content" ((line++)) done < "$1" }
六、函数调用场景
-
脚本内调用 • 直接在脚本中定义并调用函数,适合功能专一的场景。
-
跨脚本共享 • 通过函数文件复用函数(如
source functions.sh),适合复杂项目。 -
系统配置共享 • 将全局变量和函数结合(如
config.sh),统一管理配置:bash
复制
# config.sh LOG_DIR="/var/log" set_log() { export LOG_FILE="$LOG_DIR/$1.log"; }
七、调试与最佳实践
-
调试技巧 • 先以独立脚本测试函数逻辑,再封装为函数。
• 使用
set -x开启调试模式,追踪函数执行流程。 -
最佳实践 • 命名规范:函数名明确描述功能(如
validate_email)。• 参数检查:函数开头验证参数合法性,避免异常。
• 返回值一致性:成功返回0,错误返回非0,保持约定。
八、综合示例
场景:备份脚本使用函数验证目录并记录日志。
bash
复制
#!/bin/bash
source utils.sh # 加载工具函数
backup() {
local src=$1 dest=$2
is_dir "$src" || { error_msg "源目录不存在!"; return 1; }
mkdir -p "$dest" || return 1
rsync -av "$src" "$dest" >> "${LOG_DIR}/backup.log"
}
main() {
confirm "确认开始备份?" "Y" || exit
backup "/data" "/backup" && echo "备份成功!" || error_msg "备份失败!"
}
main
总结
Shell函数通过模块化提升脚本可维护性,支持参数传递、返回值处理及跨脚本复用。结合函数文件与配置管理,可构建灵活高效的脚本系统。掌握错误处理、用户交互和调试技巧,能显著提升脚本健壮性。
第20章 向脚本传递参数 总结
本章深入讲解了Shell脚本中处理命令行参数的两种核心方法:shift命令和getopts命令,并结合实际案例演示其应用场景和最佳实践。以下是详细内容总结:
一、基础概念
-
位置参数与参数统计 • 脚本通过位置参数
$1到$9接收传递的参数,$#表示参数总数。• 示例:若脚本需要两个参数(如
start|stop和进程名),可通过if [ $# -ne 2 ]检查参数个数,并配合usage()函数提示正确用法。 -
usage语句 • 用于向用户说明脚本的正确调用方式,通常在参数错误时触发。例如:
bash
复制
usage() { echo "Usage: $(basename $0) start|stop processname" } -
case语句处理参数 • 通过
case $1 in ... esac结构匹配不同参数,执行对应操作。例如处理start和stop命令。
二、shift命令
-
作用与原理 •
shift将参数列表左移一位,丢弃当前$1,后续参数依次前移。这使得脚本能处理超过9个参数,并遍历所有输入。• 示例:循环处理所有参数:
bash
复制
while [ $# -ne 0 ]; do echo $1 shift done -
典型应用场景 • 遍历参数:在循环中依次处理每个参数。
• 分离选项与参数:例如处理文件转换脚本时,先解析选项(如
-l或-u),再通过shift跳过已处理的选项,遍历剩余文件名。 -
局限性 • 处理复杂选项(如带值选项
-c 3)时代码冗余,需手动管理参数位置,易出错。
三、getopts命令
-
作用与原理 •
getopts是更强大的参数解析工具,支持定义带值选项和错误处理。• 基本语法:
while getopts ":ahfgvc:" OPTION,其中:表示选项后需跟值,OPTARG存储选项值。 -
关键特性 • 错误处理:无效选项会触发
?分支,可自定义错误提示。• 带值选项:如
-c 3,通过c) COPIES=$OPTARG获取值。• 静默处理:通过
:开头屏蔽默认错误信息,完全自定义反馈。 -
示例 • 处理选项
-a、-h、-f、-v及带值选项-c:bash
复制
while getopts ":ahfgvc:" OPTION; do case $OPTION in a) ALL=true ;; c) COPIES=$OPTARG ;; ?) echo "Usage: ..."; exit 1 ;; esac done
四、shift与getopts对比
| 特性 | shift | getopts |
|---|---|---|
| 适用场景 | 简单参数遍历 | 复杂选项(含带值选项、多选项) |
| 代码复杂度 | 需手动管理参数位置,代码较长 | 自动解析,代码简洁 |
| 错误处理 | 需自行实现 | 内置错误检测,支持自定义提示 |
| 带值选项支持 | 需额外逻辑处理 | 直接通过 OPTARG 获取值 |
| 遵循UNIX选项惯例 | 灵活性高,但需自行设计 | 天然支持标准选项格式(如 -c 3) |
五、实践案例
-
文件大小写转换脚本(shift版) • 通过
-l和-u指定转换方向,结合shift遍历文件参数。• 关键逻辑:解析选项后,用
shift跳过已处理参数,循环处理剩余文件名。 -
文件大小写转换脚本(getopts版) • 使用
getopts解析-l、-u和-v(详细模式),代码更简洁。• 优势:轻松支持带值选项和错误处理,如
-v控制输出详细程度。
六、最佳实践
- 选项命名规范 • 遵循UNIX惯例(如
-a表示所有,-f表示文件,-h显示帮助)。 - 错误处理 • 始终校验文件存在性(如
if [ -f $1 ])和参数有效性。 - 用户友好性 • 提供清晰的
usage语句,并在参数错误时退出(exit 1)。
七、总结
• shift 适合简单参数遍历,可突破 $1~$9 的限制,但处理复杂选项时代码繁琐。
• getopts 提供标准化选项解析,支持带值选项和错误处理,显著提升脚本健壮性和可维护性。
• 实际开发中,推荐优先使用 getopts 处理复杂命令行参数,结合 shift 处理剩余参数(如文件名列表)。
在Shell脚本中,getopts 是用于解析命令行选项和参数的标准工具。while getopts ":ahfgvc:" OPTION 中的选项字符串 ":ahfgvc:" 定义了脚本接受的选项及其规则。以下是详细解释:
选项字符串 ":ahfgvc:" 的作用
-
开头的冒号
:• 抑制默认错误处理:当用户输入无效选项(如-x)或缺少参数的选项(如-c未带参数)时,getopts默认会输出错误信息。开头的冒号:会关闭这一行为,允许脚本自行处理错误。• 特殊返回值:
◦
OPTION设为?表示无效选项(如-x)。◦
OPTION设为:表示选项缺少必要参数(如-c后未跟参数)。 -
字母
a,h,f,g,v• 这些是无需参数的选项。例如:bash
复制
script.sh -a -h -f◦
-a,-h,-f,-g,-v会被识别为合法选项,不要求后续参数。 -
字母
c:• 冒号:在c后表示-c需要参数。例如:bash
复制
script.sh -c 5◦ 参数
5会被保存到$OPTARG变量中,供脚本使用。
选项字符串的结构 • 格式:":合法选项列表"
• 开头的 : 表示抑制错误输出。
• 每个字母表示一个选项,字母后的 : 表示该选项需要参数。
• 示例字符串 ":ahfgvc:" 的解析
| 选项 | 是否需要参数 | 示例用法 | 参数位置 |
|---|---|---|---|
a |
否 | -a |
无 |
h, f, g, `v |
否 | -h, -f |
无 |
c: |
是 | -c 5 |
通过 $OPTARG 获取 |
在脚本中的典型用法
bash
复制
while getopts ":ahfgvc:" OPTION; do
case $OPTION in
a) echo "Option -a 被触发" ;;
h) echo "Option -h 被触发" ;;
f) echo "Option -f 被触发" ;;
g) echo "Option -g 被触发" ;;
v) echo "Option -v 被触发" ;;
c) echo "Option -c 的参数是: $OPTARG" ;;
:) echo "错误:选项 -$OPTARG 需要参数" >&2 ;;
?) echo "错误:无效选项 -$OPTARG" >&2 ;;
esac
done
• 处理带参数的选项(如 -c)
bash
复制
script.sh -c 10
输出:Option -c 的参数是: 10
• 处理非法选项(如 -x)
bash
复制
script.sh -x
输出:错误:无效选项 -x
• 处理缺少参数的选项(如 -c 未带参数)
bash
复制
script.sh -c
输出:错误:选项 -c 需要参数
总结 • :ahfgvc: 定义了脚本接受的选项:
• a, h, f, g, v 是开关选项(无需参数)。
• c 必须后跟参数(如 -c 5)。
• 开头的 : 允许脚本自定义错误处理,提升用户体验。
• getopts 会自动处理选项的顺序和组合,例如:
bash
复制
script.sh -a -c 3 -h
会依次解析 -a, -c 3, -h。
通过这种方式,脚本可以灵活、健壮地处理命令行参数,符合UNIX/Linux工具的标准行为。
第21章创建屏幕输出的详细总结
核心目标 使用Shell脚本创建交互式、专业的屏幕输出,依赖tput命令和终端控制序列(转义序列),尤其关注颜色、光标控制和菜单设计。
一、tput命令
作用:通过终端数据库(terminfo/termcap)控制终端属性,生成字符串、数字、布尔输出。
- 字符串输出 控制文本样式和终端行为,常用选项: •
bel:响铃
• clear:清屏
• cup r c:移动光标到行r列c
• bold:粗体
• smul/rmul:下划线开关
• rev:反色显示
• civis/cnorm:隐藏/显示光标
示例:
bash
复制
BOLD=$(tput bold) # 启用粗体
echo "${BOLD}Hello World"
- 数字输出 获取终端信息: •
cols:终端列数
• lines:终端行数
示例:
bash
复制
COLS=$(tput cols) # 获取当前终端宽度
- 布尔输出 判断终端功能是否存在: •
hs:是否有状态行
• chts:光标是否可见
示例:
bash
复制
if tput hs; then echo "终端支持状态行"; fi
二、转义序列与控制码
作用:直接发送控制码改变终端行为,如清屏、光标位置、颜色。
- 基本语法 • 转义序列以
\033[开头(\033代表Esc键)。
• 示例:
• 清屏:echo -e "\033[2J"
• 移动光标:echo -e "\033[10;5H"(第10行第5列)
- 光标控制 • 隐藏/显示光标:
bash
复制
echo -e "\033[?25l" # 隐藏
echo -e "\033[?25h" # 显示
• 保存/恢复光标位置:
bash
复制
echo -e "\033[s" # 保存
echo -e "\033[u" # 恢复
- 屏幕居中显示 通过计算列数动态居中文本:
bash
复制
center() {
str=$1
len=$(echo -n $str | wc -c)
cols=$(tput cols)
pos=$(( (cols - len) / 2 ))
tput cup $2 $pos
echo -n "$str"
}
center "Hello" 5 # 在第5行居中显示
三、颜色设置
ANSI颜色码: • 前景色:30-37(黑、红、绿、黄、蓝、紫、青、白)
• 背景色:40-47(同上)
- 颜色语法 • 格式:
\033[背景;前景m
• 示例:
bash
复制
echo -e "\033[40;32m绿底黑字\033[0m" # 恢复默认用\033[0m
- 颜色函数封装
bash
复制
color() {
case $1 in
red) echo -e "\033[31m";;
green_bg) echo -e "\033[42m";;
reset) echo -e "\033[0m";;
esac
}
echo "$(color red)Error$(color reset)"
四、交互式菜单设计
- 功能键处理 通过
cat -v捕获按键转义序列,绑定到脚本逻辑:
bash
复制
read -rsn1 key
case $key in
$'\x1b') # 处理Esc键
read -rsn2 -t 1 key
case $key in
[A) echo "上箭头";;
[B) echo "下箭头";;
esac
;;
esac
- 权限控制 通过配置文件(如
priv.user)管理用户权限:
bash
复制
user_level() {
while read user priv; do
if [[ $user == $USER ]]; then
[[ $priv == "yes" ]] && return 0 || return 1
fi
done < priv.user
return 1
}
if user_level; then
echo "允许修改"
else
echo "权限不足"
fi
- 完整菜单示例 集成tput、颜色、光标控制和权限验证:
bash
复制
#!/bin/bash
trap '' 2 3 15 # 忽略中断信号
while true; do
clear
tput cup 3 10
echo -e "$(tput rev) 主菜单 $(tput sgr0)"
echo "1. 新增记录"
echo "2. 查看记录"
echo "Q. 退出"
read -p "选择: " choice
case $choice in
1) add_record;;
2) view_record;;
Q) break;;
esac
done
五、注意事项
- 终端兼容性:不同终端对控制序列的支持可能不同,优先使用
tput而非硬编码转义序列。 - 颜色节制:避免过度使用颜色,确保可读性。
- 光标控制:操作后恢复光标状态,避免脚本异常退出时光标隐藏。
- 信号处理:使用
trap防止用户通过Ctrl+C中断关键流程。
第23章 调试脚本 详细总结
一、调试原则与预防错误
- 分阶段测试 • 建议将脚本拆分为多个独立任务或过程,每个部分完成时立即测试,确保无误后再继续开发。
- 错误定位技巧 • Shell报错时需关注整个相关代码段而非仅错误行。Shell的错误提示通常指向语法结构结束处(如
done、fi等)。
二、常见错误类型及解决方法
- 循环结构错误 • 表现:如
syntax error near unexpected token 'done'。
• 原因:for/while/until/case语句结构不完整,可能漏写do/done/fi等关键字。
• 解决:回溯代码段,检查循环结构是否完整。
- 漏写引号错误 • 表现:
unexpected EOF while looking for ‘’’。
• 原因:字符串引号未闭合(如单引号或双引号不成对)。
• 解决:检查所有字符串引号是否成对,尤其是多行字符串。
- 测试条件错误 • 表现:
[: missing ']'或操作符错误。
• 原因:
• 测试条件([ ]或[[ ]])内部缺少操作符(如-eq, ==)。
• 变量与方括号之间缺少空格(如[$VAR]应为[ $VAR ])。
• -eq用于非数字比较(应用=或==)。
• 解决:确保测试条件语法正确,操作符与数据类型匹配。
- 变量大小写不一致 • 表现:变量未正确赋值或引用。
• 原因:定义变量时用大写(如NAME="John"),引用时误用小写(如echo $name)。
• 解决:统一变量命名规范(推荐全小写加下划线)。
- for循环变量引用错误 • 表现:循环列表未正确解析变量。
• 原因:在循环列表中使用变量时漏写$符号(如for LOOP in LIST应为for LOOP in $LIST)。
• 解决:确保引用变量时使用$符号(如$LIST)。
- echo命令的误用 • 表现:调试时误判命令执行状态。
• 原因:在echo后直接检查$?状态(echo本身总返回成功状态)。
• 解决:在关键命令后直接检查$?,避免与echo混淆。
三、调试工具与方法
- echo命令调试 • 用途:在关键位置输出变量值或执行流程(如
echo "Processing $VAR")。
• 优势:简单直观,可快速定位变量赋值或逻辑错误。
- set命令调试选项 • 开启方式:在脚本中插入
set -option,关闭用set +option。
• 常用选项:
• set -n(语法检查模式):仅解析脚本语法,不执行命令。
• set -v(详细输出模式):逐行显示脚本读取内容。
• set -x(追踪执行模式):显示每条命令及其参数(最常用)。
• 示例:
bash
复制
#!/bin/sh
set -x # 开启追踪
LIST="Peter Susan John"
for LOOP in $LIST; do
echo "Name: $LOOP"
done
set +x # 关闭追踪
• 输出效果:
+ LIST=Peter Susan John
+ for LOOP in '$LIST'
+ echo 'Name: Peter'
Name: Peter
+ for LOOP in '$LIST'
+ echo 'Name: Susan'
Name: Susan
...
四、调试实例分析
• 场景:检查用户输入是否在预设列表中。
• 错误现象:输入不在列表中但无提示。
• 调试步骤:
- 使用
set -x追踪变量比较过程。 - 发现
if ["$LOOP"="$NAME"]未正确分隔操作符(应为"$LOOP" = "$NAME")。 - 修正后重新测试,确认逻辑正确性。
五、总结
• 核心策略:预防优于调试,分阶段测试减少错误。
• 调试流程:
- 优先使用
echo输出中间变量。 - 复杂逻辑开启
set -x追踪执行细节。 - 关注Shell报错提示的结构性错误(如
done/fi缺失)。 • 注意事项:
• 变量引用严格区分大小写和$符号。
• 测试条件确保语法正确(空格、操作符、数据类型)。
• 多行字符串和循环结构需闭合引号及关键字。
第24章详Shell嵌入命令
这些命令内置于Bourne Shell中,执行速度快于外部命令。以下是主要内容总结:
1. 嵌入命令概述
• 定义:嵌入命令是Shell内置的,而非存储在/bin或usr/bin中的外部命令。
• 优势:执行效率更高,无需启动外部进程。
• 示例:cd、pwd、echo等常用命令均为嵌入命令,但也可通过路径调用外部版本(如/bin/pwd)。
2. 标准嵌入命令列表及详解
关键命令功能总结• 控制流:
• break:退出循环(for/while/until/case)。
• continue:跳过当前循环迭代,进入下一次循环。
• return:退出函数并返回指定值。
• exit:退出当前Shell。
• eval:解析参数并执行结果命令(用于动态生成命令)。
• exec:执行命令并替换当前Shell进程(执行后不返回原Shell)。
• 目录与文件:
• cd:切换工作目录。
• pwd:显示当前目录(内建版更高效)。
• umask:设置默认文件创建权限掩码。
• ulimit:设置或显示Shell资源限制(如核心转储文件大小、最大进程数等)。
• 变量与参数:
• export:导出变量,使子进程可访问。
• readonly:标记变量为只读。
• set:设置位置参数或控制Shell选项(如调试模式set -x)。
• shift:左移位置参数,用于遍历参数列表。
• unset:删除变量或函数。
• 输入输出:
• echo:输出信息到标准输出。
• read:从标准输入读取一行数据。
• 进程与信号:
• wait:等待子进程结束(可指定进程ID或等待所有子进程)。
• trap:捕获信号并执行指定命令(如清理临时文件)。
• 调试与性能:
• times:显示Shell及子进程的用户和系统时间,用于性能分析。
• type:查询命令类型(嵌入/外部)及路径(如type pwd显示其为内建命令)。
3. 重点命令详解
set• 用途:
• 设置位置参数(如set param1 param2),可在脚本内动态指定参数。
• 控制Shell选项(如set -x启用调试模式,set +x关闭)。
• 示例:
bash
复制
# 脚本内设置参数并遍历
set accounts.doc accounts.bak
while [ $# -ne 0 ]; do
echo $1
shift
done
ulimit • 常用选项:
• -a:显示所有资源限制。
• -c:限制核心转储文件大小(ulimit -c 0禁用)。
• -f:限制进程创建文件的最大大小。
• 示例:
bash
复制
ulimit -a # 显示当前限制
ulimit -c 1000 # 允许生成最大1000块的核心转储文件
eval与exec • eval:解析参数并执行生成的命令,常用于动态构造命令。
bash
复制
cmd="ls -l"
eval $cmd # 执行"ls -l"
• exec:执行命令并替换当前Shell进程,后续脚本不再执行。
bash
复制
exec /bin/bash # 替换当前Shell为Bash
type • 用途:判断命令类型(内建/外部)及路径。
bash
复制
type pwd # 输出:pwd is a shell builtin
type cp # 输出:cp is /bin/cp
wait • 用途:等待子进程结束,用于并发任务同步。
bash
复制
sleep 5 & # 后台运行sleep
wait # 等待所有后台进程完成
4. 应用场景与最佳实践
• 性能优化:优先使用内建命令(如pwd而非/bin/pwd)。
• 脚本调试:利用set -x和times分析执行流程与耗时。
• 资源管理:通过ulimit防止脚本耗尽系统资源(如限制文件大小)。
• 参数处理:使用set和shift动态管理脚本参数。
• 进程控制:wait和trap实现进程同步与信号处理。
5. 注意事项
• 命令冲突:若需调用外部命令,需指定完整路径(如/bin/pwd)。
• 资源限制:ulimit设置可能因系统默认值不同而需调整,建议在脚本初始化时配置。
• 安全性:eval执行动态命令存在风险,需谨慎处理不可信输入。
掌握这些嵌入命令的使用,能够显著提升Shell脚本的效率和可控性,尤其在资源管理、调试和并发处理等场景中表现突出。
第25章深入讨论 << 的总结
1. 基础回顾
<<(here文档)用于将多行输入传递给命令,格式为:
sh
复制
command << delimiter
输入内容
delimiter
delimiter 是自定义的结束标记,输入内容直到再次遇到该标记为止。
2. 核心应用场景
2.1 快速创建文件
-
用法
:通过
cat命令和
<<直接输入文件内容。
sh
复制
cat >> myfile << NEWFILE 文本内容 NEWFILE -
注意事项
:
-
若内容含
tab,需使用
<<-忽略行首的制表符(兼容老版本Shell):
sh
复制
cat >> myfile <<- NEWFILE Tab缩进的文本 NEWFILE
-
2.2 快速生成打印文档
-
用法
:直接发送多行文本到打印机或其他命令(如
lpr)。
sh
复制
lpr << QUICKDOC 会议通知:下周举办星际迷航大会。 票价请电话咨询。 QUICKDOC
2.3 自动选择菜单
-
场景
:自动化交互式脚本的菜单选择(如数据库备份)。
sh
复制
/usr/local/sybin/syb_backup >> $log_f 2>&1 << MAYDAY 2 3 Y MAYDAY -
关键点
:
- 通过预设输入序列模拟用户选择(如
2→3→Y)。 - 输出重定向到日志文件(
>> $log_f 2>&1),便于调试。
- 通过预设输入序列模拟用户选择(如
2.4 自动FTP传输
-
脚本实现
:
sh
复制
ftp -i -n $DEST_HOST << FTPIT user anonymous $USER@$THIS_HOST $MODE get $FILENAME $DIREC/$FILENAME.ftp quit FTPIT -
功能细节
:
-i关闭交互提示,-n禁止自动登录。- 支持二进制/ASCII传输模式选择,默认路径为
/tmp。 - 错误检查:若目录不存在,回退到默认路径。
2.5 连接数据库
-
场景
:批量执行数据库操作(如启用
select into功能)。
sh
复制
for db in $DATABASES; do su sybase -c '/sybase/bin/isql -Usa -P$PASSWORD' << MAYDAY use master go sp_dboption $db, "select into/bulkcopy/pllsort", true go use $db go checkpoint go MAYDAY done -
优势:循环遍历数据库,自动发送SQL指令,无需手动交互。
3. 高级技巧与注意事项
-
默认值处理: 使用
${VAR:=default}设置变量默认值,提升脚本健壮性。sh
复制
echo -n "Enter host [default: my_host]: " read DEST_HOST : ${DEST_HOST:=my_host} -
错误处理与日志:
- 重定向输出到日志文件:
command >> logfile 2>&1。 - 检查文件是否存在:
if [ -s $file ]; then ...。
- 重定向输出到日志文件:
-
兼容性:
- 避免依赖特定Shell特性(如
<<-处理缩进)。 - 测试不同Shell环境(如
bash、sh)。
- 避免依赖特定Shell特性(如
4. 小结
-
核心价值:
<<是Shell脚本中强大的输入重定向工具,适用于:- 快速生成文件或文档。
- 自动化交互式流程(菜单、FTP、数据库操作)。
- 与外部工具(如
ftp、isql)集成。
-
优势:
- 减少手动操作,提高效率。
- 通过脚本复用降低维护成本。
- 结合日志和错误检查增强可靠性。
-
适用场景:
- 定时任务(如
cron自动备份)。 - 批量处理(如多数据库配置)。
- 快速生成临时文件或报告。
- 定时任务(如
通过灵活运用 <<,开发者可以简化复杂任务,将交互式操作转化为自动化流程,显著提升脚本的功能性和可维护性。
第26章 Shell工具总结与详细解释
本章介绍了Shell脚本中常用的工具和技术,包括文件管理、信号处理、命令解析和日志记录。以下是对各部分的详细总结:
1. 创建日志和临时文件
• 目的:生成唯一命名的文件,便于管理和清理。
• 关键工具:
• date命令:生成格式化的日期字符串。
◦ 示例:`date +%d%m%y` 输出日、月、年(如 `090699`)。
◦ 常用格式符:`%d`(日),`%m`(月),`%Y`(四位年),`%T`(时间,如 `10:29:41`)。
• 进程ID($$):生成唯一的临时文件名后缀。
◦ 示例:`/tmp/hold1.$$` 生成类似 `/tmp/hold1.1234` 的文件。
• 应用场景:
• 日志文件:按日期命名(如 backup_log.090699)。
• 临时文件:脚本结束时通过 rm /tmp/*.$$ 清理。
2. 信号处理
• 信号(Signal):系统向进程发送的事件通知(如中断、终止)。
• 常见信号:
| 信号编号 | 名称 | 说明 |
|----------|----------|------------------------|
| 1 | SIGHUP | 终端挂起 |
| 2 | SIGINT | 键盘中断(Ctrl+C) |
| 9 | SIGKILL | 强制终止(不可捕获) |
| 15 | SIGTERM | 软件终止(默认信号) |
• trap命令:捕获信号并执行指定操作。
• 语法:trap "command" signal_list
• 示例:
```bash
trap "my_exit" 2 3 15 # 捕获信号2/3/15时执行my_exit函数
trap "" 2 # 忽略信号2(Ctrl+C无效)
trap - 2 # 恢复默认信号处理
```
• 应用场景:
◦ 清理临时文件:脚本退出前删除临时文件。
◦ 用户确认退出:捕获中断信号时提示用户确认。
◦ 锁终端:防止意外中断关键操作(如密码输入)。
3. eval命令 • 功能:对参数进行两次解析(变量替换 + 命令执行)。
• 应用场景:
• 动态执行命令:变量存储命令字符串时,通过eval解析执行。
```bash
CMD="echo Hello"
eval $CMD # 输出 Hello
```
• 间接引用变量:通过变量名动态获取值。
```bash
VAR="value"
NAME="VAR"
eval echo \$$NAME # 输出 value
```
• 解析复杂输入:从文件读取变量名和值并动态设置。
```bash
while read NAME VALUE; do
eval "$NAME=$VALUE"
done < data.txt
```
4. logger命令 • 功能:向系统日志(如 /var/log/messages)写入消息。
• 语法:logger -p 优先级 -i "消息"
• 优先级:notice(默认)、info、debug等。
• 选项:-i 记录进程ID。
• 应用场景:
• 脚本监控:记录脚本启动、结束或错误。
• 审计日志:跟踪用户登录或关键操作。
• 示例:
```bash
logger -p notice "Script $0 started by $USER"
# 日志条目示例:Jun 17 11:02:53 hostname user: Script test.sh started by dave
```
关键实践建议
-
文件管理: • 使用日期或进程ID确保文件名唯一。
• 始终在脚本退出前清理临时文件。
-
信号处理: • 关键操作期间忽略中断信号(如文件写入)。
• 提供用户友好的退出确认机制。
-
eval使用注意: • 避免执行未经验证的字符串,防止安全漏洞。 -
日志记录: • 重要脚本应记录运行状态至系统日志,便于故障排查。
示例脚本解析
• 按日期创建日志文件:
bash
复制
LOGFILE="/logs/backup_$(date +%d%m%y)"
touch $LOGFILE
• 捕获信号并清理:
bash
复制
trap "rm -f /tmp/*.$$; exit" 2 3 15
• 动态变量赋值:
bash
复制
eval "echo \$$VARNAME" # 间接引用变量值
通过掌握这些工具,可以编写更健壮、可维护的Shell脚本,有效管理系统资源并处理异常情况。
第28章 运行级别脚本总结
1. 运行级别概述
• 定义:运行级别(Runlevel)定义了系统的操作状态,每个级别对应特定的服务集合。Linux系统基于System V初始化机制,使用运行级别管理启动和停止服务的顺序。
• 级别划分:
• 0:关机。
• 1(单用户模式):仅root可登录,用于系统维护。
• 2:多用户模式(部分网络服务不启动,某些系统作为默认)。
• 3:完整多用户模式(带网络服务)。
• 4:用户自定义(通常未使用)。
• 5:图形界面模式(某些系统)或维护模式。
• 6:重启。
2. 运行级别目录结构
• 目录位置:/etc/rcN.d 或 /etc/rc.d/rcN.d(N为运行级别数字)。
• 目录内容:包含以 S(启动)或 K(停止)开头的符号链接,指向 /etc/init.d 或 /etc/rc.d/init.d 中的实际脚本。
• 命名规则:
• SnnName:启动脚本,nn为两位数字(如S20network),按升序执行。
• KnnName:停止脚本,按降序执行(如K50httpd)。
• 例如:S35rc.audit 表示在运行级别启动顺序为35的审核服务。
3. 创建运行级别脚本
• 脚本要求:
- 必须接受
start和stop参数,可选restart、status。 - 脚本路径通常位于
/etc/init.d或/etc/rc.d/init.d。 • 示例脚本:
bash
复制
#!/bin/sh
case "$1" in
start)
/apps/audit/audlcp -a -p 12
touch /var/lock/subsys/rc.audit ;;
stop)
/apps/audit/audidown -k0
rm -f /var/lock/subsys/rc.audit ;;
restart)
$0 stop; $0 start ;;
*) echo "Usage: $0 {start|stop|restart}"; exit 1 ;;
esac
exit 0
• 部署步骤:
-
测试脚本:确保手动执行
start/stop正确。 -
将脚本放入
/etc/init.d。 -
在目标运行级别的
rcN.d目录创建符号链接:
bash
复制
ln -s ../init.d/rc.audit /etc/rc3.d/S35rc.audit # 启动 ln -s ../init.d/rc.audit /etc/rc6.d/K35rc.audit # 停止
4. inittab 文件
• 作用:/etc/inittab 是 init 进程的配置文件,定义默认运行级别和系统初始化流程。
• 条目格式:id:runlevels:action:process。
• 示例:
```ini
id:3:initdefault: # 默认运行级别3
si::sysinit:/etc/rc.d/rc.sysinit # 系统初始化脚本
15:5:wait:/etc/rc.d/rc 5 # 运行级别5执行/etc/rc.d/rc5.d
```
• 特殊操作:
• respawn:进程终止后自动重启(如终端服务)。
• once:进程运行一次后不重启。
5. 其他启动方法
• rc.local:位于 /etc/rc.local,系统初始化后执行的自定义命令。
• inittab 直接调用:添加条目到 /etc/inittab,如:
ini
复制
rc.diskchecker:3:once:/usr/local/etc/rc.diskchecker >/dev/console 2>&1
6. 关键命令与工具
• 查看运行级别:
• who -r 或 runlevel(显示当前和前一个运行级别)。
• 切换运行级别:
• init N(N为目标级别,如 init 6 重启)。
7. 注意事项
• 备份配置:修改 /etc/inittab 前需备份,错误可能导致系统无法启动。
• 锁文件管理:某些系统通过 /var/lock/subsys 跟踪服务状态。
• 顺序冲突:确保脚本的数字序号不与现有服务冲突,避免依赖问题。
8. 跨发行版差异
• 路径差异:
• Red Hat/CentOS:/etc/rc.d/init.d 和 /etc/rc.d/rcN.d。
• Debian/Ubuntu:/etc/init.d 和 /etc/rcN.d。
• 工具差异:部分系统使用 systemd 替代传统SysV init(需适配)。
9. 调试与验证
• 手动测试:直接运行脚本检查输出和日志。
• 查看日志:/var/log/boot.log 或 dmesg 排查启动问题。
通过掌握运行级别脚本的配置,可灵活控制系统服务的启动与停止,满足不同场景需求。第29章 CGI脚本总结
29章 CGI基础与配置
• CGI作用:作为Web服务器与脚本的接口,支持动态内容生成,可用Shell等语言实现。
• 环境配置:
• Web服务器(如Apache)需启用CGI,修改ScriptAlias配置指向cgi-bin目录。
• 脚本需有执行权限(chmod 755),文件后缀通常为.cgi。
• 日志文件(如Apache的error_log)用于调试。
2. 基本CGI脚本
• 结构要求:
• 首行指定解释器(如#!/bin/sh)。
• 输出必须包含MIME类型头(Content-type: text/html)和空行。
• 使用HTML标签构建页面。
• 示例脚本:
sh
复制
# firstpage.cgi
echo "Content-type: text/html"
echo ""
echo "<HTML><H1>Hello CGI!</H1></HTML>"
• 访问方式:http://server/cgi-bin/firstpage.cgi。
3. 动态内容生成
• 嵌入Shell命令:通过反引号或变量获取系统信息(如date、who)。
sh
复制
# pagetwo.cgi
USERS=$(who | wc -l)
echo "当前用户数:$USERS"
• 预格式化文本:使用<PRE>标签保留空格和格式,适合展示命令输出(如df)。
4. 服务器端内嵌(SSI)
• 启用SSI:修改Apache配置(AddType text/html .shtml)。
• 内嵌脚本:在.shtml文件中使用<!--#exec cgi="脚本路径"-->。
• 访问计数器示例:
• hitcount.cgi更新计数器文件。
• SSI页面显示计数和最后修改时间:
```html
<!-- main.shtml -->
访问次数:<!--#exec cgi="/cgi-bin/hitcount.cgi"-->
最后修改:<!--#echo var="LAST_MODIFIED"-->
```
5. GET与POST方法
• GET方法:
• 参数附加在URL(QUERY_STRING环境变量)。
• 适用于简单数据,有长度限制且可见。
• POST方法:
• 数据通过标准输入传递,更安全,适合敏感信息。
• 使用CONTENT_LENGTH获取数据长度。
• 参数解码:
• 替换+为空格,%xx为对应ASCII字符。
• 示例代码片段:
```sh
# 处理POST数据
if [ "$REQUEST_METHOD" = "POST" ]; then
QUERY_STRING=$(cat -)
fi
```
6. 表单处理与交互
• 表单构建:
• 使用<FORM>标签,指定action和method。
• 元素包括输入框、下拉菜单、单选框等。
• 示例表单处理:
• booka.cgi生成表单,conv.cgi解码参数。
• 动态生成报表(gifts_result.cgi根据用户选择计算销售额)。
7. 动态填充与自动刷新
• 填充下拉列表:从文件读取选项,循环生成<OPTION>。
sh
复制
while read LINE; do
echo "<OPTION>$LINE"
done < list.txt
• 自动刷新页面:通过<meta http-equiv="Refresh">定时重载。
html
运行
复制
<meta http-equiv="Refresh" content="60; URL=脚本地址">
8. 调试与安全
• 常见错误:
• 权限问题:确保脚本和计数器文件可读写(如chmod 666 counter)。
• 缺少MIME头或空行导致页面无法渲染。
• 安全建议:
• 避免使用root运行Web服务器,限制nobody用户权限。
• 过滤用户输入,防止命令注入。
9. 实际应用示例 • 文件系统监控:dfspace.cgi定时刷新显示磁盘使用情况。
sh
复制
df | awk '{print $5, $6}' | while read percent mount; do
echo "<TR><TD>$percent</TD><TD>$mount</TD></TR>"
done
总结
本章详细讲解了如何通过Shell编写CGI脚本,涵盖静态页面生成、动态内容嵌入、表单交互、参数解析及安全实践。通过结合SSI和HTTP方法(GET/POST),开发者能创建功能丰富的Web应用,如访问计数器、动态报表和实时监控页面。关键点包括正确配置服务器环境、遵循CGI输出规范、合理处理用户输入,以及利用Shell脚本灵活生成HTML内容。
常用 Shell 命令总结
1. 文件路径操作
• basename
• 用途:从路径中提取文件名。
• 示例:
```bash
$ basename /home/dave/myscript # 输出:myscript
```
• 脚本应用:basename $0 获取当前脚本名。
• dirname
• 用途:从路径中提取目录部分。
• 示例:
```bash
$ dirname /home/dave/myfile # 输出:/home/dave
```
2. 文件内容查看与操作
• cat
• 用途:显示、合并文件内容或通过管道读取文件。
• 选项:
◦ `-v`:显示控制字符。
• 示例:
```bash
$ cat myfile # 显示文件内容
$ cat file1 file2 >> hold # 合并文件到 hold
```
• head
• 用途:显示文件前 N 行(默认 10 行)。
• 选项:
◦ `-n <数字>`:指定行数。
• 示例:
```bash
$ head -30 logfile | more # 分页显示前 30 行
```
• more / pg
• 用途:分页显示文件内容。
• 选项:
◦ `-c`:不滚屏,覆盖换页。
◦ `-d`:显示分页提示。
• 示例:
```bash
$ more /etc/passwd # 分页查看系统账户文件
```
• nl
• 用途:为文件内容添加行号。
• 选项:
◦ `-i <数字>`:行号增量(默认 1)。
◦ `-p`:新页不重置行号。
• 示例:
```bash
$ nl myscript > hold # 带行号输出到文件
```
• strings
• 用途:查看二进制文件中的可读文本。
• 示例:
```bash
$ strings /bin/ls # 显示 ls 二进制文件中的字符串
```
3. 文件压缩与解压
• compress / uncompress
• 用途:压缩文件(生成 .Z 后缀)或解压。
• 选项:
◦ `-v`:显示压缩进度。
• 示例:
```bash
$ compress myfile # 压缩为 myfile.Z
$ uncompress myfile.Z # 解压(无需指定后缀)
```
4. 文件与目录管理
• cp
• 用途:复制文件或目录。
• 选项:
◦ `-i`:覆盖前确认。
◦ `-p`:保留权限和时间戳。
◦ `-r`:递归复制目录。
• 示例:
```bash
$ cp -r /logs /hold/logs # 递归复制目录
```
• rm
• 用途:删除文件或目录。
• 选项:
◦ `-i`:删除前确认。
◦ `-r`:递归删除目录。
• 示例:
```bash
$ rm -r /var/spool/tmp # 删除目录及其内容
```
• mkdir / rmdir
• mkdir:创建目录。
◦ 选项:`-m` 设置权限。
```bash
$ mkdir -m 755 HOLD_AREA # 创建并设置权限为 755
```
• rmdir:删除空目录。
◦ 选项:`-p` 递归删除空目录。
```bash
$ rmdir /var/spool/lp_HP # 删除空目录
```
• touch
• 用途:创建空文件或更新文件时间戳。
• 选项:
◦ `-t MMDDhhmm`:指定时间戳。
• 示例:
```bash
$ touch -t 06100930 myfile2 # 创建带指定时间戳的文件
```
5. 文件比较与统计
• diff
• 用途:比较文件差异。
• 选项:
◦ `-c`:标准格式输出差异。
◦ `-I`:忽略大小写。
• 示例:
```bash
$ diff -c file1 file2 # 显示格式化差异
```
• dircmp
• 用途:比较两个目录内容。
• 选项:
◦ `-s`:仅显示不同文件。
• 示例:
```bash
$ dircmp dir1 dir2 # 列出目录差异
```
• wc
• 用途:统计行数、单词数、字符数。
• 选项:
◦ `-l`:仅统计行数。
◦ `-w`:仅统计单词数。
◦ `-c`:仅统计字符数。
• 示例:
```bash
$ who | wc -l # 统计当前登录用户数
```
6. 系统信息与进程管理
• fuser
• 用途:显示或终止访问文件的进程。
• 选项:
◦ `-k`:终止进程。
◦ `-u`:显示进程及用户。
• 示例:
```bash
$ fuser -k /dev/hda5 # 终止访问设备的所有进程
```
• uname
• 用途:显示系统信息。
• 选项:
◦ `-a`:显示全部信息(系统名、版本等)。
• 示例:
```bash
$ uname -a # 输出:Linux bumper...2.0.36
```
• shutdown
• 用途:关闭或重启系统。
• 示例:
```bash
$ shutdown -g60 -I6 -y # 60 秒后关机并重启
```
7. 脚本与用户管理
• sleep
• 用途:暂停脚本执行指定秒数。
• 示例:
```bash
sleep 10 # 等待 10 秒
```
• logname / whoami
• logname:显示当前登录用户名。
• whoami:显示执行命令的用户名。
• 示例:
```bash
$ logname # 输出:dave
```
• script
• 用途:记录终端会话到文件。
• 选项:
◦ `-a`:追加到文件。
• 示例:
```bash
$ script mylogin # 开始记录会话到 mylogin
```
8. 其他实用命令
• printf
• 用途:格式化输出(类似 C 语言)。
• 格式符:
◦ `%s`(字符串)、`%d`(数字)、`\n`(换行)。
• 示例:
```bash
$ printf "%-10s Stand-by\n" "Server" # 左对齐输出
```
• whereis
• 用途:查找命令的二进制文件、手册路径。
• 示例:
```bash
$ whereis ls # 输出:/bin/ls /usr/share/man...
```
• tty
• 用途:显示当前终端设备路径。
• 示例:
```bash
$ tty # 输出:/dev/tty08
```
9. 进程与等待
• wait
• 用途:等待后台进程结束。
• 示例:
```bash
wait 1299 # 等待进程 ID 1299
wait # 等待所有后台进程
```
总结说明
以上命令覆盖了文件操作、系统管理、脚本编写等常见场景。使用需注意: • 危险操作(如 rm -r、fuser -k)需谨慎。
• 脚本技巧:basename $0 获取脚本名,sleep 控制执行节奏。
• 系统命令:shutdown 和 uname 因系统差异可能选项不同,建议查阅手册(man)。
Linux高手