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.
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.
Respuestas:
Ambos xclip
y xsel
pueden 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 man
páginas para ambos, sin embargo, descubrí que xclip
gana 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 xsel
para evitar eso
xieerqi:
$ xsel --clipboard < testfile.txt
xieerqi:
$ HELLOWORLD
mksh: HELLOWORLD: not found
xclip
tambié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). xsel
ofrece solo salida a stdout
xsel
solo puede operar a través de STDIN / STDOUT, mientras que xclip
también puede usar archivos reales allí? ¡Qué aburrido! Bueno, me hice amigo hace xsel
un tiempo y puedo vivir usando redirecciones de shell a archivos, así que seguiré usando eso.
xclip
hoy 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 diff
comando. +1 Gracias :)
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
xclip
es un problema importante si se encuentra con ella. Perdí 2 horas depurándolo. Finalmente cambié a xsel -bi
y xsel -bo
.
Algo más a tener en cuenta, xsel
tiene 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
Uso xclip
, porque xsel
no 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
xclip
tampoco 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
.
gnome-screenshot
, pero ese es otro problema: gitlab.gnome.org/GNOME/gnome-screenshot/issues/14
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);