【问题标题】:Running vi from Python script从 Python 脚本运行 vi
【发布时间】:2014-10-19 05:11:52
【问题描述】:

我正在尝试从 Python (2.6.4) 脚本中使用 vanilla vi(Solaris 10 上的 /usr/bin/vi)打开一个文件,但我所做的一切似乎都不起作用。我想让脚本将一些数据放在一个临时文件中,然后在 vi 中打开该文件供用户编辑。理想情况下,脚本会阻止对 vi 的调用,并在用户完成后继续执行,但我可以接受将脚本进程转换为 vi 进程(通过 exec 或其他方式)的解决方案。

我已经尝试了以下方法,但是对于其中的每一个,vi 都会将文件的第一页打印到屏幕上,然后以“输入读取错误”退出:

os.execlp('vi', 'vi', filename)

os.system('vi' + ' ' + filename)

subprocess.call('vi' + ' ' + filename, shell=True)

关于上下文,这里是完整的代码:

#!/usr/bin/python

import sys
import os
import subprocess

fname = "." + str(os.getpid()) + ".pvi.tmp"
f = open(fname, 'w')

f.write("## Remember to save this to a new file if you want to keep it!\n")

for line in sys.stdin:
    f.write(line + "\n")

f.close()

# These all give the error "Input read error"
#os.execlp('vi', 'vi', fname)
#os.system('vi' + ' ' + fname)
#subprocess.call('vi' + ' ' + fname, shell=True)

os.unlink(fname)

我基本上是在尝试将管道流程模拟到 vi 中,而我的版本不支持(vi - 不起作用)。我会将它们通过管道传输到这个脚本,然后将输出写入一个临时文件并在 vi 中打开它。

任何帮助将不胜感激!

【问题讨论】:

  • 如果你只输入vi filename而不是运行Python脚本会发生什么? $TERM 是否为您的终端正确设置?
  • 你是如何运行你的 Python 脚本的?
  • vi filename 按预期工作。我的$TERM 设置为 xterm,我认为这是正确的。我正在以echo "asdf" | pvi 的身份运行脚本(称为 pvi)。
  • 哦,这就是问题所在。输入是来自echo 的管道,而不是终端。

标签: python solaris vi


【解决方案1】:

问题是vi 的标准输入是从您的脚本继承的,这意味着它附加到管道而不是终端。试试这个:

os.system('vi' + ' "' + fname + '" </dev/tty >/dev/tty 2>&1')

如果fname 来自用户输入,这是很危险的,因为它可能包含嵌入式 shell 元字符并导致执行任意命令。但是在您的代码中似乎并非如此;您正在确定性地构建值。

替代方法是使用exec 调用之一绕过shell,但是您还必须在Python 中执行I/O 重定向,这有点笨拙。是否值得努力取决于您的应用程序的风险敞口。但是,在您的特定情况下,这似乎不是问题。

【讨论】:

  • 啊,太棒了,这非常有效!所以这是手动将终端的标准输入、标准输出和标准错误输入 vi,对吗?我永远不会想到这一点。谢谢!
  • 基本上。它实际上以相反的方式工作 - 它将 vi 进程的三个标准 I/O 流(输入、输出和错误)附加到终端。终端不知道标准输入、标准输出和标准错误;它只有一个(可能是虚拟的)显示器和键盘。
【解决方案2】:

您的 system 电话在 OSX 上适用于我:

os.system('vi' + ' ' + fname)

应该如此。在这种情况下,一个考虑因素是stdin 会发生什么。如果你在没有重定向的情况下运行它,它就可以工作。但是如果你重定向stdin,例如使用python scripty.py &lt; input.txt,那么VI 就会抱怨。它给了我Vim: Warning: Input is not from a terminal

【讨论】:

  • 不幸的是,它对我来说与上面列出的效果相同。这是双重令人沮丧的,因为我可以看到它正在读取文件,然后它立即退出。从其他 stackoverflow 的答案来看,以上所有的应该都可以在各种平台上工作,他们只是不能在我的平台上工作。
  • @DiputsMonro 查看我的编辑。我认为这是你如何运行python脚本的问题。
  • 我正在尝试将进程的输出通过管道传输到脚本中,例如echo "asdf" | myscript。重定向给了我同样的错误。你用的是香草vi还是vim?我怀疑这是我使用的 vi 版本的问题。
  • 这是 OSX 自带的,我认为是 vim。但问题是 vi 继承了脚本的 stdin,在您的情况下是重定向的。我找不到将stdin 转回终端的便携方式,因此我认为您必须使用其他答案中列出的平台特定方式之一。
【解决方案3】:

您的vi 程序的标准输入未连接到终端。一种解决方案是启动一个新终端:

os.system('xterm -e vi ' + fname)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多