Когда вы изменяете размер окна эмулятора терминала, он настраивает свой псевдотерминал («pty»), выполняя системный вызов ioctl TIOCSWINSZ (терминал ввода-вывода Idct SiZe). В свою очередь, ядро отправляет сигнал SIGWINCH (WINdow CHange) в группу процессов переднего плана (например, запущенный экземпляр Vim) этого pty. Наконец, программы, которые получили SIGWINCH, могут использовать ioctl TIOCGWINSZ (G для Get), чтобы получить новые измерения pty и перерисовать себя соответствующим образом.
Из-за того, как работает программа сценария , программы, выполняющиеся «внутри» сеанса сценария , на самом деле выполняются на pty, отличном от pty, созданного эмулятором терминала.
Рассмотрим этот журнал:
% tty
/dev/ttys003
% script
Script started, output file is typescript
% tty
/dev/ttys004
% exit
Script done, output file is typescript
Первоначально оболочка работает на ttys003
, но оболочка, которая запускается «внутри» сеанса сценария, работает на ttys004
.
Если я изменю размер окна эмулятора терминала перед выходом из сеанса сценария , эмулятор терминала установит новый размер для ttys003
, и ядро отправит SIGWINCH в программу сценария ( основной процесс ttys003
). В идеале программа- сценарий считывает новые измерения «внешнего» pty и устанавливает для «внутреннего» pty одинаковый размер. Это, в свою очередь, приведет к тому, что группа процессов переднего плана ttys004
(т. Е. Ваш экземпляр Vim) получит сигнал SIGWINCH.
К сожалению, версия скрипта, которую вы используете (версия Apple от Lion?) не передает изменения размера окна (и необработанный SIGWINCH эффективно игнорируется). Другие версии (из util-linux-ng), кажется, лучше справляются с обработкой SIGWINCH, но они не могут быть легко скомпилированы в вашей системе.
Если вы можете вручную запустить адаптацию к новому размеру, то вы можете просто запустить команду изменения размера (/usr/X11/bin/resize
) внутри «внутреннего» pty. Он запросит у эмулятора терминала соответствующий размер, используя escape-последовательности, а затем установит для 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"