"xclip" против "xsel"

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

  • xclip
  • xsel

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

7 ответов

Решение

И то и другое 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 предлагает только вывод на стандартный вывод

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

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

Что-то еще иметь в виду, 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

Использование 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

Есть еще одна причина использовать 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);

xclipимеет эту специальную функцию для удаления последней пустой строки скопированного выбора, где xselнет этой опции.

человек

-rmlastnl remove the last newline charater if present

Для меня xclip позволит zsh shell exit очень медленно при использовании guake.

Как команда запуска: $ pwd | xclip -selection c. Тогда беги $ exit выйти из оболочки.

$ exit нужны секунды, чтобы выйти.

xsel хорошо в этой ситуации.

Другие вопросы по тегам