
Shell练习题集锦:测试工程师必备技能
大约 9 分钟
Shell练习题集锦:测试工程师必备技能
纸上得来终觉浅,绝知此事要躬行。学会了Shell基础语法,是时候来点实战练习了!这些题目都是从实际测试工作中提炼出来的,掌握了它们,你就能在日常工作中游刃有余。
基础命令篇
1. 说下知道的Linux命令,越多越好
测试工程师常用命令清单:
# 文件操作类
ls, ll, cd, pwd, mkdir, rmdir, rm, cp, mv, find, locate, which, whereis
# 文本处理类
cat, less, more, head, tail, grep, awk, sed, sort, uniq, wc, cut
# 系统监控类
ps, top, htop, free, df, du, lsof, netstat, ss, iostat, vmstat
# 网络测试类
ping, curl, wget, telnet, nc, nmap, traceroute
# 进程管理类
kill, killall, jobs, nohup, screen, tmux
# 权限管理类
chmod, chown, chgrp, umask, sudo, su
# 压缩解压类
tar, gzip, gunzip, zip, unzip, 7z
# 测试专用类
ab, wrk, jmeter (命令行模式), siege2. 如何在Linux目录下找到最大的三个文件?
多种解决方案:
# 方案1:使用find + sort (推荐)
find /path/to/directory -type f -exec ls -la {} \; | sort -k5 -nr | head -3
# 方案2:使用du命令
du -a /path/to/directory | sort -nr | head -3
# 方案3:更精确的文件大小显示
find /path/to/directory -type f -printf '%s %p\n' | sort -nr | head -3
# 方案4:人性化显示文件大小
find /path/to/directory -type f -exec du -h {} \; | sort -hr | head -3实际测试场景应用:
# 查找测试日志目录中最大的3个日志文件
find /var/log/test_logs -name "*.log" -type f -exec ls -lh {} \; | sort -k5 -hr | head -3
# 查找测试报告目录中最大的文件
find ./test_reports -type f -printf '%s %p\n' | sort -nr | head -33. 查询文件中某个字符串出现的次数
多种统计方法:
# 方案1:使用grep统计行数
grep -c "error" test.log
# 方案2:统计字符串出现的总次数(包括一行中多次出现)
grep -o "error" test.log | wc -l
# 方案3:忽略大小写统计
grep -i -c "ERROR" test.log
# 方案4:使用awk统计
awk '/error/{count++} END{print count+0}' test.log
# 方案5:统计多个文件中的出现次数
grep -c "error" *.log测试场景实例:
# 统计测试日志中错误出现次数
grep -c "ERROR\|FAIL\|Exception" test_result.log
# 统计API测试中成功响应次数
grep -c "200 OK" api_test.log
# 统计性能测试中超时次数
grep -o "timeout" performance.log | wc -l4. 用Shell写个定时任务
crontab定时任务:
# 编辑定时任务
crontab -e
# 查看当前定时任务
crontab -l
# 删除所有定时任务
crontab -r实用的测试定时任务示例:
# 每天凌晨2点执行自动化测试
0 2 * * * /home/tester/scripts/daily_test.sh >> /var/log/daily_test.log 2>&1
# 每小时检查一次服务状态
0 * * * * /home/tester/scripts/health_check.sh
# 每周一上午9点生成测试报告
0 9 * * 1 /home/tester/scripts/weekly_report.sh
# 每5分钟监控系统资源
*/5 * * * * /home/tester/scripts/monitor_system.sh
# 每天晚上11点清理测试日志(保留7天)
0 23 * * * find /var/log/test_logs -name "*.log" -mtime +7 -delete定时任务脚本示例:
#!/bin/bash
# daily_test.sh - 每日自动化测试脚本
# 设置环境变量
export PATH=/usr/local/bin:$PATH
export TEST_ENV=production
# 记录开始时间
echo "$(date): 开始执行每日自动化测试" >> /var/log/daily_test.log
# 执行测试套件
cd /home/tester/automation_tests
python -m pytest tests/ --html=reports/daily_report_$(date +%Y%m%d).html
# 检查测试结果
if [ $? -eq 0 ]; then
echo "$(date): 测试执行成功" >> /var/log/daily_test.log
# 发送成功通知
curl -X POST "https://hooks.slack.com/your_webhook" \
-d '{"text":"每日自动化测试执行成功!"}'
else
echo "$(date): 测试执行失败" >> /var/log/daily_test.log
# 发送失败通知
curl -X POST "https://hooks.slack.com/your_webhook" \
-d '{"text":"⚠️ 每日自动化测试执行失败,请检查!"}'
fi进阶实战篇
5. 编写一个日志分析脚本
需求: 分析Web服务器访问日志,统计访问量最高的10个IP地址
#!/bin/bash
# log_analyzer.sh - 日志分析脚本
log_file="/var/log/nginx/access.log"
if [ ! -f "$log_file" ]; then
echo "错误:日志文件 $log_file 不存在"
exit 1
fi
echo "=== 访问量最高的10个IP地址 ==="
awk '{print $1}' "$log_file" | sort | uniq -c | sort -nr | head -10
echo -e "\n=== 最常访问的10个页面 ==="
awk '{print $7}' "$log_file" | sort | uniq -c | sort -nr | head -10
echo -e "\n=== HTTP状态码统计 ==="
awk '{print $9}' "$log_file" | sort | uniq -c | sort -nr6. 批量处理测试数据文件
需求: 将目录下所有CSV文件的第一列数据提取出来,合并到一个新文件中
#!/bin/bash
# merge_csv_data.sh
input_dir="./test_data"
output_file="merged_data.csv"
# 检查输入目录是否存在
if [ ! -d "$input_dir" ]; then
echo "错误:目录 $input_dir 不存在"
exit 1
fi
# 清空输出文件
> "$output_file"
# 处理所有CSV文件
for csv_file in "$input_dir"/*.csv; do
if [ -f "$csv_file" ]; then
echo "处理文件:$csv_file"
# 提取第一列数据(跳过标题行)
awk -F',' 'NR>1 {print $1}' "$csv_file" >> "$output_file"
fi
done
echo "数据合并完成,输出文件:$output_file"
echo "总计 $(wc -l < "$output_file") 条记录"7. 自动化环境检查脚本
需求: 检查测试环境是否就绪(服务状态、端口、磁盘空间等)
#!/bin/bash
# env_check.sh - 环境检查脚本
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 检查结果统计
pass_count=0
fail_count=0
# 检查函数
check_service() {
local service_name=$1
if systemctl is-active --quiet "$service_name"; then
echo -e "${GREEN}✅ 服务 $service_name 运行正常${NC}"
((pass_count++))
else
echo -e "${RED}❌ 服务 $service_name 未运行${NC}"
((fail_count++))
fi
}
check_port() {
local port=$1
local service_name=$2
if netstat -tlnp | grep -q ":$port "; then
echo -e "${GREEN}✅ 端口 $port ($service_name) 正常监听${NC}"
((pass_count++))
else
echo -e "${RED}❌ 端口 $port ($service_name) 未监听${NC}"
((fail_count++))
fi
}
check_disk_space() {
local path=$1
local threshold=$2
local usage=$(df "$path" | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$usage" -lt "$threshold" ]; then
echo -e "${GREEN}✅ 磁盘空间 $path 使用率 ${usage}% (< ${threshold}%)${NC}"
((pass_count++))
else
echo -e "${RED}❌ 磁盘空间 $path 使用率 ${usage}% (>= ${threshold}%)${NC}"
((fail_count++))
fi
}
# 开始检查
echo "=== 测试环境检查开始 ==="
echo "检查时间:$(date)"
echo
# 检查关键服务
echo "--- 服务状态检查 ---"
check_service "nginx"
check_service "mysql"
check_service "redis"
echo
echo "--- 端口检查 ---"
check_port "80" "HTTP"
check_port "443" "HTTPS"
check_port "3306" "MySQL"
check_port "6379" "Redis"
echo
echo "--- 磁盘空间检查 ---"
check_disk_space "/" 80
check_disk_space "/var/log" 70
echo
echo "=== 检查结果汇总 ==="
echo -e "通过:${GREEN}$pass_count${NC} 项"
echo -e "失败:${RED}$fail_count${NC} 项"
if [ $fail_count -eq 0 ]; then
echo -e "${GREEN}🎉 环境检查全部通过,可以开始测试!${NC}"
exit 0
else
echo -e "${RED}⚠️ 环境检查发现问题,请修复后再进行测试!${NC}"
exit 1
fi8. 性能测试数据收集脚本
需求: 在性能测试期间收集系统资源使用情况
#!/bin/bash
# performance_monitor.sh - 性能监控脚本
# 配置参数
duration=${1:-60} # 监控时长(秒),默认60秒
interval=${2:-5} # 采样间隔(秒),默认5秒
output_dir="./performance_data"
# 创建输出目录
mkdir -p "$output_dir"
# 生成时间戳
timestamp=$(date +"%Y%m%d_%H%M%S")
# 输出文件
cpu_file="$output_dir/cpu_${timestamp}.log"
memory_file="$output_dir/memory_${timestamp}.log"
disk_file="$output_dir/disk_${timestamp}.log"
network_file="$output_dir/network_${timestamp}.log"
echo "开始性能监控..."
echo "监控时长:${duration}秒"
echo "采样间隔:${interval}秒"
echo "数据保存到:$output_dir"
# 监控函数
monitor_cpu() {
while true; do
echo "$(date '+%Y-%m-%d %H:%M:%S'),$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | sed 's/%us,//')" >> "$cpu_file"
sleep "$interval"
done
}
monitor_memory() {
while true; do
echo "$(date '+%Y-%m-%d %H:%M:%S'),$(free | grep Mem | awk '{printf "%.2f", $3/$2 * 100.0}')" >> "$memory_file"
sleep "$interval"
done
}
monitor_disk() {
while true; do
echo "$(date '+%Y-%m-%d %H:%M:%S'),$(iostat -x 1 1 | grep -E '^[a-z]' | awk '{sum+=$10} END {printf "%.2f", sum}')" >> "$disk_file"
sleep "$interval"
done
}
monitor_network() {
while true; do
echo "$(date '+%Y-%m-%d %H:%M:%S'),$(cat /proc/net/dev | grep eth0 | awk '{print $2,$10}')" >> "$network_file"
sleep "$interval"
done
}
# 启动后台监控
monitor_cpu &
cpu_pid=$!
monitor_memory &
memory_pid=$!
monitor_disk &
disk_pid=$!
monitor_network &
network_pid=$!
# 等待指定时间
sleep "$duration"
# 停止监控
kill $cpu_pid $memory_pid $disk_pid $network_pid 2>/dev/null
echo "监控完成!数据文件:"
echo " CPU使用率:$cpu_file"
echo " 内存使用率:$memory_file"
echo " 磁盘IO:$disk_file"
echo " 网络流量:$network_file"高级挑战篇
9. 实现一个简单的测试框架
需求: 创建一个可以运行多个测试用例的框架
#!/bin/bash
# test_framework.sh - 简单测试框架
# 测试结果统计
total_tests=0
passed_tests=0
failed_tests=0
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m'
# 断言函数
assert_equals() {
local expected=$1
local actual=$2
local message=${3:-"断言失败"}
((total_tests++))
if [ "$expected" = "$actual" ]; then
echo -e "${GREEN}✅ PASS${NC}: $message"
((passed_tests++))
else
echo -e "${RED}❌ FAIL${NC}: $message"
echo " 期望值: $expected"
echo " 实际值: $actual"
((failed_tests++))
fi
}
assert_not_empty() {
local value=$1
local message=${2:-"值不应为空"}
((total_tests++))
if [ -n "$value" ]; then
echo -e "${GREEN}✅ PASS${NC}: $message"
((passed_tests++))
else
echo -e "${RED}❌ FAIL${NC}: $message"
echo " 值为空"
((failed_tests++))
fi
}
# 测试用例
test_string_operations() {
echo -e "${BLUE}--- 测试字符串操作 ---${NC}"
str="Hello World"
assert_equals "Hello World" "$str" "字符串赋值测试"
assert_equals "11" "${#str}" "字符串长度测试"
assert_equals "Hello" "${str%% *}" "字符串截取测试"
}
test_file_operations() {
echo -e "${BLUE}--- 测试文件操作 ---${NC}"
test_file="/tmp/test_file_$$"
echo "test content" > "$test_file"
assert_equals "true" "$([ -f "$test_file" ] && echo true || echo false)" "文件创建测试"
assert_equals "test content" "$(cat "$test_file")" "文件内容测试"
rm -f "$test_file"
assert_equals "false" "$([ -f "$test_file" ] && echo true || echo false)" "文件删除测试"
}
test_math_operations() {
echo -e "${BLUE}--- 测试数学运算 ---${NC}"
result=$((5 + 3))
assert_equals "8" "$result" "加法运算测试"
result=$((10 - 4))
assert_equals "6" "$result" "减法运算测试"
result=$((3 * 4))
assert_equals "12" "$result" "乘法运算测试"
}
# 运行所有测试
run_all_tests() {
echo "=== 开始运行测试 ==="
echo
test_string_operations
echo
test_file_operations
echo
test_math_operations
echo
echo "=== 测试结果汇总 ==="
echo "总计测试: $total_tests"
echo -e "通过: ${GREEN}$passed_tests${NC}"
echo -e "失败: ${RED}$failed_tests${NC}"
if [ $failed_tests -eq 0 ]; then
echo -e "${GREEN}🎉 所有测试通过!${NC}"
exit 0
else
echo -e "${RED}⚠️ 有测试失败!${NC}"
exit 1
fi
}
# 执行测试
run_all_tests10. 综合练习:自动化部署脚本
需求: 编写一个完整的应用部署脚本
#!/bin/bash
# deploy.sh - 自动化部署脚本
set -e # 遇到错误立即退出
# 配置参数
APP_NAME="test-app"
APP_VERSION=${1:-"latest"}
DEPLOY_ENV=${2:-"staging"}
BACKUP_DIR="/opt/backups"
APP_DIR="/opt/apps/$APP_NAME"
LOG_FILE="/var/log/deploy.log"
# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
# 错误处理
error_exit() {
log "ERROR: $1"
exit 1
}
# 检查权限
check_permissions() {
if [ "$EUID" -ne 0 ]; then
error_exit "请使用root权限运行此脚本"
fi
}
# 备份当前版本
backup_current_version() {
if [ -d "$APP_DIR" ]; then
backup_name="${APP_NAME}_$(date +%Y%m%d_%H%M%S)"
log "备份当前版本到 $BACKUP_DIR/$backup_name"
cp -r "$APP_DIR" "$BACKUP_DIR/$backup_name"
fi
}
# 下载新版本
download_new_version() {
log "下载 $APP_NAME 版本 $APP_VERSION"
# 这里模拟下载过程
sleep 2
log "下载完成"
}
# 部署应用
deploy_application() {
log "开始部署应用"
# 停止服务
systemctl stop "$APP_NAME" 2>/dev/null || true
# 部署新版本
mkdir -p "$APP_DIR"
# 这里模拟部署过程
sleep 3
# 启动服务
systemctl start "$APP_NAME"
systemctl enable "$APP_NAME"
log "应用部署完成"
}
# 健康检查
health_check() {
log "执行健康检查"
max_attempts=30
attempt=1
while [ $attempt -le $max_attempts ]; do
if curl -f -s "http://localhost:8080/health" > /dev/null; then
log "健康检查通过"
return 0
fi
log "健康检查失败,重试 $attempt/$max_attempts"
sleep 10
((attempt++))
done
error_exit "健康检查失败,部署回滚"
}
# 主流程
main() {
log "开始部署 $APP_NAME 版本 $APP_VERSION 到 $DEPLOY_ENV 环境"
check_permissions
backup_current_version
download_new_version
deploy_application
health_check
log "部署成功完成!"
}
# 执行主流程
main "$@"总结
这些练习题涵盖了Shell脚本的各个方面:
- 基础命令使用 - 掌握常用Linux命令
- 文本处理 - grep、awk、sed的综合运用
- 系统监控 - 资源使用情况收集
- 自动化测试 - 测试框架的实现
- 运维部署 - 完整的部署流程
学习建议:
- 从简单题目开始,逐步提高难度
- 每个脚本都要实际运行测试
- 注意错误处理和边界情况
- 多思考如何优化和改进
记住:实践是最好的老师!多写、多练、多总结,你很快就能成为Shell脚本专家!
