私の最初の目標は、Pythonスクリプト内からコマンドラインのテキストエディタを使ってユーザ入力を得ることでした。具体的には、私の計画は、一時的なファイルを作成し、あらかじめ書き込まれたテキストを入力し、テキストエディタでファイルを開き、ユーザーがファイルの内容を変更できるようにし、ユーザーがファイルを終了した後、エディタを開き、最後にすべてのファイルを削除します。PythonのサブプロセスでVimを使った一時ファイルを編集するのがMac OSで期待どおりに動作しない
これは私のために働く方法を見つけたようですが、方法によってはうまくいかなかったいくつかのアプローチを試みましたが、その理由を正確に理解したいと思います。
は、次のPythonスクリプト(this postから取られたスクリプトを少し変更したバージョンを)考えてみましょう:
#!/usr/bin/env python2
# -*- encoding: ascii -*-
"""callvim.py
Demonstrates calling a text-editor (e.g. Vim) from within a Python script,
including passing input to the editor and reading output from the editor.
"""
import tempfile
import os
from subprocess import call
# Get the text editor from the shell, otherwise default to Vim
EDITOR = os.environ.get('EDITOR','vim')
# Set initial input with which to populate the buffer
initial_message = "Hello world!"
# Open a temporary file to communicate through
with tempfile.NamedTemporaryFile(suffix=".tmp") as tf:
# Write the initial content to the file I/O buffer
tf.write(initial_message)
# Flush the I/O buffer to make sure the data is written to the file
tf.flush()
# Open the file with the text editor
call([EDITOR, tf.name])
# Rewind the file offset to the beginning of the file
tf.seek(0)
# Read the file data into a variable
edited_message = tf.read()
# Output the data
print(edited_message)
私がこれまでに2つの異なる環境でこのスクリプトを実行しようとしました:MacOSのコンピュータ上で(MacOSの実行します10.12)とDebianコンピュータ(Debian 8.8を実行中)にあります。どちらのコンピュータも同じ(マイナー)バージョンのVimがインストールされています(Vim 7.4)。
Debian 8(Jessie)マシンでEDITOR=vim
とこのスクリプトを実行すると、期待通りに動作します。私はVimと "Hello world!"という文字列を含むバッファを入力するように求められます。 "Goodbye world!"という文字列を含むようにバッファを編集してファイルを保存し、Vimを終了すると、 "Goodbye world!"という文字列が表示されます。コンソールに印刷されます。
MacOS 10.12(Sierra)マシンで同じスクリプトを実行すると、動作しないようです。同じ手順で「Hello world!」が表示されます。あたかもファイルが編集される前に読み込まれているかのように画面に表示されます。
しかし、私のMacでEDITOR=nano
のスクリプトを実行すると、もう一度すべてが期待どおりに機能しているようです。
このスクリプトでは、tempfile
モジュールとは異なる方法(例:tempfile.TemporaryFile()
とtempfile.mkstemp()
を使用)を使用して、同じ結果を得ていくつかのバリエーションを試しました。
ここで、次の代替のスクリプトを考えてみます。
#!/usr/bin/env python2
# -*- encoding: ascii -*-
"""callvim.py
Demonstrates calling a text-editor (e.g. Vim) from within a Python script,
including passing input to the editor and reading output from the editor.
"""
import subprocess
import os
# Create a temporary file and write some default text
file_path = "tempfile"
file_handle = open(file_path, "w")
file_handle.write("Hello world!")
file_handle.close()
# Open the file with Vim
subprocess.call(["vim", file_path])
# Rewind to the beginning of the file
file_handle = open(file_path, 'r')
# Read the data from the file
data = file_handle.read()
# Close the temporary file
file_handle.close()
# Delete the temporary file
os.remove(file_path)
# Print the data
print(data)
tempfile
モジュールを使用して回避このスクリプトでは、両方のプラットフォーム間で一貫して取り組んでいるように見えます。
このスクリプトは、Vimとtempfile
PythonモジュールがmacOS上でどのようにやりとりするかと何らかの理由で失敗しているようです。何が起きてる?