You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Bash脚本中检测手动关闭的终端并执行后续命令

问题分析

你之前的脚本失效原因有两点:

  1. 捕获的gnome-terminal进程PID会在终端启动子进程后立即退出,导致wait提前触发后续命令
  2. 脚本中wait "$SECOND_PID" "$FIRST_PID"里的FIRST_PID未定义,属于无效参数

下面提供两种可行的解决方案:


方案1:使用gnome-terminal --wait参数(推荐)

--wait参数会让gnome-terminal持续运行,直到终端内的命令执行完毕才退出,这样捕获的PID能准确对应终端的生命周期。

修改后的脚本

#!/bin/bash
BASE_DIR="$(cd "$(dirname "$0")" && pwd)"
FIRST_DIR="$BASE_DIR"
SECOND_DIR="$BASE_DIR/dir1/"
THIRD_DIR="$BASE_DIR/dir2/"

# 启动第一个终端(无需等待)
gnome-terminal --working-directory="$FIRST_DIR" -- bash -c "
    echo 'lspci pcie cards';
    ./Delete_log_files.sh; 
    lspci -n; 
    ./Load_drivers.sh; 
    exec bash;"
sleep 1

# 启动第二个终端,启用--wait并后台运行
gnome-terminal --wait --working-directory="$SECOND_DIR" -- bash -c "
    echo 'run GDMS app'; 
    make; 
    sudo ./main;
    # 若需停止测试后仍保留终端,可添加exec bash;否则去掉该行,停止测试后终端自动关闭
" & SECOND_PID=$!
sleep 1

# 启动第三个终端,逻辑同第二个
gnome-terminal --wait --working-directory="$THIRD_DIR" -- bash -c "
    echo 'run GDMS app';    
    make; 
    sudo ./main;
" & THIRD_PID=$!

# 等待两个测试终端全部关闭
wait "$SECOND_PID" "$THIRD_PID"
# 执行清理命令
./Delete_log.sh

说明

  • 如果希望用户按下Ctrl+C停止./main后立即触发清理,就去掉终端脚本里的exec bash,此时./main终止后脚本执行完毕,终端自动退出
  • 如果需要用户停止测试后仍能在终端内操作,直到手动关闭终端才触发清理,保留exec bash即可

方案2:跟踪./main进程PID(兼容旧版gnome-terminal)

如果你的gnome-terminal不支持--wait参数,可通过临时文件记录./main的PID,主脚本循环检测进程状态,直到两个测试进程都终止。

修改后的脚本

#!/bin/bash
BASE_DIR="$(cd "$(dirname "$0")" && pwd)"
FIRST_DIR="$BASE_DIR"
SECOND_DIR="$BASE_DIR/dir1/"
THIRD_DIR="$BASE_DIR/dir2/"

# 创建临时目录存储PID文件
TEMP_DIR=$(mktemp -d)
SECOND_PID_FILE="$TEMP_DIR/second.pid"
THIRD_PID_FILE="$TEMP_DIR/third.pid"

# 启动第一个终端
gnome-terminal --working-directory="$FIRST_DIR" -- bash -c "
    echo 'lspci pcie cards';
    ./Delete_log_files.sh; 
    lspci -n; 
    ./Load_drivers.sh; 
    exec bash;"
sleep 1

# 启动第二个终端,记录./main的PID并等待其终止
gnome-terminal --working-directory="$SECOND_DIR" -- bash -c "
    echo 'run GDMS app'; 
    make; 
    sudo ./main &
    MAIN_PID=\$!
    echo \$MAIN_PID > '$SECOND_PID_FILE'
    wait \$MAIN_PID
    rm -f '$SECOND_PID_FILE'
    exec bash;" &
sleep 1

# 启动第三个终端,逻辑同第二个
gnome-terminal --working-directory="$THIRD_DIR" -- bash -c "
    echo 'run GDMS app';    
    make; 
    sudo ./main &
    MAIN_PID=\$!
    echo \$MAIN_PID > '$THIRD_PID_FILE'
    wait \$MAIN_PID
    rm -f '$THIRD_PID_FILE'
    exec bash;" &

# 循环检测两个测试进程是否仍在运行
while true; do
    SECOND_RUNNING=0
    if [ -f "$SECOND_PID_FILE" ]; then
        SECOND_PID=$(cat "$SECOND_PID_FILE")
        # 检查PID是否存在
        if kill -0 "$SECOND_PID" 2>/dev/null; then
            SECOND_RUNNING=1
        else
            rm -f "$SECOND_PID_FILE"
        fi
    fi

    THIRD_RUNNING=0
    if [ -f "$THIRD_PID_FILE" ]; then
        THIRD_PID=$(cat "$THIRD_PID_FILE")
        if kill -0 "$THIRD_PID" 2>/dev/null; then
            THIRD_RUNNING=1
        else
            rm -f "$THIRD_PID_FILE"
        fi
    fi

    # 两个进程都终止则退出循环
    if [ $SECOND_RUNNING -eq 0 ] && [ $THIRD_RUNNING -eq 0 ]; then
        break
    fi
    sleep 2
done

# 清理临时目录
rm -rf "$TEMP_DIR"
# 执行清理命令
./Delete_log.sh

说明

  • 该方案不依赖gnome-terminal的特殊参数,兼容性更强
  • 即使终端被意外关闭,主脚本也会检测到PID失效,自动终止循环并执行清理

内容的提问来源于stack exchange,提问作者Jonathan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 06:53:24