«xclip» против «xsel»


43

Существует два инструмента командной строки (в двух разных пакетах) для доступа к буферу обмена X:

  • xclip
  • xsel

Я хотел бы знать разницу между этими двумя и услышать рекомендацию, какую использовать в каких случаях.


1
Именно то, что я хотел знать сегодня :) +1
WinEunuuchs2Unix

Ответы:


26

Оба xclipи xselмогут хранить текст в 3 разных выделениях (по умолчанию это первичное выделение). По своему опыту я знаю, что основной выбор - это то, что вы выделяете и отпускаете средним щелчком мыши (что соответствует нажатию правой и левой клавиш сенсорной панели на ноутбуке). Буфер обмена является традиционным CtrlV.

Однако, изучив manстраницы для обоих, я обнаружил, что xclipвыигрывает в одном аспекте - чтение из входного файла:

xieerqi:
$ cat testfile.txt                                                             
HELLOWORLD

xieerqi:
$ xclip -selection clipboard testfile.txt

xieerqi:
$ HELLOWORLD
mksh: HELLOWORLD: not found

xieerqi:
$ xsel testfile.txt 
Usage: xsel [options]
Manipulate the X sele . . . (usage page goes on)

Конечно, вы можете использовать перенаправление оболочки, xselчтобы обойти это

xieerqi:
$ xsel --clipboard < testfile.txt                                              

xieerqi:
$ HELLOWORLD
mksh: HELLOWORLD: not found

xclipтакже выигрывает в том, что вы можете выводить содержимое буфера обмена в файл (что, возможно, полезно, если вы хотите перенаправить выбор PRIMARY, то есть выделение). xselпредлагает только вывод на стандартный вывод


2
Так что нет никакой разницы, за исключением того, что xselможно работать только через STDIN / STDOUT, а xclipтакже использовать там реальные файлы? Как скучно! Ну, я xselнедавно подружился и могу использовать перенаправление оболочки на файлы, так что я буду продолжать это использовать.
Byte Commander

2
Если я не пропустил что-то на страницах руководства или какие-то скрытые функции, это действительно все, что есть в этих двух программах :) Обе хорошо справляются с работой, так что, я думаю, это больше предпочтение, чем что-либо
Сергей Колодяжный

Я установил xclipсегодня и задавался вопросом, был ли это правильный выбор. Ваш ответ подтвердил, что это потому, что я создаю файл из буфера обмена для использования с diffкомандой. +1 Спасибо :)
WinEunuuchs2Unix

1
Я наткнулся на сообщение, в котором есть отличная функция-обертка для xclip, которая может значительно повлиять на масштаб. madebynathan.com/2011/10/04/a-nicer-way-to-use-xclip
dragon788

@ dragon788 ну, это хорошо, но вопрос касается разницы в использовании двух команд, поэтому я не совсем понимаю, насколько это актуально
Сергей Колодяжный,

22

В дополнение к ответу @Serg , есть часть информации со страницы Tmux в Arch Wiki, которая может быть полезна в некоторых конкретных случаях :

в отличие от xsel, он [xclip] лучше работает при печати необработанных битовых потоков, которые не соответствуют текущей локали. Тем не менее, лучше использовать xsel вместо xclip, поскольку xclip не закрывает STDOUT после чтения из буфера tmux. Таким образом, tmux не знает, что задание копирования выполнено, и продолжает ждать завершения xclip, что делает tmux безразличным. Обходной путь - перенаправить STDOUT xclip в / dev / null.


Это не закрытие проблемы STDOUTxclip является серьезной проблемой, если вы столкнетесь с ней. Я потратил 2 часа на его отладку. Я наконец перешел на xsel -biи xsel -bo.
Бруно Броноски

15

Что-то еще нужно иметь в виду, xselимеет меньше зависимостей, чем xclip:

# apt-cache depends xsel
xsel
  Depends: libc6
  Depends: libx11-6
  Conflicts: xsel:i386

# apt-cache depends xclip
xclip
  Depends: libc6
  Depends: libx11-6
  Depends: libxmu6
  Conflicts: xclip:i386

2
Я подозреваю, что большинство установок уже имеют libxmu6, хотя многие пакеты, такие как xterm, x11-apps и x11-utils, зависят от него.
JoshB

6

Используйте xclip, потому что xselне может извлечь двоичные данные из буфера обмена, например, снимок экрана. Например, сохранить скриншот в буфер обмена:

$ maim -s | xclip -selection clipboard -t image/png

Затем сохраните в файл и сравните вывод:

$ xclip -o -selection clipboard > 1xclip
$ xsel -o --clipboard > 1xsel
$ ls -go 1*
-rw-rw-r-- 1 11948 Sep 26 20:13 1xclip
-rw-rw-r-- 1     0 Sep 26 20:13 1xsel

1
Я обнаружил, что xclipне всегда можно обрабатывать двоичные данные, например, при использовании кнопки «Копировать в буфер» из gnome-screenshot я ничего не получаю. При копировании изображения с помощью Ctrl + C, например, из документа LibreOffice, оно работает только в том случае, если я вручную указываю целевой тип, например xclip -o -t image/png -selection clipboard.
Byte Commander

2
Я не получаю вывод gnome-screenshotвообще, но это другая проблема - gitlab.gnome.org/GNOME/gnome-screenshot/issues/14
Анатолий techtonik

0

Есть еще одна причина использовать xclip поверх xsel - xclip может манипулировать буфером обрезки 0, передавая -selection buffer-cut, чего не может сделать xsel.

Относительно легко позволить ему манипулировать и другими буферами вырезания; Вот мой патч, хотя он не проверен и не дает никаких гарантий.

diff --git a/xclip.c b/xclip.c
index 5fc760cb7..eeb05f662 100644
--- a/xclip.c
+++ b/xclip.c
@@ -35,11 +35,12 @@
 #include "xclib.h"

 /* command line option table for XrmParseCommand() */
-XrmOptionDescRec opt_tab[14];
+XrmOptionDescRec opt_tab[15];

 /* Options that get set on the command line */
 int sloop = 0;         /* number of loops */
 char *sdisp = NULL;        /* X display to connect to */
+int bufnum = 0;        /* Cut buffer number to use */
 Atom sseln = XA_PRIMARY;   /* X selection to work with */
 Atom target = XA_STRING;

@@ -165,6 +166,9 @@ doOptSel(void)
        break;
    case 'b':
        sseln = XA_STRING;
+       if (XrmGetResource(opt_db, "xclip.buffer", "Xclip.Buffer", &rec_typ, &rec_val)) {
+           bufnum = atoi(&rec_val.addr[0]);
+       }
        break;
    }

@@ -177,8 +181,10 @@ doOptSel(void)
        fprintf(stderr, "XA_SECONDARY");
        if (sseln == XA_CLIPBOARD(dpy))
        fprintf(stderr, "XA_CLIPBOARD");
-       if (sseln == XA_STRING)
+       if (sseln == XA_STRING) {
        fprintf(stderr, "XA_STRING");
+       fprintf(stderr, "\nUsing buffer number %d", bufnum);
+       }

        fprintf(stderr, "\n");
    }
@@ -276,7 +282,7 @@ doIn(Window win, const char *progname)

     /* Handle cut buffer if needed */
     if (sseln == XA_STRING) {
-   XStoreBuffer(dpy, (char *) sel_buf, (int) sel_len, 0);
+   XStoreBuffer(dpy, (char *) sel_buf, (int) sel_len, bufnum);
    return EXIT_SUCCESS;
     }

@@ -445,7 +451,7 @@ doOut(Window win)
     unsigned int context = XCLIB_XCOUT_NONE;

     if (sseln == XA_STRING)
-   sel_buf = (unsigned char *) XFetchBuffer(dpy, (int *) &sel_len, 0);
+   sel_buf = (unsigned char *) XFetchBuffer(dpy, (int *) &sel_len, bufnum);
     else {
    while (1) {
        /* only get an event if xcout() is doing something */
@@ -595,6 +601,11 @@ main(int argc, char *argv[])
     opt_tab[13].argKind = XrmoptionNoArg;
     opt_tab[13].value = (XPointer) xcstrdup(ST);

+    opt_tab[14].option = xcstrdup("-buffer");
+    opt_tab[14].specifier = xcstrdup(".buffer");
+    opt_tab[14].argKind = XrmoptionSepArg;
+    opt_tab[14].value = (XPointer) NULL;
+
     /* parse command line options */
     doOptMain(argc, argv);

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.