MST
星途 面试题库

面试题:Bash进程管理与信号处理综合

编写一个Bash脚本,创建3个子进程,每个子进程执行不同的任务(例如一个子进程持续输出当前时间,一个子进程计算1到100的和,另一个子进程等待用户输入)。要求在脚本接收到SIGINT信号(通常是Ctrl+C)时,能够优雅地终止所有子进程,并清理相关资源,同时输出每个子进程的执行结果。请详细说明脚本的实现思路及关键代码。
36.1万 热度难度
编程语言Bash

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 创建子进程:使用 fork 系统调用创建3个子进程,每个子进程执行不同的任务。
  2. 任务执行
    • 一个子进程通过 while 循环持续输出当前时间,使用 date 命令。
    • 一个子进程计算1到100的和,通过 for 循环累加。
    • 一个子进程等待用户输入,使用 read 命令。
  3. 信号处理:在父进程中注册 SIGINT 信号处理函数,当接收到 SIGINT 信号时,向所有子进程发送 SIGTERM 信号,等待子进程结束,并收集每个子进程的执行结果。

关键代码

#!/bin/bash

# 定义信号处理函数
handle_sigint() {
    # 向所有子进程发送SIGTERM信号
    for pid in "${pids[@]}"; do
        kill -SIGTERM "$pid"
    done

    # 等待所有子进程结束
    for pid in "${pids[@]}"; do
        wait "$pid"
        status=$?
        if [ $status -eq 0 ]; then
            echo "子进程 $pid 正常结束"
        else
            echo "子进程 $pid 异常结束,状态码:$status"
        fi
    done

    exit 0
}

# 注册SIGINT信号处理函数
trap handle_sigint SIGINT

# 存储子进程PID的数组
pids=()

# 创建第一个子进程,输出当前时间
pid1=$(fork)
if [ $pid1 -eq 0 ]; then
    while true; do
        date
        sleep 1
    done
    exit 0
else
    pids+=("$pid1")
fi

# 创建第二个子进程,计算1到100的和
pid2=$(fork)
if [ $pid2 -eq 0 ]; then
    sum=0
    for ((i = 1; i <= 100; i++)); do
        sum=$((sum + i))
    done
    echo "1到100的和为:$sum"
    exit 0
else
    pids+=("$pid2")
fi

# 创建第三个子进程,等待用户输入
pid3=$(fork)
if [ $pid3 -eq 0 ]; then
    echo "请输入内容:"
    read input
    echo "你输入的内容是:$input"
    exit 0
else
    pids+=("$pid3")
fi

# 父进程等待子进程结束
for pid in "${pids[@]}"; do
    wait "$pid"
done

代码说明

  1. 信号处理函数 handle_sigint
    • 向所有子进程发送 SIGTERM 信号。
    • 等待所有子进程结束,并根据子进程的退出状态码输出相应信息。
  2. 注册信号处理:使用 trap handle_sigint SIGINT 注册 SIGINT 信号处理函数。
  3. 创建子进程
    • 使用 fork 创建3个子进程,每个子进程执行不同的任务。
    • 将子进程的PID存储在 pids 数组中。
  4. 父进程等待:父进程通过 wait 等待所有子进程结束。