nautilus 如何设置快捷键打开当前选中的文件?

See*_*uth 4 nautilus scripts gimp nautilus-script

厌倦Open With了在特定应用程序中右键单击打开文件,我想设置一个快捷方式来打开文件,例如 Gimp。不过,我不想更改默认的打开操作。(Ubuntu 14.04)

我试过的:

我已经设置了一个键盘快捷键来运行下面的脚本,以在指定的应用程序 (gimp) 中打开选定的 Nautilus 文件。

!/bin/sh
for file in $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS 
do
/usr/bin/gimp "$file"
done
Run Code Online (Sandbox Code Playgroud)

和...

!/bin/sh
/usr/bin/gimp "$1"
Run Code Online (Sandbox Code Playgroud)

但是,它永远不会在 nautilus 窗口中正确选择所选文件。

有没有办法做到这一点?

Ser*_*nyy 5

注意:在这个答案中有两个解决方案,每个都有自己的好处。鼓励用户找出哪一种最适合他们的特定情况。

介绍

Nautilus 本身不提供定义自定义键盘快捷键及其操作的方法。这是您尝试的脚本失败的主要原因。$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS只能通过右键单击子菜单使用。但是我们可以利用其他东西来实现预期的结果 - 在设置和系统剪贴板中定义的快捷方式。

Nautilus 内置于称为 Gtk 工具包的东西中。它是一个用于创建图形应用程序的扩展库,除其他外,它还有用于与系统剪贴板交互的实用程序。Nautilus 是一个文件管理器,它的特殊之处在于它将 URI 列表(以 形式file:///home/user/Pictures/encoded%image%name.png)输出到剪贴板(这对大多数用户来说并不是众所周知的事实,我最近也学到了)。显然,这是 GUI 文件管理器复制文件的方式。

我们可以通过复制文件的 URI(或者准确地说,是 URI 的列表;即使只有一个,它默认为一个列表)来利用这一事实。然后我们可以将该列表传递给gimp. 下面介绍的两个解决方案正是按照这个想法运作的。

2个解决方案的推理:

我个人认为解决方案#1 是首选。它首先依赖于手动按下复制快捷方式,然后是脚本快捷方式——这是两个键盘快捷键——但它的优势在于依赖性较少。这是一种更手动的方法,但相当不错。它使用os.execlp调用,它将用 Gimp 替换脚本的进程,从而仅充当Gimp. 在脚本和系统编程中经常使用exec函数族

编写第二个解决方案是因为 Jacob Vlijm 在评论中提到execlp,无论出于何种原因,该功能对他来说都不起作用。我觉得这很奇怪,因为它execlp属于ospython 的标准模块,它是默认安装的模块之一。此外,subprocess.Popen()默认为exec()函数族;从subprocess文档:

在 POSIX 上,shell=False(默认):在这种情况下,Popen 类使用 os.execvp() 来执行子程序。args 通常应该是一个序列。一个字符串将被视为一个序列,该字符串是唯一的项目(要执行的程序)。

(注意“On POSIX”是指“POSIX 兼容的操作系统”;Ubuntu 是 POSIX 兼容的)

因此,这似乎不是功能本身的问题,而是用户系统的问题。尽管如此,我还是写了第二个脚本。那个使用subprocess模块并依赖于xdotool,它基本上会自动为您按下Ctrl+C快捷方式,然后启动 Gimp。我个人不太喜欢这个,因为它需要安装额外的项目,但它的优点是只需要一个键盘快捷键。

然而,这个想法是一样的。我们仍然使用 Gtk 工具来查询剪贴板内容,并且在每种情况下,脚本都必须绑定到快捷方式。

解决方案#1,两个快捷方式,最小依赖

用法:选择文件并先按Ctrl+C复制文件,然后按您分配给此脚本的快捷方式。execlp函数将用gimp.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from gi.repository import Gtk, Gdk
from os import execlp
from time import sleep
from urllib.parse import unquote
import signal
import threading
import subprocess

uris = None

def autoquit():
    global uris
    #sleep(0.5)
    while not uris:
       # allow sufficient time to obtain uris
       sleep(2)
       pass
    Gtk.main_quit()

def get_clipboard_contents():
    global uris
    clip = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
    tr = threading.Thread(target=autoquit)
    tr.daemon = True
    tr.start()
    uris = clip.wait_for_uris()
    Gtk.main()
    return [unquote(i).replace('file://','')
           for i in uris]
def main():
    signal.signal(signal.SIGINT,signal.SIG_DFL)
    files = get_clipboard_contents()
    print(files)
    args = ['gimp'] + files
    execlp('gimp',*args)

if __name__ == '__main__': main()
Run Code Online (Sandbox Code Playgroud)

解决方案#2:单一快捷方式,xdotool 依赖

此脚本的用法更简单:在 Nautilus 中选择文件并按键盘快捷键。注意:您必须已xdotool安装此功能才能工作,请使用sudo apt-get install xdotool.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from gi.repository import Gtk, Gdk
from subprocess import Popen,STDOUT
from time import sleep
from urllib.parse import unquote
import sys

def unquote_uri(*args):
    uris = args[-2]
    unquoted_args = [ str(unquote(i).replace('file://',''))
                      for i in uris]
    with open('/dev/null','w') as dev_null:
        proc = Popen(['gimp',*unquoted_args],stdout=dev_null,stderr=STDOUT)
    Gtk.main_quit()


def main():
    # NOTE: xdotool is REQUIRED for this to work
    Popen(['xdotool','key','Ctrl+c'])
    sleep(0.5)
    clip = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
    clip.request_uris(unquote_uri, None)
    Gtk.main()

if __name__ == '__main__': main()
Run Code Online (Sandbox Code Playgroud)

设置快捷方式

在这两种情况下,您都需要将脚本链接到快捷方式。打开系统设置 -> 键盘 -> 快捷方式 -> 自定义。单击+按钮。提供文件的完整 (!) 路径作为命令。例如,/home/User_Name/bin/clipboard_launch.py

在此处输入图片说明

指定快捷方式是明智的。例如,由于我们正在调用 Gimp,我已将我的脚本分配给Ctrl+ Super+ G