不久前,我决定通过添加以下方法记录我的所有终端活动:
script -t 0 "/Users/XXXXXXX/terminalLogs/log0$(date '+%y-%m-%d-%H:%M').txt"
到我的 .bash_profile 文件。这通常按预期工作,但我发现调整窗口大小时存在问题。
因此我按如下方式启动终端窗口:
一切都很好...如果我调整窗口大小并使用 vim 打开文件,我会得到:
(您会注意到 vim 窗口比终端窗口小)
如果我输入“exit”退出日志记录并调整大小,我就会得到我期望的 vim 终端。
所以我有点困惑,如果有人可以解释发生了什么,或者他们可以建议一个模型,或者人们对我应该如何记录命令有更好的想法,那就太好了。:(
答案1
当你调整终端仿真器窗口的大小时,它会调整其伪终端(“pty”)通过进行 TIOCSWINSZ(终端 IO 控制集 WINdow SiZe)ioctl 系统调用。反过来,内核向前台进程组(例如正在运行的Vim) 的 pty。最后,收到 SIGWINCH 的程序可以使用 TIOCGWINSZ(G 代表获取)ioctl 来检索新的 pty 尺寸并根据需要重新绘制自身。
由于脚本程序工作时,在“内部”运行的程序脚本会话实际上在与终端仿真器创建的 pty 不同的 pty 上运行。
考虑这个日志:
% tty
/dev/ttys003
% script
Script started, output file is typescript
% tty
/dev/ttys004
% exit
Script done, output file is typescript
最初,shell 在 上运行ttys003
,但在 内部启动的 shell脚本会话正在运行ttys004
。
如果我在退出之前调整了终端仿真器窗口的大小脚本会话中,终端仿真器将设置新的大小ttys003
,内核将向脚本程序(的前台进程ttys003
)。理想情况下,脚本程序将读取“外部” pty 的新尺寸,并将“内部” pty 设置为相同的尺寸。这反过来会导致前台进程组ttys004
(即您的Vim例如,接收 SIGWINCH。
不幸的是,脚本您正在使用 (Apple 版本的 Lion?) 似乎不会传递窗口大小的变化(并且未处理的 SIGWINCH 会被有效忽略)。其他版本(来自 util-linux-ng) 似乎在处理 SIGWINCH 方面做得更好,但它们可能不易在您的系统上编译。
如果你可以手动触发适应新尺寸,那么你可以简单地运行调整大小命令(/usr/X11/bin/resize
)。它将使用转义序列向终端仿真器查询适当的大小,然后将 pty 设置为正确的尺寸。在您所述的场景中,您可以:!resize
从您的Vim实例来调整“内部” pty 的大小(命令:!
完成后 Vim 会注意到)。
如果你想要自动调整大小,那么你必须找到一个版本脚本正确传播 pty 维度更改(通过处理 SIGWINCH 并进行正确的 ioctl)。或者,您可能能够script
用以下 Expect 程序的调用替换您的调用:
#!/usr/bin/expect
proc date {fmt} {
clock format [clock seconds] -format $fmt
}
set file [if {$argc > 0} {lindex $argv 0} {list typescript}]
send_user "Script started, output file is $file\n"
log_file "$file"
send_log "Script started on [date %+]\n"
# WINCH code from http://ubuntuforums.org/showthread.php?t=865420
trap {
set rows [stty rows]
set cols [stty columns]
stty rows $rows columns $cols < $spawn_out(slave,name)
} WINCH
spawn -noecho $env(SHELL)
interact
send_log "\nScript done on [date %+]\n"
log_file
send_user "Script done, output file is $file\n"
给它一个文件名作为其唯一参数:
/path/to/script.expect "$HOME/terminalLogs/log0$(date '+%y-%m-%d-%H:%M').txt"
答案2
我没有明确的答案但是...
- 根据它的手册页(
$ man script
),script
似乎不喜欢交互式程序:
某些交互式命令(如 vi(1))会在 typescript 文件中产生垃圾。脚本实用程序最适合处理不操作屏幕的命令。结果旨在模拟硬拷贝终端,而不是可寻址终端。
“默认”大小与启动时的窗口大小相同
script
。这可能会
script
强制重置或禁用一系列功能(例如调整窗口大小的功能)。手册页没有提到这个主题,但我认为阻止调整大小是有意义的。