簡體   English   中英

如何使用 python 或 CL 將文件復制到剪貼板,以便稍后使用 STRG+V 粘貼?

[英]How copy file to clipboard using python or CL to paste it using STRG+V later on?

我正在嘗試將文件復制(使用 python 或我可以使用 python 調用的 CL 命令)到剪貼板,以便稍后使用 STRG+V 將其粘貼。 據我了解,文件不會“移動”到剪貼板中,而是剪貼板保存路徑和告訴操作系統“這是一個文件”的參數/標志。 我對特定於 linux 的答案感到滿意,但通用答案將是最重要的。

彈夾

不是解決方案,因為它不允許復制文件,只允許復制字符串。

剪輯

不是解決方案,因為它只復制文本

xclip-copyfile

不是解決方案,因為它只復制到 X 剪貼板,而不是剪貼板。 雖然 xclip 提供選項 -selection -selection clipboard (但只復制文本),但xclip-copyfile沒有這樣的選項。

使用查找

find ${PWD} -name "*.pdf"| xclip -i -selection clipboard -t text/uri-list

是此處描述的命令: https://askubuntu.com/questions/210413/what-is-the-command-line-equivalent-of-copying-a-file-to-clipboard#answer-210428

但我不能用它復制復制文件,因此假設它不適用於所有文件。

配置

剪貼板是 Window 管理的一部分,而不是 Linux 操作系統本身的一部分。 具有不同分布的不同配置表現不同,因此需要不同的變體。 與此同時,Wayland 也越來越多地陸續取代 X,這意味着需要考慮三種配置:

  • 僅限韋蘭
  • Wayland 與 XWayland 一起(與未適配的 X 軟件兼容)
  • X

發送剪貼板內容

保存到剪貼板時,系統首先只通知接收者數據可用於剪貼板。 只有在請求時才會發送實際數據。 因此,在傳輸數據之前不得終止將內容發送到剪貼板的程序。 根據環境/配置,也有可能在程序終止后立即刪除剪貼板的內容。

那么問題中已經提到的xclip程序是如何工作的呢? 它似乎在被調用后立即終止。 但仔細觀察它並沒有,因為它執行一個分叉,因此它仍然存在於后台(通過查看源代碼或命令ps很容易驗證)。

格式

此外,不同的環境以不同的方式需要內容。 例如,GNOME 需要使用特殊目標x-special/gnome-copied-files和內容的特殊格式復制的文件列表,例如 GNOME 文件管理器 Nautilus 的copy\nfile:///etc/group到正確執行復制操作。

另一方面,在 KDE 下,只有一個帶有目標text/uri-list的 URI 列表。

確定環境

以下示例程序適用於帶有 Gnome 的 Linuxmint 20.2 Cinnamon、Ubuntu 22.04 和帶有 KDE 的 Kubuntu 22.04。 其他發行版/配置可能需要一些定制。 這里建議在適當的文件管理器中簡單地復制文件,然后使用程序查看剪貼板內容,然后對腳本進行適當的調整。

基於環境變量XDG_CURRENT_DESKTOPWAYLAND_DISPLAY ,以下程序嘗試確定環境。

如果是Wayland,則使用wl-copy ,否則使用xclip 相應地調整目標和內容格式。 使用subprocess.Popen啟動工具並將內容發送到工具的stdin

完成后,程序退出。 然后wl-copyxclip創建一個 fork,確保數據存在於剪貼板中。

import os
import subprocess
import sys
from pathlib import Path

gnome_desktops = ['X-Cinnamon', 'XFCE']


def is_gnome(desktop):
    if desktop.endswith("GNOME") or desktop in gnome_desktops:
        return True
    return False


def target():
    current_desktop = os.environ['XDG_CURRENT_DESKTOP']
    if is_gnome(current_desktop):
        return 'x-special/gnome-copied-files'
    elif current_desktop == 'KDE':
        return 'text/uri-list'
    else:
        sys.exit(f'unsupported desktop {current_desktop}')


def base_copy_cmd():
    if 'WAYLAND_DISPLAY' in os.environ:
        return 'wl-copy'
    return 'xclip -i -selection clipboard'


def copy_clipboard_cmd():
    return f"{base_copy_cmd()} -t '{target()}'"


def content(files_to_copy):
    uris = '\n'.join([Path(f).as_uri() for f in files_to_copy])
    current_desktop = os.environ['XDG_CURRENT_DESKTOP']
    if is_gnome(current_desktop):
        return f"copy\n{uris}".encode("utf-8")
    return uris.encode("utf-8")


def copy_to_clipboard(files_to_copy):
    copy_process = subprocess.Popen(copy_clipboard_cmd(), shell=True, stdin=subprocess.PIPE)
    copy_process.stdin.write(content(files_to_copy))
    copy_process.stdin.close()
    copy_process.wait()


if __name__ == '__main__':
    files = ['/etc/hosts', '/etc/group']
    copy_to_clipboard(files)

如上所述,對於其他環境,只需在本機文件管理器中復制文件,然后檢查當前剪貼板內容並對腳本進行適當調整。

根據環境, xclipwl-copy (使用 package 管理器安裝 package wl-clipboard )必須在那里。 關於wl-copy詳細信息可以在這里找到: https://github.com/bugaevc/wl-clipboard

檢查剪貼板

最后,為了能夠轉儲剪貼板的當前內容,這里有一個小腳本可以做到這一點。 因此可以查看其他程序(如本機文件管理器)放入剪貼板。 通常許多程序將相同數據的幾個不同表示目標放入剪貼板。

import gi

gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk


def on_activate(app):
    win = Gtk.ApplicationWindow(application=app)
    win.set_title("GTK Clipboard Util")
    win.set_default_size(256, 192)
    btn = Gtk.Button(label="Dump Clipboard")
    btn.connect('clicked', dump)
    box = Gtk.VBox()
    win.add(box)
    box.add(btn)
    win.show_all()


def dump(button):
    cb_targets = []
    counter = 0

    def print_content(clipboard, data):
        print(data.get_data())
        print()
        print_next_target_and_content(clipboard)

    def print_next_target_and_content(clipboard):
        nonlocal counter
        if counter < len(cb_targets):
            target = cb_targets[counter]
            print(target)
            clipboard.request_contents(target, print_content)
            counter += 1

    def get_targets(clipboard, targets, n_targets):
        nonlocal counter
        nonlocal cb_targets
        counter = 0
        cb_targets = targets
        print_next_target_and_content(clipboard)

    gtk_clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
    gtk_clipboard.request_targets(get_targets)


if __name__ == '__main__':
    app = Gtk.Application(application_id='com.software7.clipboard.formats')
    app.connect('activate', on_activate)
    app.run(None)

根據我的理解,您想使用 python 在操作系統中復制文件,就像“ctrl + c”一樣。

您的字符串需要根據 windows 和 linux 操作系統規范正確格式化,這需要您處理許多邊緣情況,因此最好讓操作系統完成所有工作

windows 的簡單方法是以下腳本

import subprocess, sys    
p = subprocess.Popen("powershell.exe -command \"Set-Clipboard -Path D:\copy_file.py\"", stdout=sys.stdout)
p.communicate()

對於 linux,我找到了可以運行的以下命令。

import os
os.system("xclip-copyfile /home/copy_file.py") #copies file to clipboard

介紹


我之前發現自己遇到過類似的問題(但復制目錄),這是我想出的解決方案,這是一個個人解決方案,但我能找到的最佳選擇。

注意:這是特定於 linux 的答案,它不適用於 windows 假設它很好,因為 OP。 指定linux標簽

解決方案


實際上xclip有另一種方法可以將文件復制到目錄中。

xclip-copyfile是一個文件復制命令,可將多個文件復制到剪貼板。

這需要可以通過aptpacmanyum安裝的xclip package

sudo pacman -S xclip # Arch
sudo apt install xclip # Debian/Ubuntu
yum install xclip #RHEL/Centos

如果不起作用嘗試更新數據庫

尋找剪切/粘貼代替?

還有一個替代方法,列在https://linux.die.net/man/1/xclip-copyfile還有另外 2 個命令:

  • xclip-cutfile ,用來代替剪切。
  • xclip-pastefile ,用於粘貼。

概要

xclip-copyfile [-p] FILES...

xclip-cutfile [-p] FILES...

xclip-pastefile

所有 rest 都可以在linux.die.net上的文檔中找到(以上主要文章)

有用的鏈接

這里有一些有用的鏈接,可以檢查您是否對該主題感興趣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM