Shell 脚本中的进程管理包括启动、监控、终止进程以及进程间通信等操作。
进程启动
后台运行
bash# 在后台运行命令 command & # 后台运行并忽略挂起信号 nohup command & # 使用 disown 将进程从当前 shell 分离 command & disown %1
子进程
bash# 使用括号创建子进程 (command1; command2) & # 子进程中的变量不影响父进程 ( local_var="child" echo "Child: $local_var" ) echo "Parent: $local_var" # 输出: Parent: (空)
进程监控
查看进程
bash# 查看所有进程 ps aux # 查看特定用户的进程 ps -u username # 查看特定进程 ps -p PID # 实时监控进程 top htop # 查看进程树 pstree
查找进程
bash# 使用 grep 查找进程 ps aux | grep "nginx" # 使用 pgrep 查找进程 ID pgrep nginx # 使用 pidof 查找进程 ID pidof nginx # 查找进程详细信息 ps -p $(pgrep nginx) -o pid,ppid,cmd
监控进程状态
bash# 检查进程是否运行 if ps -p PID > /dev/null; then echo "Process is running" else echo "Process is not running" fi # 使用 pgrep 检查 if pgrep -x "nginx" > /dev/null; then echo "nginx is running" fi
进程终止
终止进程
bash# 发送 SIGTERM 信号(正常终止) kill PID # 发送 SIGKILL 信号(强制终止) kill -9 PID # 按名称终止进程 pkill process_name # 终止所有匹配的进程 killall process_name
信号类型
bash# 常用信号 kill -l # 列出所有信号 # SIGHUP (1) - 重新加载配置 kill -1 PID # SIGINT (2) - 中断(Ctrl+C) kill -2 PID # SIGTERM (15) - 正常终止 kill -15 PID # SIGKILL (9) - 强制终止 kill -9 PID
等待进程
bash# 启动后台进程 command & PID=$! # 等待进程完成 wait $PID # 等待所有后台进程 wait # 检查进程退出状态 wait $PID exit_status=$? echo "Exit status: $exit_status"
进程间通信
信号通信
bash# 捕获信号的脚本 #!/bin/bash trap 'echo "Received SIGINT"; exit' INT trap 'echo "Received SIGTERM"; exit' TERM while true; do echo "Running..." sleep 1 done
管道通信
bash# 匿名管道 command1 | command2 # 命名管道(FIFO) mkfifo /tmp/my_pipe cat > /tmp/my_pipe & cat < /tmp/my_pipe
文件通信
bash# 使用文件进行通信 lock_file="/tmp/script.lock" # 创建锁文件 if [ -f "$lock_file" ]; then echo "Script is already running" exit 1 fi touch "$lock_file" # 执行任务 # ... # 删除锁文件 rm -f "$lock_file"
实际应用示例
进程守护脚本
bash#!/bin/bash # 守护进程脚本 daemon_process() { local command="$1" local lock_file="/tmp/${command}.lock" # 检查锁文件 if [ -f "$lock_file" ]; then local pid=$(cat "$lock_file") if ps -p "$pid" > /dev/null 2>&1; then echo "$command is already running (PID: $pid)" return 1 else rm -f "$lock_file" fi fi # 启动进程 $command & local pid=$! echo $pid > "$lock_file" echo "Started $command (PID: $pid)" return 0 } # 使用守护进程 daemon_process "nginx"
进程监控脚本
bash#!/bin/bash # 监控进程脚本 monitor_process() { local process_name="$1" local max_memory="$2" # MB local max_cpu="$3" # % while true; do # 获取进程信息 local pid=$(pgrep -x "$process_name") if [ -z "$pid" ]; then echo "$process_name is not running" sleep 5 continue fi # 获取内存使用 local memory=$(ps -p "$pid" -o rss= | awk '{print $1/1024}') # 获取 CPU 使用 local cpu=$(ps -p "$pid" -o %cpu=) echo "$process_name (PID: $pid) - Memory: ${memory}MB, CPU: ${cpu}%" # 检查是否超过阈值 if (( $(echo "$memory > $max_memory" | bc -l) )); then echo "Warning: Memory usage exceeds ${max_memory}MB" fi if (( $(echo "$cpu > $max_cpu" | bc -l) )); then echo "Warning: CPU usage exceeds ${max_cpu}%" fi sleep 5 done } # 使用监控脚本 monitor_process "nginx" 512 80
批量进程管理
bash#!/bin/bash # 批量终止进程 kill_processes() { local pattern="$1" local signal="${2:-15}" local pids=$(pgrep -f "$pattern") if [ -z "$pids" ]; then echo "No processes found matching: $pattern" return 1 fi echo "Killing processes: $pids" kill -$signal $pids sleep 2 # 检查进程是否仍在运行 for pid in $pids; do if ps -p "$pid" > /dev/null 2>&1; then echo "Process $pid still running, forcing kill" kill -9 "$pid" fi done echo "All processes killed" } # 使用批量终止 kill_processes "python.*script.py"
进程重启脚本
bash#!/bin/bash # 进程重启脚本 restart_process() { local process_name="$1" local command="$2" echo "Restarting $process_name..." # 终止进程 local pid=$(pgrep -x "$process_name") if [ -n "$pid" ]; then echo "Stopping $process_name (PID: $pid)" kill "$pid" sleep 2 # 检查是否仍在运行 if ps -p "$pid" > /dev/null 2>&1; then echo "Force killing $process_name" kill -9 "$pid" fi fi # 启动进程 echo "Starting $process_name..." $command & local new_pid=$! sleep 2 # 检查是否启动成功 if ps -p "$new_pid" > /dev/null 2>&1; then echo "$process_name restarted successfully (PID: $new_pid)" return 0 else echo "Failed to start $process_name" return 1 fi } # 使用重启脚本 restart_process "nginx" "nginx -g 'daemon off;'"
进程管理最佳实践
- 使用 nohup 和 disown: 确保进程在 shell 退出后继续运行
- 使用锁文件: 防止重复启动进程
- 优雅地终止进程: 优先使用 SIGTERM 而不是 SIGKILL
- 监控进程状态: 定期检查进程是否正常运行
- 记录进程信息: 便于问题排查和调试
- 使用信号处理: 实现优雅的进程关闭
- 设置资源限制: 防止进程占用过多资源
- 使用进程组: 便于管理相关进程