简体   繁体   English

如何使用 python 或 CL 将文件复制到剪贴板,以便稍后使用 STRG+V 粘贴?

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

I am trying to copy (using python or a CL command which I then can call using python) a file to the clipboard to later paste it using STRG+V.我正在尝试将文件复制(使用 python 或我可以使用 python 调用的 CL 命令)到剪贴板,以便稍后使用 STRG+V 将其粘贴。 As far as I understand it, files are not "moved" into the clipboard, but rather the clipboard holds the path and an argument/flag that tells the OS "this is a file".据我了解,文件不会“移动”到剪贴板中,而是剪贴板保存路径和告诉操作系统“这是一个文件”的参数/标志。 I am happy with a linux-specific answer, but a universal answer would be the cherry on top.我对特定于 linux 的答案感到满意,但通用答案将是最重要的。

pyperclip弹夹

Is not a solution, because it doesn't allow to copy files, just strings.不是解决方案,因为它不允许复制文件,只允许复制字符串。

xclip剪辑

Is not a solution, because it only copies text不是解决方案,因为它只复制文本

xclip-copyfile xclip-copyfile

Is not a solution, because it only copies to the X clipboard, not the clipboard.不是解决方案,因为它只复制到 X 剪贴板,而不是剪贴板。 While xclip offers the option -selection clipboard (but only copies text), xclip-copyfile has no such option.虽然 xclip 提供选项 -selection -selection clipboard (但只复制文本),但xclip-copyfile没有这样的选项。

Using find使用查找

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

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

But I can't replicate copying files with it and therefore assume that it is not working for all files.但我不能用它复制复制文件,因此假设它不适用于所有文件。

Configurations配置

The clipboard is part of the Window Management and not of the Linux operating system itself.剪贴板是 Window 管理的一部分,而不是 Linux 操作系统本身的一部分。 Different configurations with different distributions behave differently and therefore require different variants.具有不同分布的不同配置表现不同,因此需要不同的变体。 Meanwhile, Wayland is increasingly on the way to successively replace X, which means there are three configurations to consider:与此同时,Wayland 也越来越多地陆续取代 X,这意味着需要考虑三种配置:

  • Wayland only仅限韦兰
  • Wayland together with XWayland (compatibility with non-adapted X software) Wayland 与 XWayland 一起(与未适配的 X 软件兼容)
  • X X

Sending clipboard content发送剪贴板内容

When saving to the clipboard, the system first only informs the receiver that data is available for the clipboard.保存到剪贴板时,系统首先只通知接收者数据可用于剪贴板。 Only on request, the actual data is sent.只有在请求时才会发送实际数据。 The program that sends the content to the clipboard must therefore not be terminated before the data has been transferred.因此,在传输数据之前不得终止将内容发送到剪贴板的程序。 Depending on the environment/configuration, it is also possible that the content of the clipboard is deleted as soon as the program is terminated.根据环境/配置,也有可能在程序终止后立即删除剪贴板的内容。

How then does the xclip program already mentioned in the question work?那么问题中已经提到的xclip程序是如何工作的呢? It seems to terminate immediately after being called.它似乎在被调用后立即终止。 But on closer inspection it doesn't, because it performs a fork, so that it is still present in the background (easily verifiable by looking at the source code or the command ps ).但仔细观察它并没有,因为它执行一个分叉,因此它仍然存在于后台(通过查看源代码或命令ps很容易验证)。

Format格式

Furthermore, different environments require the content in different ways.此外,不同的环境以不同的方式需要内容。 For example GNOME requires the list of files to be copied with the special target x-special/gnome-copied-files and a special formatting of the content, eg copy\nfile:///etc/group for the GNOME file manager Nautilus to perform the copy operation correctly.例如,GNOME 需要使用特殊目标x-special/gnome-copied-files和内容的特殊格式复制的文件列表,例如 GNOME 文件管理器 Nautilus 的copy\nfile:///etc/group到正确执行复制操作。

Under KDE, on the other hand, there is then only one URI list with the target text/uri-list .另一方面,在 KDE 下,只有一个带有目标text/uri-list的 URI 列表。

Determining the environment确定环境

The following example program works for Linuxmint 20.2 Cinnamon, Ubuntu 22.04 with Gnome and Kubuntu 22.04 with KDE.以下示例程序适用于带有 Gnome 的 Linuxmint 20.2 Cinnamon、Ubuntu 22.04 和带有 KDE 的 Kubuntu 22.04。 Other distributions / configurations may require some customization.其他发行版/配置可能需要一些定制。 Here it is advisable to simply copy a file in the appropriate file manager and then look at the clipboard contents with a program and then make appropriate adaptions to the script.这里建议在适当的文件管理器中简单地复制文件,然后使用程序查看剪贴板内容,然后对脚本进行适当的调整。

Based on the environment variables XDG_CURRENT_DESKTOP and WAYLAND_DISPLAY the following program tries to determine the environments.基于环境变量XDG_CURRENT_DESKTOPWAYLAND_DISPLAY ,以下程序尝试确定环境。

If it is Wayland, wl-copy is used, otherwise xclip is used.如果是Wayland,则使用wl-copy ,否则使用xclip The target and the content formatting is adapted accordingly.相应地调整目标和内容格式。 With subprocess.Popen the tool is started and the content is sent to stdin of the tool.使用subprocess.Popen启动工具并将内容发送到工具的stdin

As soon as this is done, the program exits.完成后,程序退出。 Both wl-copy and xclip then create a fork, ensuring that the data is present in the clipboard.然后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)

As mentioned above for other environments simply copy a file in the native file manager and then inspect the current clipboard contents and make appropriate adjustments to the script.如上所述,对于其他环境,只需在本机文件管理器中复制文件,然后检查当前剪贴板内容并对脚本进行适当调整。

Depending on the environment, xclip or wl-copy (install the package wl-clipboard with your package manager) must be there.根据环境, xclipwl-copy (使用 package 管理器安装 package wl-clipboard )必须在那里。 Detailed information about wl-copy can be found here: https://github.com/bugaevc/wl-clipboard .关于wl-copy详细信息可以在这里找到: https://github.com/bugaevc/wl-clipboard

Inspect Clipboard检查剪贴板

Finally, to be able to dump the current contents of the clipboard, here is a small script that does just that.最后,为了能够转储剪贴板的当前内容,这里有一个小脚本可以做到这一点。 So it is possible to see what other programs like the native file manager put into the clipboard.因此可以查看其他程序(如本机文件管理器)放入剪贴板。 Usually many programs put several different representations targets of the same data into the 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)

Based on my understanding, you want to copy file just like "ctrl + c" in os using python.根据我的理解,您想使用 python 在操作系统中复制文件,就像“ctrl + c”一样。

Your string will need to be correctly formatted according to windows and linux OS specification which requires you to handle many edge cases so it would be better if you let the OS do all the work您的字符串需要根据 windows 和 linux 操作系统规范正确格式化,这需要您处理许多边缘情况,因此最好让操作系统完成所有工作

An easy way for windows is the following script windows 的简单方法是以下脚本

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

For linux, I found the following command which you can run.对于 linux,我找到了可以运行的以下命令。

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

Introduction介绍


I've found myself in a similar problem before(but copying directory) and here's the solution i came up with, it's a personal solution but the best alternative I could find.我之前发现自己遇到过类似的问题(但复制目录),这是我想出的解决方案,这是一个个人解决方案,但我能找到的最佳选择。

NOTE : This is linux-specific answer and it won't work on windows assumed it was fine since the OP.注意:这是特定于 linux 的答案,它不适用于 windows 假设它很好,因为 OP。 specified the linux tag指定linux标签

Solution解决方案


Actually xclip has an alternative for file-copying recursing into directory.实际上xclip有另一种方法可以将文件复制到目录中。

xclip-copyfile is a file-copying command that copies multiple files to your clipboard. xclip-copyfile是一个文件复制命令,可将多个文件复制到剪贴板。

This requires the xclip package that can be installed via apt , pacman and yum这需要可以通过aptpacmanyum安装的xclip package

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

if doesn't work try updating the database如果不起作用尝试更新数据库

Looking for cut/paste instead?寻找剪切/粘贴代替?

There is an alternative too, listed in https://linux.die.net/man/1/xclip-copyfile there are also 2 other commands:还有一个替代方法,列在https://linux.die.net/man/1/xclip-copyfile还有另外 2 个命令:

  • xclip-cutfile , used to cut instead. xclip-cutfile ,用来代替剪切。
  • xclip-pastefile , used to paste instead. xclip-pastefile ,用于粘贴。

Synopsis概要

xclip-copyfile [-p] FILES...

xclip-cutfile [-p] FILES...

xclip-pastefile

All the rest can be found on the documentation on linux.die.net (main articols above)所有 rest 都可以在linux.die.net上的文档中找到(以上主要文章)

Useful links有用的链接

Here are some useful links to check out if you are intrested in the subject.这里有一些有用的链接,可以检查您是否对该主题感兴趣。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM