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

为何注册SIGHUP信号处理函数后,XTerm无法关闭等待输入的PHP CLI进程?

解决方案

问题根源

点击XTerm关闭按钮时,终端会给子进程(PHP脚本)发送SIGHUP信号。你注册的空信号处理函数覆盖了默认的终止行为,再加上PHP的pcntl_signal默认启用SA_RESTART标志——这个标志会让被信号中断的阻塞系统调用(比如fgets(STDIN))自动重启,导致脚本继续卡在等待输入状态,XTerm因为子进程未退出,窗口无法关闭。之前添加exit(1)无效,是因为SA_RESTART让脚本回到了fgets,没机会执行退出逻辑。

修复代码

修改后的脚本同时处理信号中断问题,保留你需要的所有逻辑,还能执行关闭前的清理:

<?php
// 启用异步信号处理,确保信号触发时立即执行处理函数
pcntl_async_signals(true);

$exitTriggered = false;

function cleanup_and_exit() {
    global $exitTriggered;
    if ($exitTriggered) return; // 避免重复执行清理
    $exitTriggered = true;

    // 这里写入你的清理逻辑:关闭文件、释放资源、记录日志等
    echo "Running cleanup procedures...\n";

    exit(0);
}

// 注册SIGHUP信号处理,禁用SA_RESTART,让阻塞调用被中断后不再重启
pcntl_signal(SIGHUP, 'cleanup_and_exit', false);
// 额外注册SIGTERM,兼容部分终端关闭时发送的信号类型
pcntl_signal(SIGTERM, 'cleanup_and_exit', false);

// 等待用户输入,收到信号时fgets会被中断并返回false
$input = fgets(STDIN);

// 若信号触发了退出标记,执行清理退出
if ($exitTriggered) {
    cleanup_and_exit();
}

// 正常输入后的逻辑(如果需要)
echo "Input received: $input\n";

验证方式

执行xterm -e php test.php,点击XTerm右上角关闭按钮,脚本会自动执行清理逻辑并终止进程,窗口正常关闭。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 02:58:36