Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

xcopy

Запускает произвольную команду, и, только если она завершилась успешно, копирует её stdout в системный буфер обмена — на macOS, Linux (X11 и Wayland) и Windows.

$ xcopy git rev-parse HEAD
Successfully copied to the clipboard!
$ pbpaste          # macOS
a1b2c3d4e5f6...

Зачем

Стандартный паттерн command | pbcopy копирует в буфер обмена всё, что успел вывести процесс, даже если он упал с ошибкой на середине — в буфере остаётся оборванный/мусорный результат. xcopy сначала полностью считывает вывод команды в собственный буфер, проверяет код завершения, и только при успехе (exit code == 0) передаёт накопленные данные в буфер обмена. Если команда завершилась с ошибкой — буфер обмена не трогается вообще.

Установка

Зависимости для сборки: компилятор с поддержкой C99 и POSIX (popen, system, sys/wait.h).

cc -std=c99 -O2 -o xcopy xcopy.c
sudo install -m 755 xcopy /usr/local/bin/xcopy

Утилита буфера обмена

xcopy сам ничего не реализует для доступа к буферу обмена — он вызывает внешнюю системную утилиту. Какая именно утилита доступна — определяется на этапе компиляции через препроцессор (#if defined(__APPLE__), #elif defined(__linux__), #elif defined(__CYGWIN__) || defined(_WIN32)), то есть бинарник, собранный под Linux, никогда даже не будет содержать код для pbcopy, и наоборот.

Для Linux заранее нельзя определить компиляцией, что стоит в системе — X11, Wayland или ничего, поэтому там подключается список кандидатов, и на этапе выполнения используется первый найденный в $PATH:

ОС Утилита(ы) Нужно установить отдельно
macOS pbcopy нет, есть из коробки
Linux (Wayland) wl-copy пакет wl-clipboard
Linux (X11) xclip → иначе xsel xclip или xsel
Windows (Cygwin/MSYS) clip нет, есть из коробки

Если на Linux не установлена ни одна из подходящих утилит, xcopy завершится с понятной ошибкой и подскажет, что именно попробовал:

$ xcopy echo hi
Error: no clipboard utility found on this Linux system.
Tried: wl-copy, xclip, xsel

Попытка собрать xcopy на платформе, для которой в коде вообще нет секции препроцессора (не macOS/Linux/Windows), закончится ошибкой компиляции (#error), а не тихим падением в рантайме.

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

xcopy <команда> [аргументы...]

Все аргументы после xcopy склеиваются в одну строку через пробел и выполняются как есть через sh -c, точно так же, как если бы вы написали их в шелле напрямую. Это значит, что пайпы, редиректы и кавычки внутри команды работают привычным образом — но и требуют той же осторожности, что и обычный sh -c (см. «Безопасность» ниже).

Примеры

Скопировать текущий git-хэш:

xcopy git rev-parse HEAD

Скопировать содержимое файла:

xcopy cat notes.txt

Скопировать результат сложного пайплайна (нужны кавычки, так как | и && иначе разберёт по частям сам ваш внешний шелл, а не xcopy):

xcopy "ps aux | grep nginx"

Скопировать вывод команды вместе со stderr (git, например, часть сообщений всегда пишет в stderr, а не в stdout):

xcopy "git pull 2>&1"

Как это работает

  1. Аргументы склеиваются в одну командную строку и запускаются через popen(cmd, "r").
  2. Весь stdout команды построчно читается в динамически растущий буфер в памяти (без ограничения на размер вывода).
  3. pclose() возвращает код завершения команды. Если код не нулевой или процесс был завершён сигналом — программа печатает диагностику в stderr и не трогает буфер обмена.
  4. Только если команда завершилась успешно, определяется доступная в системе утилита буфера обмена (см. таблицу выше), и накопленный буфер целиком (fwrite по точной длине, а не по strlen, поэтому бинарные данные с нулевыми байтами не обрезаются) передаётся ей на вход.

Коды завершения

Код Значение
0 Команда выполнена успешно, вывод скопирован в буфер
1 Неверные аргументы, ошибка запуска команды, сама команда завершилась с ненулевым кодом/по сигналу, отсутствует подходящая утилита буфера обмена, либо ошибка копирования

Диагностика во всех случаях ошибки печатается в stderr, а не в stdout, поэтому вывод самой оборачиваемой команды остаётся «чистым» для дальнейшего использования в пайпах.

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

Команда выполняется через sh -c, как и в любом инструменте на базе popen/system. Не передавайте в xcopy непроверенный пользовательский ввод в качестве аргументов — как и с обычным шеллом, туда можно подставить ;, `, $(...) и получить выполнение произвольного кода.

Лицензия

LICENSE

About

A utility for posix systems to copy the command output stream.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages