'xclip' vs. '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пропонує лише вихід на stdout


2
Тож немає різниці, окрім того, що вони xselможуть працювати лише через STDIN / STDOUT, а xclipтакож там можна використовувати реальні файли? Як нудно! Ну, я подружився xselдеякий час тому і можу жити, використовуючи перенаправлення оболонок до файлів, тому я буду продовжувати це використовувати.
Байт-командир

2
Якщо я не пропустив щось на сторінках man або є якісь приховані функції, це справді все, що є для цих двох програм :) Обидва роблять достатньо хорошу роботу, тому, мабуть, це більше вподобання, ніж усе
Сергій Колодяжний

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

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

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

22

Окрім відповіді @Serg , на Arch Arch Wiki є інформація про сторінку Tmux , яка може бути корисною в деяких конкретних випадках :

на відміну від 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-додатки та x11-утиліти, залежать від цього.
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 я не отримую жодного результату. При копіюванні зображення за допомогою Ctrl + C з, наприклад, LibreOffice Document, воно працює лише в тому випадку, якщо я вручну вказую цільовий тип типу xclip -o -t image/png -selection clipboard.
Байт-командир

2
Я взагалі не отримую результатів gnome-screenshot, але це інше питання - gitlab.gnome.org/GNOME/gnome-screenshot/isissue/14
anatoly techtonik

0

Є ще одна причина використання xclip over 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.