![](/img/trans.png)
[英]How does files get copy/cut/paste using clipboard operations (ctrl-c /ctrl-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
但我不能用它复制复制文件,因此假设它不适用于所有文件。
配置
剪贴板是 Window 管理的一部分,而不是 Linux 操作系统本身的一部分。 具有不同分布的不同配置表现不同,因此需要不同的变体。 与此同时,Wayland 也越来越多地陆续取代 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_DESKTOP
和WAYLAND_DISPLAY
,以下程序尝试确定环境。
如果是Wayland,则使用wl-copy
,否则使用xclip
。 相应地调整目标和内容格式。 使用subprocess.Popen
启动工具并将内容发送到工具的stdin
。
完成后,程序退出。 然后wl-copy
和xclip
创建一个 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)
如上所述,对于其他环境,只需在本机文件管理器中复制文件,然后检查当前剪贴板内容并对脚本进行适当调整。
根据环境, xclip
或wl-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
是一个文件复制命令,可将多个文件复制到剪贴板。
这需要可以通过apt
、 pacman
和yum
安装的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.