1

我遇到了一个我不确定如何调试的行为。

基本设置

在编辑 python 文件时,我有一个 vim 脚本可以与 IPython 交互。基本上它会运行我在光标处选择的任何命令。它工作得很好,大大提高了我的工作效率。但是,有一个问题。当 IPython 终端在 SSH 窗口中时,速度非常慢。这可能是一个非常小众的问题,所以我会尽力解释它,并尽可能提供 MWE,但这里有很多组件在起作用。

我在客户端和服务器系统上运行带有 Gnome 3 前端的 Ubuntu Linux 16.04。IPython 是 5.2.2 版。我的终端是终结者。

初步实验

当 vim 收到一个 is 时执行这个基本脚本:

  • 将当前行复制到系统剪贴板。
  • 预处理文本以修复任何缩进问题。
  • 用于wmctrl查找并记住我的 gvim 窗口的窗口 ID。
  • 用于wmctrl查找最近选择的终端窗口的窗口 ID(这通常是运行 IPython 的窗口)。
  • 用于wmctrl专注于 IPython 窗口
  • 用于xdotool发送 ctrl+shift+v 键序列。这会将文本粘贴到 IPython 提示符中。
  • 用于xdotool发送 KP_Enter,它将在 IPython 提示符下执行代码。
  • 用于wmctrl将焦点重新回到 gvim 窗口,这使得交互看起来很流畅(通常情况下,但在这种情况下不会)。

在脚本的后半部分,它等待 0.01 秒让每个命令执行。

我写了一些调试文本和时间戳,看看我是否能查明是什么花了这么长时间。

1496591696.3065512 
----
CopyGVimToTerminalDev
1496591696.3065684 mode = 'n'
1496591696.3065758 return_to_vim = '1'
1496591696.3065836 grabbing text at current line
1496591696.3066013 preparing text
1496591696.3066237 copying text to clipboard
1496591696.3157291 copied text to clipboard
1496591696.315782 Running script
Executing x do: (
    ('remember_window_id', 'ACTIVE_GVIM'),
    ('focus', 'x-terminal-emulator.X-terminal-emulator'),
    ('key', 'ctrl+shift+v'),
    ('key', 'KP_Enter'),
    ('focus_id', '$ACTIVE_GVIM'),
)
# Step 0
[] 
# Step 1
['wmctrl', '-ia', '0x2400004'] wmctrl -ia 0x2400004
# Step 2
['xdotool', 'key', 'ctrl+shift+v'] xdotool key ctrl+shift+v
# Step 3
['xdotool', 'key', 'KP_Enter'] xdotool key KP_Enter
# Step 4
['wmctrl', '-ia', '0x3400003'] wmctrl -ia 0x3400003
1496591696.550773 Finished script

您可以看到脚本从时间 1496591696.3065684 开始,然后很快通过第一部分,在 1496591696.315782 结束,到目前为止只有 ~.01 秒并且不明显。然后它执行wmctrlandxdotool命令。这些是使用 python 的子处理模块调用的。总的来说,整个脚本在 1496591696.550773 处结束,总共只有 ~.2 秒,这也不是很明显。

因此,脚本本身很快。但是当我查看 IPython 终端时,至少 1 或 2 秒内没有任何反应。我相信这是因为当 xdotool 执行时它会很快返回,但是发送的密钥序列被卡在某个缓冲区的某个地方并且永远存在。

最小的例子

所以,我确定问题不在我的脚本中。它要么与 ipython、ssh 和/或 xdotool 的某种组合有关。这是重现该问题的 MWE:

  • 打开一个终端窗口。
  • 使用 查找终端窗口的 ID wmctrl -lx
  • SSH 进入远程机器并启动ipython.
  • 打开第二个终端窗口。
  • 将任何虚拟文本复制到剪贴板。
  • 执行这个测试命令(使用正确的窗口 ID):

    wmctrl -ia 0x2400004 && xdotool key ctrl+shift+v && xdotool key KP_Enter

当我这样做时,会发生同样的缓慢。它很快切换到终端窗口,我可以看到测试命令在我的第二个终端中完成,但粘贴的文本在 IPython 中没有出现大约 4 秒(手动计数)。

最小示例的变体

这些变化导致行为消失:

直接粘贴 如果您只是选择 IPython 窗口并按 ctrl+shift+v,则文本会立即粘贴。关于被聚焦的窗口wmctrl或发送的 ctrl+shift+v 命令的某些东西xdotool一定是造成问题的原因。

粘贴到 bash 提示符有效 如果您不启动 IPython,并执行测试命令,复制的文本会很快粘贴到 SSH bash 提示符中。所以 IPython 正在为这个问题做出贡献。

tmux 使行为消失 最后一个变化真的很奇怪,但可能表明潜在的问题。如果不是open terminal -> ssh -> start ipython,我会open terminal -> ssh -> start tmux -> start ipython,然后运行测试脚本也会快速复制文本。我猜 tmux 在替换输入缓冲区方面做了一些事情,但我真的对 I/O 细节知之甚少,无法知道那是什么。


所以,我想我已经能够确定当 IPython 直接通过 SSH 接收 IO 以及何时xdotool发送 IO 时,这是一些奇怪的 I/O 缓冲区问题。但现在我不知道如何继续解决这个问题,或者是否有可能解决。

很好,我找到了 tmux 解决方法,但是强迫自己进入 tmux 进行这些交互式会话可能会限制输出滚动/从终端输出复制回我的客户端机器。它还阻止我做一些需要 X11 转发的事情。我希望能够直接在 ssh 中工作。

因此,如果有人有任何想法,我将非常感谢您对此的帮助。

4

0 回答 0