'xclip' vs. 'xsel'

43

Existem duas ferramentas de linha de comando (em dois pacotes diferentes) para acessar a área de transferência do X:

  • xclip
  • xsel

Eu adoraria saber a diferença entre os dois e ouvir uma recomendação de qual usar em quais casos.

Byte Commander
fonte
1
Exatamente o que eu queria saber hoje :) +1
WinEunuuchs2Unix 18/17

Respostas:

26

Ambos xclipe xselpodem armazenar texto em três seleções diferentes (por padrão, é a seleção principal). Por experiência, eu sei que a seleção primária é basicamente o que você destaca e liberou com o clique do meio do mouse (o que corresponde a pressionar as teclas direita e esquerda do touchpad em um laptop). A área de transferência é a tradicional CtrlV.

Examinando as manpáginas de ambos, no entanto, descobri que xclipganha em um aspecto - lendo um arquivo 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)

Claro que você pode usar o redirecionamento de shell xselpara contornar esse problema

xieerqi:
$ xsel --clipboard < testfile.txt                                              

xieerqi:
$ HELLOWORLD
mksh: HELLOWORLD: not found

xcliptambém ganha no fato de que você pode enviar o conteúdo da área de transferência para arquivo (o que talvez seja útil quando você deseja redirecionar a seleção PRIMARY, ou seja, destaques). xseloferece apenas saída para stdout

Sergiy Kolodyazhnyy
fonte
2
Portanto, não há diferença, exceto que xselsó pode operar através do STDIN / STDOUT, enquanto xcliptambém pode usar arquivos reais lá? Que aborrecido! Bem, fiz amizade xselhá um tempo e posso usar redirecionamentos de shell para arquivos, então continuarei usando isso.
Byte Commander
2
A menos que eu tenha perdido algo nas páginas do manual ou que haja alguns recursos ocultos, isso é tudo o que há nesses dois programas :) Ambos estão fazendo um trabalho bom o suficiente, então eu acho que é mais uma preferência do que qualquer coisa
Sergiy Kolodyazhnyy
Instalei xcliphoje e me perguntei se era a escolha certa. Sua resposta confirmou que eu estava criando um arquivo da área de transferência para usar com o diffcomando 1 Obrigado :)
WinEunuuchs2Unix 18/17
1
Corri através de um post tem uma excelente função de wrapper para xclip que pode inclinar a escala muito a favor. madebynathan.com/2011/10/04/a-nicer-way-to-use-xclip
dragon788
@ dragon788 bem, isso é bom, mas pergunta é sobre diferença no uso de dois comandos, então eu não vejo como isso é relevante
Sergiy Kolodyazhnyy
22

Além da resposta do @Serg , há uma parte da informação da página do Tmux no Arch Wiki que pode ser útil em alguns casos específicos :

ao contrário do xsel, o [xclip] funciona melhor na impressão de fluxo de bits bruto que não se encaixa no local atual. No entanto, é melhor usar o xsel em vez do xclip, porque o xclip não fecha o STDOUT depois de ler o buffer do tmux. Como tal, o tmux não sabe que a tarefa de cópia foi concluída e continua aguardando o término do xclip, tornando o tmux sem resposta. Uma solução alternativa é redirecionar o STDOUT do xclip para / dev / null

PlasmaBinturong
fonte
Isso não encerra o problema STDOUT com xclipé um grande problema se você o encontrar. Eu perdi duas horas depurando-o. Eu finalmente mudei para xsel -bie xsel -bo.
Bruno Bronosky 18/09
15

Outra coisa a ter em mente, xseltem menos dependências do 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
fonte
2
Eu suspeito que a maioria das instalações já possui libxmu6, mas muitos pacotes, como xterm, x11-apps e x11-utils, dependem disso.
joshb
6

Use xclip, porque xselnão é possível extrair dados binários da área de transferência, como screenshost. Por exemplo, salve a captura de tela na área de transferência:

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

Em seguida, salve no arquivo e compare a saída:

$ 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
fonte
1
Acho que xclipnem sempre é capaz de lidar com dados binários, por exemplo, ao usar o botão "Copiar para a área de transferência" do gnome-screenshot, não recebo nenhuma saída. Ao copiar uma imagem com Ctrl + C de, por exemplo, um Documento do LibreOffice, ela só funciona se eu especificar manualmente o tipo de destino como xclip -o -t image/png -selection clipboard.
Byte Commander
2
Eu não entendo saída gnome-screenshotem tudo, mas isso é outra questão - gitlab.gnome.org/GNOME/gnome-screenshot/issues/14
techtonik anatoly
0

Há um outro motivo para usar o xclip sobre o xsel - o xclip pode manipular o buffer de corte 0 passando -selection buffer-cut, o que o xsel não pode fazer.

É relativamente fácil permitir que ele manipule os outros tampões de corte também; aqui está o meu patch, apesar de não ter sido bem testado e não ter garantias.

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
fonte