该问题与 PuTTY 本身无关,与 SSH 客户端和伪终端有关。
要避免此问题,请将 PuTTY 配置为使用伪终端。 (在 TTY 面板中,有一个“不要分配伪终端”复选框。确保它未被选中。)
With ssh
,你需要使用-t
选项告诉ssh
使用伪终端。
这是一个简单的示例程序,您可以在 Linux 中使用它来获取终端大小。它不需要诅咒:
#include <unistd.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <stdio.h>
static int get_size(const int fd, int *const rows, int *const cols)
{
struct winsize sz;
int result;
do {
result = ioctl(fd, TIOCGWINSZ, &sz);
} while (result == -1 && errno == EINTR);
if (result == -1)
return errno;
if (rows)
*rows = sz.ws_row;
if (cols)
*cols = sz.ws_col;
return 0;
}
int main(void)
{
int rows, cols;
if (!get_size(STDIN_FILENO, &rows, &cols) ||
!get_size(STDOUT_FILENO, &rows, &cols) ||
!get_size(STDERR_FILENO, &rows, &cols))
printf("%d rows, %d columns\n", rows, cols);
else
fprintf(stderr, "Terminal size is unknown.\n");
return 0;
}
实际信息是通过使用TIOCGWINSZ
TTY 控制。
伪终端的大小实际上是由内核维护的。如果没有伪终端,只有标准流,就没有行和列;在这种情况下它只是一个流。特别是,甚至tput lines
and tput cols
那么就会失败。
如果没有伪终端,许多交互式命令行程序将无法运行。例如,top
会报告类似的内容“未设置 TERM 环境变量” or “顶部:tty 获取失败”。其他的也可以,只是不能交互;它们只会输出一次,但就好像终端无限高无限宽一样。
总之,您的应用程序应该识别它是在伪终端中运行(终端大小已知,可能支持诅咒等),还是在流模式下运行(通过 SSH 或 PuTTY,故意不使用伪终端——或者可能只是因为输入输出全部定向到文件或从文件或类似文件中定向)。