1. Shell编程基础语法精要
1.1 转义字符与终端控制
在Shell脚本中,转义字符是实现特殊功能的关键符号。它们以反斜杠()开头,用于表示无法直接输入的字符或控制终端行为。以下是实际开发中最常用的转义序列:
bash复制echo -e "第一行\n第二行" # \n实现换行
echo -e "文本\t制表符" # \t插入水平制表符
echo -e "\033[31m红色文字\033[0m" # \033设置终端属性
注意:使用echo打印转义字符时,必须添加-e参数启用转义解析。在printf命令中则默认支持转义字符。
1.2 变量命名规范与作用域
Shell变量的命名必须遵循特定规则:
- 只能包含字母、数字和下划线
- 不能以数字开头
- 避免使用Shell保留字(如if、for等)
- 区分大小写(var与VAR是不同的变量)
bash复制合法变量示例:
user_name="Alice"
count_1=100
_temp_file="/tmp/log"
非法变量示例:
2var=10 # 数字开头
user-name="Bob" # 包含连字符
系统预设变量是Shell环境中自动存在的特殊变量,它们在脚本中有着重要作用:
bash复制#!/bin/bash
echo "当前脚本名称: $0"
echo "第一个参数: $1"
echo "参数总数: $#"
echo "所有参数: $@"
echo "上条命令结果: $?"
1.3 字符串格式化输出
printf命令提供了比echo更强大的格式化输出能力。常用的格式说明符包括:
bash复制printf "十进制: %d\n八进制: %o\n十六进制: %x\n" 255 255 255
printf "浮点数: %.2f\n字符串: %s\n" 3.14159 "hello"
格式字符串中可以插入各种转义序列实现精细控制:
bash复制printf "列1\t列2\t列3\n%-10s%5d%8.2f\n" "Item" 100 19.99
2. 正则表达式深度解析
2.1 基本正则表达式核心语法
基本正则(BRE)是Shell工具(grep/sed等)默认支持的模式匹配语言:
bash复制grep '^[A-Z]' file.txt # 匹配以大写字母开头的行
sed -n '/[0-9]\{3,\}/p' data.txt # 匹配至少3个连续数字
BRE中的特殊字符需要转义才能发挥元字符作用:
bash复制echo "a*b" | grep 'a\*b' # 匹配字面量a*b
2.2 扩展正则表达式高级特性
扩展正则(ERE)通过-E选项启用,支持更简洁的语法:
bash复制# 匹配IP地址
echo "192.168.1.1" | grep -E '([0-9]{1,3}\.){3}[0-9]{1,3}'
# 使用或运算
echo "apple banana" | grep -E 'apple|banana'
ERE与BRE的主要区别在于元字符不需要转义:
bash复制# ERE中的量词
echo "aaa" | grep -E 'a{3}'
# 等价BRE
echo "aaa" | grep 'a\{3\}'
2.3 POSIX字符类实战应用
POSIX字符类提供标准化的字符集定义,特别适合国际化场景:
bash复制# 匹配所有标点符号
grep '[[:punct:]]' multilingual.txt
# 匹配非字母字符
tr -cd '[:alpha:]' < mixed_data.txt
字符类可以组合使用实现复杂匹配:
bash复制# 匹配字母数字开头的行
grep '^[[:alnum:]]' documents/*
3. 系统操作与文件测试
3.1 文件属性测试方法
Shell脚本中常用的文件测试操作符:
bash复制if [ -f "/path/to/file" ]; then
echo "常规文件存在"
fi
[ -x "/usr/bin/bash" ] && echo "可执行文件"
复合条件测试示例:
bash复制if [ -r "$file" -a -s "$file" ]; then
echo "文件可读且非空"
fi
3.2 网络诊断工具进阶用法
nmap的基础扫描技巧:
bash复制# 快速扫描局域网存活主机
nmap -sn 192.168.1.0/24
# 扫描目标主机的TCP服务
nmap -sT -p1-1024 target.example.com
cURL获取HTTP请求详细信息:
bash复制curl -o /dev/null -s -w \
'响应码: %{http_code}
下载大小: %{size_download}字节
总时间: %{time_total}秒\n' \
https://example.com
3.3 磁盘分区管理实践
使用parted进行磁盘分区的典型流程:
bash复制sudo parted /dev/sdb mklabel gpt
sudo parted /dev/sdb mkpart primary ext4 1MiB 1GiB
sudo parted /dev/sdb print
重要提示:分区操作会破坏数据,务必先确认目标设备。生产环境建议先备份重要数据。
4. 变量高级操作技巧
4.1 变量测试与默认值设置
变量测试语法在脚本健壮性方面非常有用:
bash复制# 如果未设置PORT,使用默认值8080
listen_port=${PORT:-8080}
# 强制要求配置变量
: ${API_KEY:?"必须设置API_KEY环境变量"}
4.2 字符串操作大全
字符串截取和替换示例:
bash复制path="/usr/local/bin/bash"
echo ${path:5} # 从第5字符开始:local/bin/bash
echo ${path:5:5} # 从第5字符取5个:local
echo ${path#/*/} # 最短掐头:local/bin/bash
echo ${path##/*/} # 最长掐头:bash
echo ${path/bin/sbin} # 替换第一个bin为sbin
大小写转换技巧:
bash复制var="Hello World"
echo ${var^^} # 全部大写
echo ${var,,} # 全部小写
echo ${var^h} # 仅首字母h大写
4.3 数组操作精要
Bash数组的基本使用方法:
bash复制# 声明数组
colors=("red" "green" "blue")
# 访问元素
echo ${colors[1]} # 输出green
# 遍历数组
for color in "${colors[@]}"; do
echo $color
done
# 获取数组长度
echo "共有${#colors[@]}种颜色"
5. 文本处理三剑客实战
5.1 sed流编辑器高级技巧
sed的多命令组合示例:
bash复制# 替换并删除行
sed -e 's/foo/bar/g' -e '/^#/d' config.ini
# 保留空间高级用法
seq 3 | sed -n '1h; 2,3H; ${g; s/\n/:/g;p}'
原地修改文件并备份:
bash复制sed -i.bak 's/old/new/g' important.txt
5.2 awk编程完整示例
awk字段处理典型场景:
bash复制# 统计日志中各IP的访问次数
awk '{ip_count[$1]++} END {for(ip in ip_count) print ip, ip_count[ip]}' access.log
# 计算CSV文件第二列平均值
awk -F, 'NR>1 {sum+=$2; count++} END {print "平均值:",sum/count}' data.csv
5.3 组合工具解决复杂问题
管道组合处理复杂文本:
bash复制# 提取访问量前5的URL
awk '{print $7}' access.log | sort | uniq -c | sort -nr | head -5
# 监控网络连接变化
watch -n 1 "ss -tuna | awk '{print \$5}' | cut -d: -f1 | sort | uniq -c"
6. Shell脚本调试与优化
6.1 脚本调试技巧
set命令的调试选项:
bash复制#!/bin/bash
set -exuo pipefail
# -e: 命令失败时立即退出
# -x: 打印执行的命令
# -u: 使用未定义变量时报错
# -o pipefail: 管道中任意命令失败则整个管道失败
6.2 性能优化建议
提高Shell脚本性能的方法:
bash复制# 避免频繁调用外部命令
# 不好的写法
for i in $(seq 1 100); do
echo $i
done
# 好的写法
for ((i=1; i<=100; i++)); do
echo $i
done
# 使用内置字符串操作代替awk/sed处理简单文本
var="hello world"
echo ${var// /_} # 代替sed 's/ /_/g'
6.3 安全编程规范
安全的Shell脚本编写原则:
bash复制# 总是引用变量
rm "$filename" # 而不是 rm $filename
# 检查文件是否存在
[ -f "$input_file" ] || { echo "错误:文件不存在"; exit 1; }
# 使用陷阱处理信号
trap 'cleanup; exit 1' INT TERM
7. 实用参考数据速查
7.1 ASCII码表核心部分
| 八进制 | 十进制 | 十六进制 | 字符 | 描述 |
|---|---|---|---|---|
| 40 | 32 | 20 | (空格) | 空格符 |
| 41 | 33 | 21 | ! | 感叹号 |
| ... | ... | ... | ... | ... |
| 60 | 48 | 30 | 0 | 数字0 |
| 61 | 49 | 31 | 1 | 数字1 |
| ... | ... | ... | ... | ... |
| 101 | 65 | 41 | A | 大写A |
| 102 | 66 | 42 | B | 大写B |
| ... | ... | ... | ... | ... |
| 141 | 97 | 61 | a | 小写a |
| 142 | 98 | 62 | b | 小写b |
7.2 常用运算符优先级
| 运算符 | 描述 |
|---|---|
++ -- |
自增/自减 |
! ~ |
逻辑/位取反 |
** |
幂运算 |
* / % |
乘、除、取模 |
+ - |
加、减 |
< <= > >= |
比较 |
== != |
相等性 |
&& |
逻辑与 |
| ` | |
?: |
三元条件 |
7.3 Shell选项速查表
| set选项 | shopt选项 | 功能描述 |
|---|---|---|
-e |
errexit |
命令失败时退出 |
-u |
nounset |
使用未定义变量时报错 |
-x |
xtrace |
打印执行的命令 |
-o pipefail |
- | 管道失败时退出 |
- |
nocaseglob| 不区分大小写的文件名扩展 - |
extglob| 启用扩展模式匹配
掌握这些核心规则和技巧后,Shell脚本编写将更加得心应手。在实际开发中,建议将这些表格打印出来作为速查手册,遇到不确定的语法时快速参考。