'xclip' vs. 'xsel'

43

Hay dos herramientas de línea de comandos (en dos paquetes diferentes) para acceder al portapapeles X:

  • xclip
  • xsel

Me encantaría saber la diferencia entre esos dos y escuchar una recomendación sobre cuál usar en cada caso.

Byte Commander
fuente
1
Exactamente lo que quería saber hoy :) +1
WinEunuuchs2Unix

Respuestas:

26

Ambos xclipy xselpueden almacenar texto en 3 selecciones diferentes (por defecto es la selección primaria). Por experiencia, sé que la selección primaria es básicamente lo que resaltas y liberas con el clic central del mouse (que corresponde a presionar la tecla táctil derecha e izquierda en una computadora portátil). El portapapeles es el tradicional CtrlV.

Al examinar las manpáginas para ambos, sin embargo, descubrí que xclipgana en un aspecto: leer de un archivo de entrada:

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)

Por supuesto, podría usar la redirección de shell xselpara evitar eso

xieerqi:
$ xsel --clipboard < testfile.txt                                              

xieerqi:
$ HELLOWORLD
mksh: HELLOWORLD: not found

xcliptambién gana en el hecho de que puede enviar el contenido del portapapeles a un archivo (lo que quizás sea útil cuando desea redirigir la selección PRIMARIA, es decir, los resaltados). xselofrece solo salida a stdout

Sergiy Kolodyazhnyy
fuente
2
Entonces, ¿no hay diferencia excepto que xselsolo puede operar a través de STDIN / STDOUT, mientras que xcliptambién puede usar archivos reales allí? ¡Qué aburrido! Bueno, me hice amigo hace xselun tiempo y puedo vivir usando redirecciones de shell a archivos, así que seguiré usando eso.
Byte Commander
2
A menos que me haya perdido algo en las páginas del manual o haya algunas características ocultas, eso es todo lo que hay en estos dos programas :) Ambos están haciendo un trabajo lo suficientemente bueno, así que supongo que es más una preferencia que otra cosa
Sergiy Kolodyazhnyy
Lo instalé xcliphoy y me preguntaba si era la elección correcta. Su respuesta confirmó que fue porque estoy creando un archivo desde el portapapeles para usar con el diffcomando. +1 Gracias :)
WinEunuuchs2Unix
1
Me encontré con una publicación que tiene una excelente función de envoltura para xclip que puede inclinar la escala a su favor. madebynathan.com/2011/10/04/a-nicer-way-to-use-xclip
dragon788
@ dragon788 bueno, esto es bueno, pero la pregunta es sobre la diferencia en el uso de dos comandos, por lo que no entiendo cómo esto es relevante
Sergiy Kolodyazhnyy
22

Además de la respuesta @Serg , hay una información de la página de Tmux en Arch Wiki que puede ser útil en algunos casos específicos :

a diferencia de xsel, [xclip] funciona mejor en la impresión de flujo de bits sin formato que no se ajusta a la configuración regional actual. Sin embargo, es mejor usar xsel en lugar de xclip, porque xclip no cierra STDOUT después de leer del búfer de tmux. Como tal, tmux no sabe que la tarea de copia se ha completado y continúa esperando la finalización de xclip, lo que hace que tmux no responda. Una solución alternativa es redirigir STDOUT de xclip a / dev / null

PlasmaBinturong
fuente
Este STDOUT no cerrar problema con xclipes un problema importante si se encuentra con ella. Perdí 2 horas depurándolo. Finalmente cambié a xsel -biy xsel -bo.
Bruno Bronosky
15

Algo más a tener en cuenta, xseltiene menos dependencias que 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
fuente
2
Sin embargo, sospecho que la mayoría de las instalaciones ya tienen libxmu6, muchos paquetes como xterm, x11-apps y x11-utils dependen de ello.
JoshB
6

Uso xclip, porque xselno puede extraer datos binarios del portapapeles, como screenhost. Por ejemplo, guardar captura de pantalla en el portapapeles:

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

Luego guarde en el archivo y compare la salida:

$ 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
fuente
1
Creo que xcliptampoco siempre es capaz de manejar datos binarios, por ejemplo, cuando uso el botón "Copiar al portapapeles" de gnome-screenshot no obtengo ningún resultado. Al copiar una imagen con Ctrl + C desde, por ejemplo, un documento de LibreOffice, solo funciona si especifico manualmente el tipo de destino xclip -o -t image/png -selection clipboard.
Byte Commander
2
No obtengo ningún resultado gnome-screenshot, pero ese es otro problema: gitlab.gnome.org/GNOME/gnome-screenshot/issues/14
anatoly techtonik
0

Hay otra razón para usar xclip sobre xsel: xclip puede manipular el buffer de corte 0, pasando -selection buffer-cut, lo que xsel no puede hacer.

Es relativamente fácil permitirle manipular también los otros tampones de corte; Aquí está mi parche, aunque no está bien probado y viene sin garantías.

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
fuente