52

There are two command-line tools (in two different packages) to access the X clipboard:

  • xclip
  • xsel

I would love to know the difference between those two and hear a recommendation which one to use in which cases.

| improve this question | | | | |
32

Both xclip and xsel can store text into 3 different selections (by default it is primary selection). From experience I know that primary selection is basically what you high-light and released with the middle mouse click (which corresponds to pressing both right and left touchpad key on a laptop). The clipboard is the traditional CtrlV.

By examining the man pages for both, however, I've discovered that xclip wins in one aspect - reading from an input file:

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)

Of course you could use shell redirection with xsel to get around that

xieerqi:
$ xsel --clipboard < testfile.txt                                              

xieerqi:
$ HELLOWORLD
mksh: HELLOWORLD: not found

xclip also wins in the fact that you can output the contents of clipboard to file (which is perhaps useful when you want to redirect PRIMARY selection , i.e. highlights). xsel offers only output to stdout

| improve this answer | | | | |
  • 2
    So there's no difference except that xsel can only operate through STDIN/STDOUT, while xclip also can use real files there? How boring! Well, I made friends with xsel a while ago and can live with using shell redirections to files, so I'll keep using that. – Byte Commander Dec 4 '15 at 10:38
  • 2
    Unless I've missed something in the man pages or there are some hidden features, that's really all there is to these two programs :) Both are doing good enough job, so I guess it's more of a preference than anything – Sergiy Kolodyazhnyy Dec 4 '15 at 12:14
  • I installed xclip today and wondered if it was the right choice. Your answer confirmed it was because I'm creating file from clipboard to use with diff command. +1 Thanks :) – WinEunuuchs2Unix Mar 18 '17 at 17:20
  • 1
    I ran across a post has an excellent wrapper function for xclip that may tip the scale far in it's favor. madebynathan.com/2011/10/04/a-nicer-way-to-use-xclip – dragon788 Jun 16 '17 at 17:49
  • @dragon788 well, this is nice but question is about difference in usage of two commands, so I don't quite see how this is relevant – Sergiy Kolodyazhnyy Jun 16 '17 at 17:54
24

In addition to @Serg answer, there is a piece of information from the Tmux page in the Arch Wiki that can be useful in some specific cases:

unlike xsel it [xclip] works better on printing raw bitstream that doesn't fit the current locale. Nevertheless, it is neater to use xsel instead of xclip, because xclip does not close STDOUT after it has read from tmux's buffer. As such, tmux doesn't know that the copy task has completed, and continues to wait for xclip's termination, thereby rendering tmux unresponsive. A workaround is to redirect STDOUT of xclip to /dev/null

| improve this answer | | | | |
  • 1
    This not closing STDOUT issue with xclip is a major problem if you encounter it. I wasted 2 hours debugging it. I finally switched to xsel -bi and xsel -bo. – Bruno Bronosky Sep 18 '19 at 6:56
16

Something else to keep in mind, xsel has fewer dependencies than 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
| improve this answer | | | | |
  • 2
    I suspect most installations already have libxmu6 though, many packages such as xterm, x11-apps, and x11-utils depend on it. – JoshB Aug 5 '16 at 7:32
7

Use xclip, because xsel can not extract binary data from clipboard, such as screenshots. For example, save screenshot to clipboard:

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

Then save to file and compare output:

$ 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
| improve this answer | | | | |
  • 1
    I find that xclip isn't necessarily always able to handle binary data either, e.g. when using the "Copy to clipboard" button from gnome-screenshot I get no output at all. When copying an image with Ctrl+C from e.g. a LibreOffice Document, it only works if I manually specify the target type like xclip -o -t image/png -selection clipboard. – Byte Commander Sep 26 '18 at 20:28
  • 2
    I don't get output from gnome-screenshot at all, but that's another issue - gitlab.gnome.org/GNOME/gnome-screenshot/issues/14 – anatoly techtonik Sep 28 '18 at 9:32
0

There is one other reason to use xclip over xsel – xclip can manipulate cut buffer 0, by passing -selection buffer-cut, which xsel cannot do.

It's relatively easy to allow it to manipulate the other cut buffers as well; here is my patch, though it's not well-tested and comes with no guarantees.

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

| improve this answer | | | | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.