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

Node.js使用node-pty做终端录制时Backspace退格键显示异常如何解决

问题根因

  1. 时间戳计算逻辑错误:原getDuration函数使用getMilliseconds()仅获取当前秒内的毫秒值,跨秒时计算得到的时长会出现负数,即使取绝对值也和实际间隔严重不符,导致终端控制字符的输出时序异常,控制序列无法被正确解析。
  2. 终端输入映射错误:stdin设置为raw模式后,按下退格键会输出ASCII 127(DEL字符),而bash默认将退格操作绑定为ASCII 8(BS字符),输入字符不匹配导致退格的视觉反馈异常。
  3. 未同步窗口尺寸:录制过程中如果终端窗口大小发生变化,pty进程的行列数和实际终端不匹配,也会导致字符渲染错位。
  4. 初始时间戳未初始化:第一次触发pty的data事件时,lastRecordTimestamp为null,会导致首次时长计算错误。

修复方案

修改代码的以下部分即可:

1. 修正时间戳计算逻辑

function getDuration() {
    const now = Date.now()
    const duration = now - lastRecordTimestamp
    lastRecordTimestamp = Date.now()
    return duration
}

2. 修正record函数配置

function record(filename) {
    var ptyProcess = pty.spawn(shell, [], {
        name: 'TermRecord Session',
        cols: process.stdout.columns,
        rows: process.stdout.rows,
        cwd: process.env.HOME,
        env: process.env
    });

    // 初始化时间戳
    lastRecordTimestamp = Date.now()

    process.stdout.setDefaultEncoding('utf8');
    process.stdin.setEncoding('utf8')
    process.stdin.setRawMode(true)
    process.stdin.resume();

    // 同步终端窗口尺寸到pty进程
    process.stdout.on('resize', () => {
        ptyProcess.resize(process.stdout.columns, process.stdout.rows)
    })

    ptyProcess.on('data', function(data) {
        process.stdout.write(data)
        var duration = getDuration();

        if (duration < 5) {
            duration = 100
        }

        recording.push({
            delay: Math.abs(duration),
            content: data
        });
    });

    ptyProcess.on('exit', () => {
        process.stdin.setRawMode(false);
        process.stdin.pause()
        // 移除resize监听避免内存泄漏
        process.stdout.removeAllListeners('resize')

        recording[0].delay = 1000
        try {
            writeFileSync(filename, JSON.stringify(recording, null, '\t'));
        } catch (err) {
            console.log(err);
        }
    })

    // 适配退格键输入映射
    var onInput = (data) => {
        if (data === '\x7f') { // raw模式下退格输入为DEL(127)
            ptyProcess.write('\x08') // 替换为bash识别的BS(8)
        } else {
            ptyProcess.write(data)
        }
    }
    process.stdin.on('data', onInput)
}

验证方法

修改完成后重新启动录制功能,输入字符后按退格即可看到字符被正常擦除,不会再出现空白残留,执行命令也不会出现字符不匹配的报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 02:36:03