Eshell 系统调用 ioctl TIOCGWINSZ 返回值不对

不是 Emacs 拿不到,我的理解是因为 Emacs 没有按照 ioctl 的方式提供信息。


另外,这个问题似乎跟环境变量一样,存在这继承的现象。

首先我准备了一个 c 写的命令:

#include <sys/ioctl.h>
#include <stdio.h>
int main(int argc, char **argv)
{
  struct winsize sz;
  ioctl(0, TIOCGWINSZ, &sz);
  printf("Screen width: %i, Screen height: %i\n", sz.ws_col, sz.ws_row);
  return 0;
}

在终端里:

⋊> [~/D/s/c/winsize] ./a.out
Screen width: 181, Screen height: 24

⋊> [~/D/s/c/winsize] sh -c './a.out'
Screen width: 181, Screen height: 24

第二条命令是在一个子进程中执行,执行完立即退出。如果把它想象成一个有形的窗体,那么这个窗体还没创建就销毁了,所以它返回的窗口信息应该是来自于父进程。

Script Editor.app 中试验:

do shell script "/usr/local/bin/python3 -c 'import os; print(os.isatty(1))'"
-- => False
do shell script "~/.scratch/c/winsize/a.out"
-- => "Screen width: 0, Screen height: 0"

结果跟 Eshell 和 M-! 是一样的,其创建的 shell 子进程还没来得及生成窗口信息就退出了,又无法从父进程中继承(类似 Emacs 与 Eshell 的情形),或许这就是为什么 shell-command 文档里要注明 inferior shell 的原因了。


1 个赞