„xclip” vs. „xsel”

43

Istnieją dwa narzędzia wiersza polecenia (w dwóch różnych pakietach), aby uzyskać dostęp do schowka X:

  • xclip
  • xsel

Bardzo chciałbym poznać różnicę między tymi dwoma i usłyszeć zalecenie, które z nich zastosować w jakich przypadkach.

Bajt Dowódca
źródło
1
Dokładnie to, co chciałem dzisiaj wiedzieć :) +1
WinEunuuchs2Unix

Odpowiedzi:

26

Zarówno xclipi xselmożna przechowywać tekst w 3 różne pozycje (domyślnie jest to wybór podstawowy). Z doświadczenia wiem, że wybór podstawowy jest zasadniczo tym, co wyróżniasz i zwalniasz środkowym kliknięciem myszy (co odpowiada naciśnięciu prawego i lewego klawisza touchpada na laptopie). Schowek jest tradycyjny CtrlV.

Jednak po przejrzeniu manstron dla obu odkryłem, że xclipwygrywa w jednym aspekcie - czytanie z pliku wejściowego:

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)

Oczywiście możesz użyć przekierowania powłoki za pomocą, xselaby obejść ten problem

xieerqi:
$ xsel --clipboard < testfile.txt                                              

xieerqi:
$ HELLOWORLD
mksh: HELLOWORLD: not found

xclipwygrywa również w tym, że możesz wyprowadzać zawartość schowka do pliku (co może być przydatne, gdy chcesz przekierować PODSTAWOWY wybór, czyli podświetlenia). xseloferuje tylko wyjście na standardowe wyjście

Sergiy Kolodyazhnyy
źródło
2
Więc nie ma różnicy poza tym, że xselmoże działać tylko poprzez STDIN / STDOUT, a xclipjednocześnie może używać tam prawdziwych plików? Jak nudne! Cóż, zaprzyjaźniłem się już xseljakiś czas temu i mogę żyć z wykorzystaniem przekierowań powłoki do plików, więc będę nadal z tego korzystać.
Bajt Dowódca
2
Chyba że coś przeoczyłem na stronach podręcznika lub są jakieś ukryte funkcje, to naprawdę wszystko, co jest z tymi dwoma programami :) Oba wykonują wystarczająco dobrą robotę, więc myślę, że to bardziej preferencja niż cokolwiek innego
Sergiy Kolodyazhnyy
Zainstalowałem xclipdzisiaj i zastanawiałem się, czy to był właściwy wybór. Twoja odpowiedź potwierdziła, że ​​to dlatego, że tworzę plik ze schowka do użycia z diffpoleceniem. +1 dzięki :)
WinEunuuchs2Unix
1
Natknąłem się na post ma doskonałą funkcję otoki dla xclip, która może przechylić skalę na swoją korzyść. madebynathan.com/2011/10/04/a-nicer-way-to-use-xclip
dragon788 16.06.17
@ dragon788 cóż, to jest miłe, ale pytanie dotyczy różnicy w użyciu dwóch poleceń, więc nie bardzo rozumiem, jak to jest istotne
Sergiy Kolodyazhnyy
22

Oprócz odpowiedzi @Serg na stronie Arch Wiki znajduje się informacja ze strony Tmux, która może być przydatna w niektórych szczególnych przypadkach :

w przeciwieństwie do xsel it [xclip] działa lepiej na drukowaniu surowego strumienia bitów, który nie pasuje do bieżących ustawień regionalnych. Niemniej jednak rozsądniej jest używać xsel zamiast xclip, ponieważ xclip nie zamyka STDOUT po odczytaniu z bufora tmux. Jako taki, tmux nie wie, że zadanie kopiowania zostało zakończone, i nadal czeka na zakończenie xclipa, co powoduje, że tmux nie odpowiada. Obejściem tego problemu jest przekierowanie STDOUT xclipa do / dev / null

Plazma Binturong
źródło
Ten problem z nie zamykaniem STDOUTxclip jest poważnym problemem, jeśli go napotkasz. Zmarnowałem 2 godziny na debugowanie. W końcu przełączyłem się na xsel -bii xsel -bo.
Bruno Bronosky
15

O czym należy pamiętać, xselma mniej zależności niż 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
Martin K.
źródło
2
Podejrzewam, że większość instalacji ma już libxmu6, wiele pakietów takich jak xterm, x11-apps i x11-utils zależy od tego.
JoshB,
6

Użyj xclip, ponieważ xselnie można wyodrębnić danych binarnych ze schowka, np. Screenhosthost. Na przykład zapisz zrzut ekranu do schowka:

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

Następnie zapisz do pliku i porównaj dane wyjściowe:

$ 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
anatoly techtonik
źródło
1
Uważam, że xclipniekoniecznie zawsze jest w stanie obsłużyć dane binarne, np. Gdy używam przycisku „Kopiuj do schowka” z ekranu gnome-screenshot, w ogóle nie otrzymuję danych wyjściowych. Podczas kopiowania obrazu za pomocą Ctrl + C np. Z dokumentu LibreOffice działa to tylko wtedy, gdy ręcznie określę typ docelowy, taki jak xclip -o -t image/png -selection clipboard.
Bajt Dowódca
2
W ogóle nie otrzymuję danych wyjściowych gnome-screenshot, ale to kolejny problem - gitlab.gnome.org/GNOME/gnome-screenshot/issues/14
anatoly techtonik
0

Jest jeszcze jeden powód, aby używać xclipa nad xsel - xclip może manipulować buforem cięcia 0, przekazując -selection buffer-cut, czego Xsel nie może zrobić.

Stosunkowo łatwo jest pozwolić mu również manipulować innymi buforami cięcia; oto moja łatka, choć nie jest dobrze przetestowana i nie ma żadnych gwarancji.

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);

Josh
źródło