不是 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 的原因了。