Debian SSH - 调整终端大小未向 bash 注册

Nuc*_*Dog 11 debian bash term

由于磁盘故障,我们最近重新安装了我们的服务器,现在我们在调整终端大小时遇到​​了问题。我们安装了 Debian 6.0.6。

症状

当您调整终端大小时,似乎没有基于 ncurses 的应用程序(已测试:ytalk、irssi、screen、tmux、一些 ncurses 示例应用程序)正确调整大小。屏幕通常以空白结束。在应用程序中强制重绘将使用旧的终端大小重绘。

在 bash (4.1.5(1)) 提示符下调整窗口大小时,COLUMNS 和 LINES 变量永远不会更新。

诊断

试图在 bash 中捕获 SIGWINCH,它似乎从未被接收到。这是经过测试的:

trap 'touch /home/user/sigwinch' SIGWINCH
trap 'touch /home/user/sigusr1' SIGUSR1
kill -s SIGWINCH $$
kill -s SIGUSR1 $$
Run Code Online (Sandbox Code Playgroud)

这应该在我的主目录中创建了这两个文件。它只创建了/home/user/sigusr1.

尝试kill -s SIGWINCH $$不会导致 $COLUMNS/$LINES 变量的更新。

启用checkwinsize( shopt -s checkwinsize) 将导致 bash 在从任何应用程序返回时更新 $COLUMNS/$LINES(如预期)。在checkwinsize启用启用的终端调整大小后,这会导致以下结果:

$ echo $COLUMNS ; ls > /dev/null ; echo $COLUMNS
72
107
Run Code Online (Sandbox Code Playgroud)

将我的登录 shell 更改为 tcsh 之类的内容并尝试调整终端的大小按预期工作,就像我测试的其他盒子上的 bash 一样。

我尝试删除我的 .bashrc 但它什么也没做。对于在 PuTTY 和来自 Linux 机器的某种 rxvt 类型终端中具有不同 bash 配置的其他几个用户,此问题正在发生。

斯特拉斯

我在 bash 上运行 strace 并尝试调整终端的大小,但没有任何结果(read在打印提示后立即在通话中被阻止)。

我在一个空行上按回车,bash 做了一大堆东西。我认为相关的输出是:(full strace

1: rt_sigprocmask(SIG_SETMASK, [WINCH], NULL, 8) = 0
2: rt_sigaction(SIGWINCH, {0x80e2c20, [], SA_RESTART}, {0x809c310, [], 0}, 8) = 0
3: rt_sigprocmask(SIG_BLOCK, [INT], [WINCH], 8) = 0
4: write(2, "aa:~$ ", 6)                   = 6
5: rt_sigprocmask(SIG_SETMASK, [WINCH], NULL, 8) = 0
6: rt_sigprocmask(SIG_BLOCK, NULL, [WINCH], 8) = 0
7: read(0,
Run Code Online (Sandbox Code Playgroud)

这显示了 bash,据我所知:(我可能会严重误解这一点。我在这里超出了我的范围。)

1: Disabling delivery of the SIGWINCH signal, when previously it was allowed.
2: Registering a handler for the SIGWINCH signal.
3: Masking some other combination of signals. As evidenced by line 5, this does not include SIGWINCH.
4: Printing the prompt.
5: Masking SIGWINCH, where previously nothing was blocked.
6: Masking the "union of null and SIGWINCH" which, to my understanding, would result in SIGWINCH being masked.
7: Waiting on input.
Run Code Online (Sandbox Code Playgroud)

在没有这些问题的盒子(Ubuntu,bash 4.2.24(1))上执行相同的 strace 导致:

1: rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
2: rt_sigaction(SIGWINCH, {0x49e320, [], SA_RESTORER|SA_RESTART, 0x7f7ef49f64c0}, {0x457880, [], SA_RESTORER, 0x7f7ef49f64c0}, 8) = 0
3: rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
4: write(2, "aaaaaaa:~$ ", 11)             = 11
5: rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
6: rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
7: read(0,
Run Code Online (Sandbox Code Playgroud)

到底发生了什么,为什么我的 bash 坏了?:(

我猜可能只是某个地方有一个选项默认为意想不到的事情,但在谷歌上的几个小时没有任何结果。

非常感谢任何帮助和/或指示。这真的很令人沮丧。

谢谢你。

Nuc*_*Dog 11

关于 strace 输出的某些事情一直困扰着我。也就是说,当 bash 启动时,它似乎已经屏蔽了 SIGWINCH。不能肯定,不明白它吐出的东西有一半,但在这一点上肯定值得探索。

strace -o strace_file bash -l从不存在问题的 tcsh shell运行。bash 从不掩饰 SIGWINCH。当它屏蔽它时,只是因为它试图恢复以前的面具。那么最初的面具是从哪里来的呢?

在谷歌上花更多时间和一个全新的想法,我发现这篇文章提到 aptitude 有时会导致 sshd 在 SIGWINCH 被屏蔽的情况下启动,然后它会被所有产生的进程直接继承到 shell。

我试过ps axwwws(所有,分离,宽输出,信号)。它显示了几个产生的 sshd 进程屏蔽了 SIGWINCH。

服务器/侦听过程(sshd 本身)没有。使用 tcsh 的托管连接的进程也没有。那部分让我感到困惑。我猜测(再次,对此知之甚少)信号掩码是进程组范围内的或其他东西,tcsh 在开始时将其重置,这也影响了 ssh。

因此,一时兴起,我与 tcsh 连接(以获得一个没有 SIGWINCH 掩码的干净术语),重新启动 ssh,将我的 shell 改回 bash ......它起作用了!一切恢复正常!

据我所知 aptitude 还没有在这个盒子上运行,并且 ssh 已经重新启动了几次以进行配置更改。然而,沿着这条线的某个地方,面具进入了它,并像一种严重的疾病一样感染了一切。

要识别相同的问题,请运行ps axwwws | grep sshd并查找第二个长列 ( BLOCKED) 设置为 0x8000000 的sshd 进程。那是SIGWINCH。就像是:

   0 26425 0000000000000000 0000000008000000 0000000000001000 0000000180004003 Ss   ?          0:00 sshd: aa [priv]
1000 26430 0000000000000000 0000000008000000 0000000000001000 0000000180010000 S    ?          0:02 sshd: aa@pts/24
Run Code Online (Sandbox Code Playgroud)

修复它(可能不是最好的解决方案,对我有用):

$ sudo apt-get install tcsh
[snip]
$ chsh -s /bin/tcsh
[connect in with a new connection, leave the old one open in case of any issues with tcsh]
$ sudo /etc/init.d/ssh restart
Run Code Online (Sandbox Code Playgroud)

它是固定的。

干杯!