Node.js使用node-pty做终端录制时Backspace退格键显示异常如何解决
问题根因
- 时间戳计算逻辑错误:原
getDuration函数使用getMilliseconds()仅获取当前秒内的毫秒值,跨秒时计算得到的时长会出现负数,即使取绝对值也和实际间隔严重不符,导致终端控制字符的输出时序异常,控制序列无法被正确解析。 - 终端输入映射错误:stdin设置为raw模式后,按下退格键会输出ASCII 127(DEL字符),而bash默认将退格操作绑定为ASCII 8(BS字符),输入字符不匹配导致退格的视觉反馈异常。
- 未同步窗口尺寸:录制过程中如果终端窗口大小发生变化,pty进程的行列数和实际终端不匹配,也会导致字符渲染错位。
- 初始时间戳未初始化:第一次触发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
相关产品推荐
相关产品推荐

