Введение

При работе на удалённых серверах через SSH часто возникает задача: скопировать данные из удалённой сессии в буфер обмена локальной машины. На macOS локальная команда pbcopy решает эту задачу, но при выполнении на удалённом сервере данные попадают в буфер удалённой машины (если он вообще существует), а не локальной. Обзор рассматривает все доступные подходы к решению этой задачи — от встроенных механизмов терминалов до специализированных утилит.

OSC 52 — Escape-последовательность для буфера обмена

Принцип работы

OSC 52 (Operating System Command 52) — ANSI escape-последовательность, которая инструктирует терминальный эмулятор записать данные в системный буфер обмена 1. Формат последовательности:

ESC ] 52 ; c ; <base64-данные> BEL

Терминал перехватывает эту последовательность, декодирует base64-содержимое и помещает его в системный clipboard. Ключевое свойство — последовательность работает независимо от того, где она была сгенерирована: локально, через SSH или через цепочку SSH → tmux → Neovim 2.

“OSC 52 is location-independent — the terminal doesn’t care where the sequence originates, even from a remote SSH session” 1.

Минимальный скрипт

На удалённом сервере достаточно создать скрипт-замену pbcopy:

#!/bin/bash
# ~/bin/pbcopy — копирование в локальный буфер через OSC 52
printf "\033]52;c;%s\007" "$(base64 | tr -d '\n')"

Использование: echo "текст" | pbcopy или cat file.txt | pbcopy 3.

Ограничения

Максимальный объём передаваемых данных — приблизительно 74 994 байта (~75 КБ) из-за ограничений длины escape-последовательности (100 000 байт с учётом base64-оверхеда) 1.

Поддержка терминалами

ТерминалПоддержкаПримечания
iTerm2ДаТребует включения в Preferences → General → “Allow clipboard access” 4
AlacrittyДаРаботает из коробки 1
kittyДаРекомендуется clipboard_control no-append в конфиге из-за бага с append 1
WezTermДаРаботает из коробки 1
Windows TerminalЧастичноТолько копирование, вставка заблокирована 5
xtermДаОтключено по умолчанию; требует XTerm.vt100.allowWindowOps: true в .Xresources 1
footДаРаботает из коробки 1
GNOME TerminalНетНе поддерживает OSC 52 1
VTE-терминалы (XFCE Terminal, Terminator)НетНе поддерживают 1

Конфигурация tmux

tmux требует явного включения поддержки OSC 52. Конфигурация в ~/.tmux.conf:

# Включить поддержку clipboard
set -s set-clipboard on

# Для tmux 3.3+ — разрешить passthrough escape-последовательностей
set -g allow-passthrough on

# Указать terminal features для конкретных эмуляторов
set -as terminal-features "xterm*:clipboard"
set -as terminal-features "alacritty:clipboard"
set -as terminal-features "kitty:clipboard"
set -as terminal-features "wezterm:clipboard"

Параметр set-clipboard имеет три значения 6:

  • on — tmux устанавливает буфер обмена и разрешает приложениям внутри tmux изменять его
  • external — tmux устанавливает буфер, но запрещает приложениям модификацию (по умолчанию с tmux 2.6+)
  • off — полностью отключено

Параметр allow-passthrough (tmux 3.3a+) критически важен для nested-сценариев: SSH → tmux → приложение 7.

Проверка корректности настройки:

tmux info | grep Ms:

Интеграция с Neovim

Neovim имеет встроенную поддержку OSC 52 и автоматически включает её при обнаружении переменной $SSH_TTY 8. Явная конфигурация в init.lua:

vim.g.clipboard = {
  name = 'OSC 52',
  copy = {
    ['+'] = require('vim.ui.clipboard.osc52').copy('+'),
    ['*'] = require('vim.ui.clipboard.osc52').copy('*'),
  },
  paste = {
    ['+'] = require('vim.ui.clipboard.osc52').paste('+'),
    ['*'] = require('vim.ui.clipboard.osc52').paste('*'),
  },
}

Для традиционного Vim существует плагин vim-osc52 9 или альтернативный подход — скрипт-обёртка (описанный выше), указанный как clipboard provider.

Интеграция с GNU Screen

GNU Screen требует оборачивания OSC 52 в DCS (Device Control String) последовательности 10:

  • Без screen: printf "\033]52;c;...\a"
  • Один уровень screen: оборачивание в \033P...\033\\
  • Вложенный screen: двойное экранирование с учётом $SHELL_LEVEL

Безопасность OSC 52

OSC 52 спроектирован как write-only по умолчанию — приложения могут записывать в буфер обмена, но не читать из него 5. Это предотвращает кражу содержимого clipboard вредоносными скриптами.

Однако при set-clipboard on в tmux любое приложение внутри сессии может модифицировать системный буфер обмена. Рекомендуется включать только при необходимости 5.

SSH Reverse Tunnel + netcat

Принцип работы

На локальной машине запускается слушающий процесс, который принимает данные по TCP и передаёт их в pbcopy. SSH reverse forwarding пробрасывает порт с удалённой машины на локальную 11.

Настройка

Локальная машина (macOS):

# Запустить демон-слушатель
while true; do nc -l 5556 | pbcopy; done

SSH подключение:

ssh -R 5556:localhost:5556 user@remote-server

Постоянная конфигурация (~/.ssh/config):

Host remote-server
    RemoteForward 5556 localhost:5556

На удалённой машине:

cat file.txt | nc -q0 localhost 5556

Автоматизация через LaunchAgent (macOS)

Для постоянной работы можно создать LaunchAgent 12:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.local.pbcopy</string>
    <key>ProgramArguments</key>
    <array>
        <string>sh</string>
        <string>-c</string>
        <string>while true; do nc -l 127.0.0.1 2224 | pbcopy; done</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
</dict>
</plist>

Скрипт-обёртка для прозрачного использования

#!/bin/bash
# ~/.bin/pbcopy — прозрачная обёртка
if [ -z "$SSH_CONNECTION" ]; then
    /usr/bin/pbcopy "$@"
else
    nc localhost 2224
fi

Оценка

  • Плюсы: минимальные зависимости, работает везде с netcat и SSH
  • Минусы: нет аутентификации на уровне туннеля, требует постоянный демон, однонаправленная работа (только копирование), каждая отправка данных закрывает соединение и требует перезапуска nc -l

Clipper — демон для буфера обмена

Описание

Clipper — демон/launch agent, предоставляющий доступ к локальному буферу обмена для tmux и vim через TCP или Unix socket 13.

Установка

# macOS
brew install clipper

# Из исходников
git clone https://github.com/wincent/clipper.git
cd clipper && make install

Конфигурация

Clipper слушает на порту 8377 по умолчанию и передаёт данные в pbcopy (macOS) или xclip (Linux).

SSH forwarding (TCP):

ssh -R localhost:8377:localhost:8377 user@host

SSH forwarding (Unix socket, OpenSSH 6.7+):

ssh -R /home/user/.clipper.sock:/Users/user/.clipper.sock host

Интеграция с tmux

# TCP
bind-key -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "nc localhost 8377"

# Unix socket
bind-key -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "nc -U ~/.clipper.sock"

Оценка

  • Плюсы: Unix socket безопаснее TCP, прозрачная интеграция с tmux и vim, поддерживается Homebrew
  • Минусы: требует настройки на обеих машинах, однонаправленная работа

Lemonade — кроссплатформенная утилита

Описание

Lemonade — утилита для удалённого копирования, вставки и открытия URL в браузере через TCP 14. Написана на Go, поддерживает Windows, Linux, macOS.

Установка

go install github.com/lemonade-command/lemonade@latest

Использование

Локальная машина (сервер):

lemonade server

Удалённая машина (клиент):

cat file.txt | lemonade copy
lemonade paste
lemonade open 'https://example.com'

Конфигурация (~/.config/lemonade.toml)

port = 2489
host = "localhost"
allow = ["192.168.0.0/16"]
line-ending = "lf"

Оценка

  • Плюсы: двусторонняя работа (copy + paste), кроссплатформенность, возможность открывать URL в браузере
  • Минусы: нет встроенного шифрования (рекомендуется SSH port forwarding), требует отдельный сервер-процесс

sshboard — безопасный вариант

Описание

sshboard использует SSH Unix domain socket forwarding для безопасного доступа к clipboard 15. Все данные передаются через зашифрованный SSH-туннель, сокеты приватны для конкретного пользователя.

Оценка

  • Плюсы: шифрование через SSH, защита от других пользователей на shared-серверах, кроссплатформенность (Linux/FreeBSD/Windows WSL/macOS)
  • Минусы: менее популярен, сложнее в настройке

X11 Forwarding с xclip/xsel

Принцип работы

SSH пробрасывает X11-протокол, позволяя удалённым приложениям взаимодействовать с локальным X-сервером, включая буфер обмена 16.

Настройка

Сервер (/etc/ssh/sshd_config):

X11Forwarding yes

Клиент:

ssh -X user@remote-server

На удалённой машине:

echo "текст" | xclip -selection clipboard
xclip -o -selection clipboard  # вставка

Безопасность X11 Forwarding

X11 forwarding создаёт значительные риски безопасности 17:

  • X11 cookie даёт полный контроль над X-сервером — удалённое приложение может перехватывать ввод с клавиатуры, читать содержимое экрана, управлять другими окнами
  • Компрометация удалённого сервера (включая root-доступ) позволяет получить X11-credentials и получить доступ к локальному дисплею
  • Флаг -X (untrusted) безопаснее -Y (trusted), но ограничивает функциональность

“X11 cookies grant complete control to anyone with access to them” 17.

Оценка

  • Плюсы: двусторонняя работа, стандартный механизм SSH
  • Минусы: серьёзные риски безопасности, требует X11 на обеих машинах, медленнее альтернатив, не работает на headless-серверах, на macOS требует XQuartz

Сравнительная таблица

ПодходДвунаправленныйШифрованиеСложность настройкиЗависимости на удалённой машинеБезопасность
OSC 52Нет (write-only)Через SSHМинимальнаяНет (только скрипт)Высокая
SSH Reverse TunnelНетНет (в рамках туннеля — да)НизкаяnetcatСредняя
ClipperНетДа (Unix socket)Средняяnetcat или socatВысокая
LemonadeДаНет (нужен SSH tunnel)Средняяlemonade binaryСредняя
sshboardДаДа (SSH socket)Высокаяsshboard binaryВысокая
X11 ForwardingДаДаСредняяxclip + X11 libsНизкая

Дискуссионные вопросы и противоречия

OSC 52 vs специализированные утилиты

OSC 52 не требует установки дополнительного ПО на удалённой машине, но ограничен объёмом передаваемых данных (~75 КБ) и зависит от поддержки терминалом. Специализированные утилиты (Clipper, Lemonade) снимают ограничение на размер, но требуют установки бинарников на обеих машинах.

Безопасность: OSC 52 vs X11 Forwarding

По security-модели OSC 52 значительно превосходит X11 Forwarding 5 17. OSC 52 ограничен записью в буфер обмена, тогда как X11 даёт полный доступ к дисплею. Тем не менее, OSC 52 при включённом set-clipboard on в tmux позволяет любому процессу в сессии модифицировать clipboard без уведомления пользователя.

Проблема paste (обратное направление)

Большинство подходов решают задачу копирования из удалённой машины в локальный буфер, но обратное направление (paste из локального буфера на удалённую машину) поддерживается только X11 Forwarding и Lemonade. В tmux отмечается асимметрия: текст, скопированный в Neovim внутри tmux, доступен локально, но внешне скопированный текст нельзя вставить в Neovim через clipboard provider 7.

Рекомендации

Оптимальный подход для macOS + SSH

OSC 52 — рекомендуемый подход для большинства сценариев:

  1. Не требует установки ПО на удалённом сервере
  2. Работает через любое количество прокси-слоёв (SSH → tmux → Neovim)
  3. Безопасен (write-only модель)
  4. Поддерживается основными терминалами macOS (iTerm2, Alacritty, kitty, WezTerm)

Минимальная настройка:

  1. Включить OSC 52 в терминале (iTerm2: Preferences → General → Selection → “Applications in terminal may access clipboard”)
  2. Создать скрипт ~/bin/pbcopy на удалённой машине (5 строк)
  3. Если используется tmux — добавить set -s set-clipboard on и set -g allow-passthrough on
  4. Neovim настроится автоматически через $SSH_TTY

Для объёмных данных (>75 КБ): SSH Reverse Tunnel или Clipper.

Quality Metrics

  • Источники найдены: 17
  • Источники процитированы: 17
  • Типы источников: official: 2, technical blog: 12, GitHub: 3
  • Покрытие цитатами: ~95%
  • Подвопросы исследованы: 5 (OSC 52, SSH tunnel, утилиты, tmux/vim, безопасность)