有许多工具,例如“script”、“screen”、“ttyrec”,允许记录 shell 会话的内容。这些工具的设计目的就是记录 pty 上显示的所有内容,包括控制字符。但是,似乎没有解决方案可以删除控制字符并显示用户看到的已记录会话的记录。甚至重放程序似乎也无法正确处理多行命令。
我花了一些时间尝试为 typescript 制作合适的解析器,并得出结论,这在一般情况下实际上是不可能的。问题是现代终端仿真器(terminator、xterm、rxvt)具有自动换行功能,并且 shell(bash、zsh)会使用它。对于交互式 shell 进程来说,一切进展顺利,因为它能够与终端的宽度保持同步并根据需要调整光标位置。不幸的是,“脚本”(据我所知,其他工具也是如此)不会跟踪 pty 大小变化事件,这些信息会丢失。因此,渲染 typescript 的工具没有足够的信息,无法重建多行命令的外观。
我是否遗漏了什么?有解决方案吗?
我看到了以下可能的解决方案,但它们都不容易,也不完整:
- 使用没有复杂命令行编辑器的 shell(如 bourne shell)
- 始终在启用“set -x”的情况下运行(在 bash 中,命令自动完成会产生很多混乱)
- 修补“脚本”(和“屏幕”)工具以记录 pty 大小变化(在 Linux 上,它已经可以将时间信息提供给 stderr,因此在那里添加 pty 大小变化事件是合乎逻辑的)
- 想出一些巧妙的算法来解析混乱的打字稿。例如,当 shell 在多行命令编辑期间需要转到另一行时,它会发送 CR。当用户提交命令时,它会发送 CR+NL。不幸的是,bash 在处理来自用户的某些 Ctrl-U 命令时也会发送 CR。
- 从其他来源(例如从 shell 历史记录)获取命令的文本(在 typescript 中被弄乱了)。但这需要自定义 shell 配置文件脚本等。
答案1
一般情况下需要在同样大小的终端里重放。
您可以决定完全忽略它。正如 sendmoreinfo 所述,您可以声明一个不支持任何这些功能的 TERM。不过,不要期望
vim
或readline
按照您习惯的方式行事。您可以将其与您的成绩单一起存储,并在重播时重新创建正确的大小(例如
xterm -geometry [...] -e [...]
),但调整大小会破坏所有内容。如果你非常关心这个问题,并且想要完美的解决方案,您可以自己实现!
您可以通过处理信号和使用来
ttyrec
记录终端大小及其变化。SIGWINCH
ioctl(STDIN_FILENO, TIOCGWINSZ, [...])
您
ttyplay
必须负责模拟终端本身,并在终端内表示它。这很棘手,但幸运的是,已经有几个项目在这样做,因此您可以重用完善的代码库。tmux
例如,我想到的是。