使用Python sh模块,如何不抑制交互式vim命令?

时间:2014-09-08 01:37:05

标签: python vim sh

import sh
sh.vim("lalala")

未在我的控制台中显示vim编辑器。设置_bg=False kwarg不做任何更改(因为那已经是默认值)

如果我使用subprocess模块,它可以工作:

import subprocess
subprocess.call(["vim", "lalala"])

1 个答案:

答案 0 :(得分:5)

问题在于vim期望其stdin是TTY,但sh创建的管道不是TTY,而是管道。

解决方案是不要试图用管道拦截vim的标准I / O.由于用管道截取stdio是sh的全部目的,而不是试图找到一种方法来对抗它,你最好不要使用它。只需使用stdlib的subprocess模块,只有在您不经意的情况下才能拦截stdio:

subprocess.check_call(['vim', 'lalala'])

但请注意sh文档中的TTYs部分:

  

某些应用程序的行为会有所不同,具体取决于它们的标准文件描述符是否附加到TTY。例如,当STDOUT未附加到TTY时,git将禁用用于人类的功能,例如彩色和分页输出。如果TTY未附加到STDIN,则其他程序可能会禁用交互式输入。还有其他程序,例如SSH(没有-n),期望他们的输入来自TTY /终端。

     

默认情况下,sh为STDOUT模拟TTY,但不为STDIN模拟。您可以通过传入额外的特殊关键字参数来更改默认行为...

因此,如果您通过_tty_in=True,那么vim的输入将是模拟的TTY,而不是管道。

但这仍然不会带来很多好处。它允许vim运行,但它会使用sh为其输入和输出创建的假TTY运行,我很确定这不是你的意思想。 (如果您希望发送控制序列并捕获并处理它发回的控制序列,那么只需编写脚本ed - 或者更好,sed - 而不是......)< / p>


那么为什么你没有得到某种错误信息或其他合理的行为?

真的,那是vim。如果您使用emacs或使用curses的任何应用以及许多其他TTY应用尝试相同的操作,他们会向stderr写一条错误消息并以1退出,因此您&#39 ;看到这样的事情:

ErrorReturnCode_1:

  RAN: '/usr/bin/emacs -nw'

  STDOUT:


  STDERR:
emacs: standard input is not a tty