一、Shell 基础
1. Shell 的分类
- Bash(Bourne Again SHell):Linux/macOS 默认 Shell,功能强大,兼容
sh
。 - Zsh:增强版 Bash,支持主题(如 Oh My Zsh)、智能补全。
- Fish:友好的交互式 Shell,自动建议和语法高亮。
- PowerShell:Windows 的现代 Shell,支持 .NET 和面向对象编程。
2. Shell 的作用
- 命令行交互:执行系统命令(如
ls
、cd
、grep
)。 - 脚本编程:编写自动化脚本(如备份、部署、监控)。
- 系统管理:配置环境变量、启动服务、管理用户权限。
二、Shell 脚本基础
1. 脚本结构
#!/bin/bash # 指定解释器
# 注释行
echo "Hello, World!" # 执行命令
2. 变量
name="Alice" # 定义变量(不要加 $)
echo "Hello, $name" # 引用变量
readonly PI=3.14 # 只读变量
unset name # 删除变量
3. 输入 / 输出
echo "输出文本"
read -p "请输入: " var # 读取用户输入
echo "这是错误信息" >&2 # 输出到错误流
4. 命令替换
date=$(date) # 方式1:使用 $()
date=`date` # 方式2:使用反引号
echo "当前日期: $date"
三、条件判断
1. 基本语法
if [ 条件 ]; then命令1
elif [ 条件2 ]; then命令2
else命令3
fi
2. 条件表达式
- 文件测试:
[ -e 文件 ]
(存在)、[ -f 文件 ]
(普通文件)、[ -d 目录 ]
。 - 数值比较:
[ $a -eq $b ]
(等于)、[ $a -gt $b ]
(大于)。 - 字符串比较:
[ "$str1" = "$str2" ]
(相等)、[ -z "$str" ]
(为空)。 - 逻辑运算符:
[ 条件1 ] && [ 条件2 ]
(与)、[ 条件1 ] || [ 条件2 ]
(或)。
四、循环控制
1. for 循环
# 遍历列表
for fruit in apple banana orange; doecho "水果: $fruit"
done# C 风格循环
for ((i=1; i<=5; i++)); doecho "计数: $i"
done# 遍历文件
for file in *.txt; doecho "处理文件: $file"
done
2. while 循环
count=1
while [ $count -le 3 ]; doecho "循环 $count"((count++))
done# 读取文件内容
while read line; doecho "行内容: $line"
done < data.txt
3. until 循环
n=1
until [ $n -gt 3 ]; do # 条件为假时执行echo "n = $n"((n++))
done
4. 循环控制命令
# break:跳出整个循环
for i in {1..5}; doif [ $i -eq 3 ]; then break; fiecho $i # 输出 1, 2
done# continue:跳过当前循环
for i in {1..5}; doif [ $i -eq 3 ]; then continue; fiecho $i # 输出 1, 2, 4, 5
done
五、函数
1. 函数定义与调用
# 方式1:使用 function 关键字
function greet() {echo "你好, $1!" # $1 是第一个参数
}# 方式2:省略 function 关键字
add() {return $(( $1 + $2 )) # 返回状态码
}# 调用函数
greet "张三" # 输出: 你好, 张三!
add 3 5
echo "结果: $?" # $? 获取返回值
2. 参数与返回值
# 参数访问
show_params() {echo "参数总数: $#" # $# 是参数个数echo "所有参数: $*" # $* 是所有参数echo "第2个参数: $2"
}show_params "a" "b" "c" # 输出: 参数总数=3, 第2个参数=b# 返回值示例
divide() {if [ $2 -eq 0 ]; thenecho "错误: 除数为0" >&2return 1 # 非零表示错误fiecho $(( $1 / $2 )) # 通过 echo 返回结果return 0 # 成功
}result=$(divide 10 2) # 捕获 echo 输出
echo "结果: $result" # 输出: 5
3. 局部变量
global_var="全局"my_function() {local local_var="局部" # 使用 local 声明局部变量echo "$local_var, $global_var" # 输出: 局部, 全局
}my_function
echo $local_var # 错误: 局部变量已销毁
六、数组
# 定义数组
fruits=("apple" "banana" "cherry")# 访问元素
echo ${fruits[0]} # 输出: apple# 获取长度
echo ${#fruits[@]} # 输出: 3# 遍历数组
for fruit in "${fruits[@]}"; doecho "水果: $fruit"
done# 添加元素
fruits+=("orange")
七、文件操作
1. 文件测试
file="test.txt"
if [ -e "$file" ]; thenecho "文件存在"if [ -f "$file" ]; thenecho "是普通文件"fi
fi
2. 文件内容处理
# 统计行数
lines=$(wc -l < data.txt)
echo "共 $lines 行"# 查找文本
grep "ERROR" log.txt > errors.txt# 读取文件
while read line; doecho "行: $line"
done < data.txt
八、高级技巧
1. 命令组合
# 管道
ls -la | grep ".txt" # 列出所有 txt 文件# 逻辑运算符
command1 && command2 # command1 成功时执行 command2
command1 || command2 # command1 失败时执行 command2
2. 参数扩展
filename="document.txt"
echo ${filename%.txt} # 移除后缀: document
echo ${filename:0:3} # 截取前3个字符: doc
3. 正则表达式
str="Hello123World"
if [[ $str =~ [0-9]+ ]]; thenecho "包含数字"
fi
4. 调试技巧
#!/bin/bash -x # 开启调试模式
set -e # 命令失败时立即退出
set -u # 访问未定义变量时报错# 代码...
九、实战示例
1. 备份脚本
#!/bin/bash# 备份脚本
SOURCE="/data/files"
BACKUP="/backup/$(date +%Y%m%d)"mkdir -p "$BACKUP"
cp -r "$SOURCE"/* "$BACKUP/"if [ $? -eq 0 ]; thenecho "备份成功: $BACKUP"
elseecho "备份失败" >&2exit 1
fi
2. 菜单系统
#!/bin/bashshow_menu() {echo "1. 查看文件"echo "2. 创建文件"echo "3. 退出"read -p "选择: " choicecase $choice in1) ls -la ;;2) read -p "文件名: "; touch "$REPLY" ;;3) exit 0 ;;*) echo "无效选择" ;;esac
}while true; doshow_menu
done