MST
星途 面试题库

面试题:Bash脚本中的进程管理与信号处理

编写一个Bash脚本,创建多个子进程执行不同的任务(例如:一个子进程持续监测系统内存使用情况并记录到日志,另一个子进程定期备份指定目录到远程服务器)。同时,脚本要能够捕获特定信号(如SIGINT、SIGTERM),在接收到信号时,优雅地终止所有子进程并清理相关资源。请详细说明实现思路以及关键代码的作用。
39.5万 热度难度
编程语言Bash

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 创建子进程:使用 & 操作符在后台启动子进程,使它们与主脚本并行运行。
  2. 执行不同任务:在子进程中编写相应的任务逻辑,如监测内存使用情况并记录日志,以及定期备份指定目录到远程服务器。
  3. 捕获信号:使用 trap 命令捕获特定信号(如 SIGINTSIGTERM),并定义信号处理函数。
  4. 终止子进程并清理资源:在信号处理函数中,通过进程ID(PID)发送终止信号给子进程,并清理相关资源,如关闭打开的文件描述符等。

关键代码及作用

#!/bin/bash

# 定义日志文件路径
memory_log_file="memory_usage.log"
backup_log_file="backup.log"

# 监测系统内存使用情况并记录到日志的函数
monitor_memory_usage() {
    while true; do
        free -h | grep Mem > $memory_log_file
        sleep 5 # 每5秒记录一次
    done
}

# 定期备份指定目录到远程服务器的函数
backup_directory() {
    local source_dir="/path/to/source/directory"
    local remote_server="user@remote-server:/path/to/destination/directory"
    while true; do
        rsync -avz $source_dir $remote_server >> $backup_log_file 2>&1
        sleep 3600 # 每小时备份一次
    done
}

# 启动子进程
monitor_memory_usage &
memory_pid=$! # 记录监测内存使用情况子进程的PID

backup_directory &
backup_pid=$! # 记录备份子进程的PID

# 信号处理函数
cleanup() {
    echo "收到信号,终止子进程..."
    kill -TERM $memory_pid $backup_pid 2>/dev/null
    wait $memory_pid $backup_pid 2>/dev/null
    echo "子进程已终止,清理完成。"
}

# 捕获SIGINT和SIGTERM信号
trap cleanup SIGINT SIGTERM

# 主脚本等待信号
while true; do
    sleep 1
done
  1. 定义日志文件路径:定义了内存使用情况日志文件和备份日志文件的路径。
  2. monitor_memory_usage 函数:使用 free -h 命令获取内存使用情况,并通过 grep Mem 提取内存相关信息,然后每5秒记录到日志文件。
  3. backup_directory 函数:使用 rsync 命令将指定目录备份到远程服务器,每小时执行一次,并将日志输出到备份日志文件。
  4. 启动子进程:使用 & 操作符在后台启动两个子进程,并记录它们的PID。
  5. cleanup 函数:在接收到 SIGINTSIGTERM 信号时,通过 kill -TERM 命令向子进程发送终止信号,并使用 wait 命令等待子进程结束。
  6. 捕获信号:使用 trap 命令捕获 SIGINTSIGTERM 信号,并指定 cleanup 函数作为处理函数。
  7. 主脚本等待信号:主脚本通过一个无限循环 while true; do sleep 1; done 等待信号,以保持脚本运行。