Python实现简易剪贴板服务

我在使用 bt-keyboard-switcher 为 MacBook Air 11" Late 2010安装Alpine Linux的sway桌面 提供蓝牙键盘模拟来为 iPad mini 5 快捷输入,但是存在一个问题是,两个系统 Linux + iPad OS之间复制粘贴数据困难,特别是我依赖iPad来完成网页浏览和AI问答,总有文本数据需要传输给 Alpine Linux 系统使用。

利用 Python 自带的库创建一个 clip_server.py :

简易剪贴板服务
#!/usr/bin/env python3
from http.server import HTTPServer, BaseHTTPRequestHandler
import json

clipboard = ""


class ClipHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        global clipboard
        self.send_response(200)
        self.send_header("Content-type", "text/plain; charset=utf-8")
        self.end_headers()
        self.wfile.write(clipboard.encode("utf-8"))

    def do_POST(self):
        global clipboard
        content_length = int(self.headers.get("Content-Length", 0))
        body = self.rfile.read(content_length).decode("utf-8")

        try:
            # 解析快捷指令发送的 JSON 数据
            data = json.loads(body)
            clipboard = data.get("text", "")
        except json.JSONDecodeError:
            # 如果收到的是普通文本则直接保存
            clipboard = body

        self.send_response(200)
        self.end_headers()
        self.wfile.write(b"OK")


if __name__ == "__main__":
    server = HTTPServer(("0.0.0.0", 9999), ClipHandler)
    print("Clipboard server running on port 9999...")
    server.serve_forever()

在 Macbook 的 Alpine Linux 系统中运行上述服务,监听在 9999 端口上:

运行剪贴板服务
python3 clip_server.py

在 Macbook 的 Alpine Linux 设置 ~/.profile 添加以下2个alias:

设置 ~/.profile
# 将 Alpine 剪贴板发送给服务(需安装 wl-clipboard)
alias c2ipad='wl-paste | curl -X POST --data-binary @- http://127.0.0.1:9999'

# 从服务拉取文本到 Alpine 剪贴板
alias cfromipad='curl -s http://127.0.0.1:9999 | wl-copy'

iPad端设置快捷方式

创建“发送至 MacBook”快捷指令 (iPad ➜ Alpine)

  • 新建快捷指令:

    • 打开 iPad 上的 Shortcuts (快捷指令) App,点击右上角 + 新建

    • 名称重命名为:发送至 MacBook

  • 添加步骤 1: Get clipboard

  • 添加步骤 2: Get contents of URL

    • URL填写为服务地址,例如我这里填写 http://192.168.1.11:9999

    • 点击该动作右侧的展开箭头,修改以下参数:

      • 方法 (Method):选择 POST

      • 请求正文 (Request Body):选择 JSON

      • 点击下面的 Add new field ,直接在内容中选择 Clipboard

../../_images/send_to_mac.png
  • 先在iPad上复制一段文本,然后点击快捷指令的 播放图标 "▶️"

  • 此时在Macbook上运行的 clip_server.py 日志中应该看到有 POST 日志输出,并用主机上刚才设置的 alias 的命令 cfromipad 把数据放到本机的剪贴板中。接下来在任何文本编辑程序中粘贴验证

创建“从 MacBook 读取”快捷指令 (Alpine ➜ iPad)

  • 新建快捷指令,命名为 从 MacBook 读取

  • 添加步骤 1: Get contents of URL

    • URL填写为服务地址,例如我这里填写 http://192.168.1.11:9999

    • 方法保留默认的 GET

  • 添加步骤 2: Copy contents to Clipboard

../../_images/get_from_mac.png

备注

为方便使用可以在iPad上将快捷方式放到桌面以及作为下拉菜单小组件

警告

本文的剪贴板服务是非常简单的开放端口服务,没有任何认证,所以存在安全隐患。为加强安全,我感觉只能在家庭的局域网内使用,日常使用应该通过 Tailscale 来固定在局域网内部的一台服务器上提供服务,以便能够给个人简单使用。

Sway环境快捷键设置

  • 确保已安装必要工具:

安装工具软件
sudo apk add wl-clipboard curl jq
  • 在 Sway 配置文件中添加快捷键绑定:

sway配置文件 ~/.config/sway/config
# -----------------------------------------------------------------------------
# 剪贴板跨设备同步快捷键 (iPad <-> Alpine Python Clip-Server)
# -----------------------------------------------------------------------------

# Mod4 + Shift + v: 从 Python 剪贴板服务拉取最新文本,写入 Alpine 的 Wayland 剪贴板
bindsym $mod+Shift+v exec --no-startup-id "curl -s http://127.0.0.1:9999 | wl-copy"

# Mod4 + Shift + c: 将 Alpine 当前剪贴板的内容推送到 Python 剪贴板服务(供 iPad 拉取)
bindsym $mod+Shift+c exec --no-startup-id "wl-paste | jq -sR '{text: .}' | curl -X POST -H 'Content-Type: application/json' --data-binary @- http://127.0.0.1:9999"

参数说明:

  • --no-startup-id 避免按快捷键时出现等待鼠标指针

  • 推送命令中使用 jq -sR '{text: .}' 能自动将多行代码或包含引号/换行符的文本安全转义为标准 JSON 格式。

参考

  • gemini