Вызовите EDITOR (vim) из python script
Я хочу вызвать редактор в python script для запроса ввода от пользователя, как это делают 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, мне кажется, что мой i/o с python script не попадает в текущую копию vim, и я не могу найти способ просто передать i/o через к vim. Я получаю следующую ошибку.
Vim: Warning: Output is not to a terminal
Vim: Warning: Input is not from a terminal
Какой лучший способ вызвать CLI-программу из python, передать ее вручную, а затем передать ее после того, как вы закончите с ней?
Ответы
Ответ 1
Вызов $EDITOR прост. Я написал этот код для вызова редактора:
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()
Хорошо, что библиотеки обрабатывают создание и удаление временного файла.
Ответ 2
В 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
Проблема PIPE. VIM - это приложение, которое зависит от того, что каналы stdin/stdout являются терминалами, а не файлами или каналами. Удаление параметров stdin/stdout работало для меня.
Я бы избегал использования os.system, так как должен быть заменен модулем подпроцесса.
Ответ 4
Пакет 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