вызвать РЕДАКТОР (vim) из скрипта Python - PullRequest
39 голосов
/ 10 июня 2011

Я хочу вызвать редактор в скрипте Python для запроса ввода от пользователя, так же, как crontab e или git commit делает.

Вот фрагмент из того, что я запускаю до сих пор. (В будущем я мог бы использовать $ EDITOR вместо vim, чтобы люди могли настраивать их по своему вкусу.)

tmp_file = '/tmp/up.'+''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(6))
edit_call = [ "vim",tmp_file]
edit = subprocess.Popen(edit_call,stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True )   

Моя проблема в том, что, используя Popen, кажется, что мой ввод-вывод со скриптом python не может перейти в рабочую копию vim, и я не могу найти способ просто передать ввод-вывод в vim , Я получаю следующую ошибку.

Vim: Warning: Output is not to a terminal
Vim: Warning: Input is not from a terminal

Какой лучший способ вызвать программу CLI из python, передать управление ей, а затем передать ее обратно, как только закончите с ней?

Ответы [ 4 ]

67 голосов
/ 10 июня 2011

Вызов $ РЕДАКТОР прост. Я написал такой код для вызова редактора:

import sys, tempfile, os
from subprocess import call

EDITOR = os.environ.get('EDITOR','vim') #that easy!

initial_message = "" # if you want to set up the file somehow

with tempfile.NamedTemporaryFile(suffix=".tmp") as tf:
  tf.write(initial_message)
  tf.flush()
  call([EDITOR, tf.name])

  # do the parsing with `tf` using regular File operations.
  # for instance:
  tf.seek(0)
  edited_message = tf.read()

Хорошо, что библиотеки обрабатывают создание и удаление временного файла.

5 голосов
/ 12 октября 2016

В python3: 'str' does not support the buffer interface

$ python3 editor.py
Traceback (most recent call last):
  File "editor.py", line 9, in <module>
    tf.write(initial_message)
  File "/usr/lib/python3.4/tempfile.py", line 399, in func_wrapper
    return func(*args, **kwargs)
TypeError: 'str' does not support the buffer interface

Для python3 используйте initial_message = b"" для объявления буферизованной строки.

Затем используйте edited_message.decode("utf-8") для декодирования буфера в строку.

import sys, tempfile, os
from subprocess import call

EDITOR = os.environ.get('EDITOR','vim') #that easy!

initial_message = b"" # if you want to set up the file somehow

with tempfile.NamedTemporaryFile(suffix=".tmp") as tf:
    tf.write(initial_message)
    tf.flush()
    call([EDITOR, tf.name])

    # do the parsing with `tf` using regular File operations.
    # for instance:
    tf.seek(0)
    edited_message = tf.read()
    print (edited_message.decode("utf-8"))

Результат:

$ python3 editor.py
look a string
3 голосов
/ 28 сентября 2017

Пакет python-editor:

$ pip install python-editor
$ python
>>> import editor
>>> result = editor.edit(contents="text to put in editor\n")

Подробнее здесь: https://github.com/fmoo/python-editor

3 голосов
/ 10 июня 2011

ТРУБА - это проблема.VIM - это приложение, которое зависит от того факта, что каналы stdin / stdout являются терминалами, а не файлами или каналами.Удаление параметров stdin / stdout помогло мне.

Я бы не стал использовать os.system, поскольку следует заменить на модуль подпроцесса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...