1️⃣ 进程管理命令
# 查看进程 ps aux # 所有进程详细列表 ps -ef | grep nginx # 查找 nginx 进程 pgrep nginx # 按名称查 PID pgrep -a nginx # 显示完整命令 pidof sshd # 查找进程 PID top # 动态进程监控 htop # 更好用的 top(需安装) # 发送信号 kill 12345 # 发送 SIGTERM(正常终止) kill -9 12345 # 发送 SIGKILL(强制杀死) kill -HUP 12345 # 发送 SIGHUP(重新加载) killall nginx # 按名称杀进程 pkill -f "python app.py" # 按命令行模式杀 bash
常用信号表
| 信号名 | 编号 | 含义 |
|---|---|---|
SIGHUP | 1 | 挂起/重读配置,重启不终止 |
SIGINT | 2 | 中断(Ctrl+C) |
SIGQUIT | 3 | 退出并产生 core dump(Ctrl+\) |
SIGKILL | 9 | 强制终止,不可被捕获 |
SIGTERM | 15 | 正常终止(默认) |
SIGSTOP | 17/19 | 暂停进程,不可被捕获 |
SIGCONT | 18/20 | 恢复暂停的进程 |
SIGUSR1 | 10 | 用户自定义信号1 |
EXIT | 0 | 脚本退出时(trap 特用) |
2️⃣ trap 信号捕获
trap 让脚本能够捕获信号,在中断/退出时执行清理工作。
#!/bin/bash # 清理函数 cleanup() { echo "\n[清理] 正在清理临时文件..." rm -f /tmp/myscript_* echo "[清理] 完成,脚本退出" } # 注册信号处理 trap cleanup EXIT # 脚本任何方式退出时都执行 trap cleanup INT TERM # Ctrl+C 或 kill 时执行 # 创建临时文件 TMP_FILE=$(mktemp /tmp/myscript_XXXXXX) echo "临时文件:$TMP_FILE" # 主要工作 echo "脚本执行中,按 Ctrl+C 可测试清理..." sleep 30 # 忽略信号 trap "" HUP # 忽略 SIGHUP # 恢复默认处理 trap - INT # 恢复 INT 的默认处理 bash
3️⃣ 后台进程管理
# & 放到后台执行 long_task.sh & echo "后台PID: $!" # jobs 查看后台任务 jobs jobs -l # 显示 PID # fg/bg 前后台切换 fg %1 # 将任务1调到前台 bg %1 # 将任务1放到后台继续 # wait:等待后台任务完成 task1.sh & pid1=$! task2.sh & pid2=$! wait $pid1; echo "task1 完成" wait $pid2; echo "task2 完成" wait # 等待所有后台任务 bash
# nohup:关闭终端后继续运行 nohup ./long_script.sh > /var/log/myscript.log 2>&1 & echo "PID: $!" # screen / tmux:会话持久化(更推荐) screen -S mysession # 新建命名会话 screen -ls # 列出所有会话 screen -r mysession # 恢复会话 # 控制并发数(同时最多5个并行任务) max_jobs=5 for item in ${list[@]}; do while [[ $(jobs -r | wc -l) -ge $max_jobs ]]; do sleep 0.5 done process_item "$item" & done wait bash
4️⃣ crontab 定时任务
# crontab 时间格式 # 分(0-59) 时(0-23) 日(1-31) 月(1-12) 周(0-7,0和7均为周日) # *=任意 ,=列举 -=范围 /=步长 # 常用示例 # 每天凌晨2点执行备份 0 2 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1 # 每5分钟检查一次 */5 * * * * /opt/scripts/monitor.sh # 每周一上午9点 0 9 * * 1 /opt/scripts/weekly_report.sh # 每月1日0点 0 0 1 * * /opt/scripts/monthly_cleanup.sh # 每天8:30和17:30 30 8,17 * * * /opt/scripts/notify.sh # 工作日(周一至周五)每小时执行 0 * * * 1-5 /opt/scripts/workday_check.sh # 系统重启时执行 @reboot /opt/scripts/startup.sh cron
# crontab 管理命令 crontab -l # 列出当前用户的定时任务 crontab -e # 编辑定时任务 crontab -r # 删除所有定时任务(危险!) crontab -u root -l # 查看 root 的定时任务 # 系统级 crontab(/etc/crontab 多一个用户字段) # 分 时 日 月 周 用户名 命令 # 0 2 * * * root /opt/scripts/backup.sh # cron 日志 grep CRON /var/log/syslog | tail -20 bash
cron 脚本注意事项cron 的 PATH 很短,脚本中务必使用绝对路径;cron 没有交互终端,不要用 read;务必将输出重定向到日志文件,否则会发邮件或丢失输出。
5️⃣ 规范的日志系统
#!/bin/bash # 生产级日志函数库 # 颜色常量(终端) RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # 重置颜色 # 日志文件路径 LOG_FILE="/var/log/myscript/$(date '+%Y%m%d').log" mkdir -p "$(dirname "$LOG_FILE")" # 日志函数 log() { local level="$1" shift local msg="$*" local ts=$(date '+%Y-%m-%d %H:%M:%S') local color=$NC case "$level" in INFO) color=$GREEN ;; WARN) color=$YELLOW ;; ERROR) color=$RED ;; DEBUG) color=$BLUE ;; esac # 写入文件(无颜色) echo "[$ts] [$level] $msg" >> "$LOG_FILE" # 输出到终端(有颜色) printf "${color}[%s] [%s]${NC} %s\n" "$ts" "$level" "$msg" } log_info() { log INFO "$@"; } log_warn() { log WARN "$@"; } log_error() { log ERROR "$@"; } log_debug() { [[ "${DEBUG:-0}" == "1" ]] && log DEBUG "$@"; } # 使用示例 log_info "脚本启动" log_warn "磁盘使用率超过80%" log_error "备份失败:连接超时" bash
6️⃣ 健壮性错误处理
#!/bin/bash # 生产脚本模板 set -euo pipefail # 严格模式 # 错误处理函数 error_handler() { local exit_code=$? local line_no=$1 log_error "脚本在第 ${line_no} 行执行失败,退出码: ${exit_code}" exit $exit_code } trap 'error_handler $LINENO' ERR # 安全执行命令(失败不退出,返回状态码) run_safe() { if ! "$@"; then log_warn "命令失败(忽略): $*" return 1 fi } # 检查依赖命令 check_deps() { local missing=() for cmd in "$@"; do command -v "$cmd" >/dev/null 2>&1 || missing+=("$cmd") done if [[ ${#missing[@]} -gt 0 ]]; then log_error "缺少依赖命令:${missing[*]}" exit 127 fi } # 使用文件锁防止重复运行 LOCK_FILE="/tmp/$(basename "$0").lock" if ! mkdir "$LOCK_FILE" 2>/dev/null; then log_error "脚本已在运行,退出" exit 1 fi trap "rm -rf '$LOCK_FILE'" EXIT # 检查依赖 check_deps curl jq rsync # 脚本主体... bash
🏋️ 今日练习
- 写一个后台监控脚本,每分钟检查 nginx 进程,若停止则自动重启,并记录日志
- 为你的脚本添加完整的 trap 处理:中断时清理临时文件,错误时记录行号,退出时打印耗时
- 设置5个 crontab 任务:每天备份、每小时清理日志、每周发报告、每天检查磁盘、开机启动检查
- 写一个使用文件锁的脚本,保证同时只有一个实例运行
- 编写一个并行任务脚本,同时向10个服务器检查连通性,等所有检查完成后输出汇总报告