[英]Change the default path to open Python3 in Sublime Text (OS X)
[英]Python3/Linux - Open text file in default editor and wait until done
我需要等到用戶在默認圖形應用程序(Debian 和衍生產品)中編輯完文本文件。
如果我將 xdg-open 與 subprocess.call 一起使用(通常會等待),它將在編輯器中打開文件后繼續。 我假設是因為 xdg-open 本身異步啟動編輯器。
通過檢索 text/plain mime 類型的啟動器並將其與 Gio.DesktopAppInfo.new 一起使用來獲取編輯器的命令,我終於獲得了或多或少的工作代碼。 假設編輯器尚未打開,在這種情況下,該過程在編輯器仍處於打開狀態時結束。
我添加了檢查 process.pid 和輪詢進程的解決方案。 兩者都以無限循環結束。
等待過程完成似乎是一種過於復雜的方式。 那么,有沒有更強大的方法來做到這一點?
#! /usr/bin/env python3
import subprocess
from gi.repository import Gio
import os
from time import sleep
import sys
def open_launcher(my_file):
print('launcher open')
app = subprocess.check_output(['xdg-mime', 'query', 'default', 'text/plain']).decode('utf-8').strip()
print(app)
launcher = Gio.DesktopAppInfo.new(app).get_commandline().split()[0]
print(launcher)
subprocess.call([launcher, my_file])
print('launcher close')
def open_xdg(my_file):
print('xdg open')
subprocess.call(['xdg-open', my_file])
print('xdg close')
def check_pid(pid):
""" Check For the existence of a unix pid. """
try:
os.kill(int(pid), 0)
except OSError:
return False
else:
return True
def open_pid(my_file):
pid = subprocess.Popen(['xdg-open', my_file]).pid
while check_pid(pid):
print(pid)
sleep(1)
def open_poll(my_file):
proc = subprocess.Popen(['xdg-open', my_file])
while not proc.poll():
print(proc.poll())
sleep(1)
def open_ps(my_file):
subprocess.call(['xdg-open', my_file])
pid = subprocess.check_output("ps -o pid,cmd -e | grep %s | head -n 1 | awk '{print $1}'" % my_file, shell=True).decode('utf-8')
while check_pid(pid):
print(pid)
sleep(1)
def open_popen(my_file):
print('popen open')
process = subprocess.Popen(['xdg-open', my_file])
process.wait()
print(process.returncode)
print('popen close')
# This will end the open_xdg function while the editor is open.
# However, if the editor is already open, open_launcher will finish while the editor is still open.
#open_launcher('test.txt')
# This solution opens the file but the process terminates before the editor is closed.
#open_xdg('test.txt')
# This will loop indefinately printing the pid even after closing the editor.
# If you check for the pid in another terminal you see the pid with: [xdg-open] <defunct>.
#open_pid('test.txt')
# This will print None once after which 0 is printed indefinately: the subprocess ends immediately.
#open_poll('test.txt')
# This seems to work, even when the editor is already open.
# However, I had to use head -n 1 to prevent returning multiple pids.
#open_ps('test.txt')
# Like open_xdg, this opens the file but the process terminates before the editor is closed.
open_popen('test.txt')
您可以使用subprocess.Popen.wait()
簡單地等待子進程終止,而不是嘗試輪詢 PID:
等待子進程終止。 設置並返回 returncode 屬性。
此外,獲取get_commandline()
的第一部分並不能保證是啟動器。 get_commandline()
返回的字符串將匹配Exec
key spec ,這意味着返回字符串中的%u
、 %U
、 %f
和%F
字段代碼應替換為正確的值。
以下是一些示例代碼,基於您的xdg-mime
方法:
#!/usr/bin/env python3
import subprocess
import shlex
from gi.repository import Gio
my_file = 'test.txt'
# Get default application
app = subprocess.check_output(['xdg-mime', 'query', 'default', 'text/plain']).decode('utf-8').strip()
# Get command to run
command = Gio.DesktopAppInfo.new(app).get_commandline()
# Handle file paths with spaces by quoting the file path
my_file_quoted = "'" + my_file + "'"
# Replace field codes with the file path
# Also handle special case of the atom editor
command = command.replace('%u', my_file_quoted)\
.replace('%U', my_file_quoted)\
.replace('%f', my_file_quoted)\
.replace('%F', my_file_quoted if app != 'atom.desktop' else '--wait ' + my_file_quoted)
# Run the default application, and wait for it to terminate
process = subprocess.Popen(
shlex.split(command), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
process.wait()
# Now the exit code of the text editor process is available as process.returncode
我對我的示例代碼有幾點意見。
備注 1:處理文件路徑中的空格
重要的是要打開的文件路徑用引號引起來,否則shlex.split(command)
會將文件名拆分為空格。
備注 2:轉義%
字符
Exec
關鍵規范指出
文字百分比字符必須轉義為 %%。
我對replace()
的使用可能會替換%
被轉義的字符。 為簡單起見,我選擇忽略這種邊緣情況。
備注3:原子
我假設所需的行為是始終等到圖形編輯器關閉。 對於atom文本編輯器,它將在啟動 window 時立即終止,除非提供了--wait
選項。 出於這個原因,如果默認編輯器是 atom,我有條件地添加--wait
選項。
備注4: subprocess.DEVNULL
subprocess.DEVNULL
是 python 3.3 中的新功能。 對於較舊的 python 版本,可以使用以下版本:
with open(os.devnull, 'w') as DEVNULL:
process = subprocess.Popen(
shlex.split(command), stdout=DEVNULL, stderr=DEVNULL)
測試
我使用 GNOME 桌面環境在 Ubuntu 上測試了上面的示例代碼。 我使用以下圖形文本編輯器進行了測試: gedit 、 mousepad和atom 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.