ipython in ssh terminal executes xdotool commands slowly

I've encountered a behavior that I'm not sure how to debug.

Basic setup

I have a vim script to interact with IPython when editing a python file. Basically it will run any command that I have selected at my cursor. It works great and increases my productivity a ton. However, there is one problem. It is very slow when the IPython terminal is in an SSH window. This is likely a very niche problem, so I'll try to explain it as best I can and give MWE where possible, but there are a lot of components at play here.

I'm running on Ubuntu Linux 16.04 with a Gnome 3 frontend on both the client and server systems. IPython is version 5.2.2. My terminal is Terminator.

Initial experiment

When vim receives a is executes this basic script:

  • Copy the current line to the system clipboard.
  • Preprocess the text to fix any indentation issues.
  • Use wmctrl to find and remember the window id of my gvim window.
  • Use wmctrl to find the window id of the most recently selected terminal window (this will typically be the one with IPython running).
  • Use wmctrl to focus on the IPython window
  • Use xdotool to send the ctrl+shift+v key sequence. This will paste the text into the IPython prompt.
  • Use xdotool to send KP_Enter, which will execute the code in the IPython prompt.
  • Use wmctrl to focus back to the gvim window, which makes the interaction seemless (usually, but not in this case).
  • In the latter part of the script it waits for .01 seconds to let each command execute.

    I wrote out some debug text along with timestamps to see if I could pinpoint what was taking so long.

    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
    

    You can see the script starts at time 1496591696.3065684, and then gets through the first portion very quickly, ending at 1496591696.315782, only a ~.01 seconds so far and not noticeable. Then it execute the wmctrl and xdotool commands. These are called using python's subprocessing module. Overall the entire script finishes at 1496591696.550773, which is only ~.2 seconds in total, which again is not very noticable.

    So, the script itself is fast. But when I look at the IPython terminal nothing happens for at least 1 or 2 seconds. I believe this is because when xdotool executes it quickly returns, but the key sequence that is sent is stuck in some buffer somewhere and taking forever.

    Minimal Example

    So, I've determined the problem is not in my script. It is either something to do with some combination of ipython, ssh, and/or xdotool. Here is a MWE that reproduces the issue:

  • Open a terminal window.
  • Find the ID of the terminal window using wmctrl -lx .
  • SSH into a remote machine and start ipython .
  • Open a second terminal window.
  • Copy any dummy text into the clipboard.
  • Execute this test command (using the correct window ID):

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

  • When I do this, the same slowness happens. It switches over to the terminal window very quickly, and I can see the test command finishes in my second terminal, but the pasted text does not appear in IPython for about 4 seconds (counted manually).

    Variations on the minimal example

    These variations cause the behavior to disappear:

    Pasting directly works If you just select the IPython window and press ctrl+shift+v, the text is pasted in with no delay. Something about the window being focused by wmctrl or the ctrl+shift+v command being sent by xdotool must be contributing the issue.

    Pasting into the bash prompt works If you do not start IPython, and execute the test command, the copied text pastes into the SSH bash prompt very quickly. So IPython is contributing to the issue.

    tmux makes the behavior disappear This last variation is REALLY weird, but might be indicative of the underlying problem. If instead of open terminal -> ssh -> start ipython , I do open terminal -> ssh -> start tmux -> start ipython , then running the test script also copies the text in quickly. I'm guessing tmux does something with replacing input buffers, but I really don't know enough about I/O details to have a clue what that is.


    So, I think I've been able to determine that this is some weird I/O buffer issue when IPython receives IO directly over SSH and when xdotool is the one sending the IO. But now I have no idea how to proceed in fixing the issue or if it is even possible to fix.

    Its good I found the tmux workaround, but forcing myself into tmux for these interactive sessions can be restricting in terms of output scrolling / copying from the terminal output back to my client machine. It also prevents me from doing some things that require X11 forwarding. I would prefer to be able to work directly in ssh.

    So, if anyone has any ideas, I'd really appreciate some help with this one.

    链接地址: http://www.djcxy.com/p/68944.html

    上一篇: 在Windows 10上Jupyter笔记本python崩溃

    下一篇: ipython在ssh终端中缓慢执行xdotool命令