Clipboard Access from the Command Line with xsel/xclip

If you’ve ever found yourself wanting to copy the entire contents of a text file to the clipboard, you may end up doing something like the following:

  1. Open the file in a text editor.
  2. Select all text.
  3. Copy to clipboard.

It can be a blow to your productivity to stop what you’re doing and do the above, especially if you were working at the command line. Another disadvantage to doing it this way is that, if you close the program from which you copied the text, it clears the clipboard. If you forget this (or you simply didn’t know about this little quirk), then you may end up wasting more time repeating those steps to get that text into your clipboard.

xsel and xclip are two commands that allow you to interact with the X clipboards. Before I explain how to use them though, a short overview of the X clipboards is in order.

X11 has not one, not two, but three clipboards. They are called:

  • PRIMARY – Also known as the “primary selection” or the “primary clipboard”. This clipboard is populated whenever you highlight text with the mouse. If you’ve ever highlighted text and noticed that you can paste it by clicking the middle button on your mouse, this is the clipboard being used.
  • SECONDARY – This clipboard is very rarely used anymore, but exists to provide a “secondary selection” clipboard to accompany the primary selection.
  • CLIPBOARD – This is the clipboard you are likely most familiar with. It is the one used when you copy text from an application such as a web browser, or a GUI text editor like gedit.

For our demonstration, we’ll use the CLIPBOARD selection as it is the clipboard you’re most likely to be using on a regular basis. To begin, let’s create a file we can use to test:

You can verify the file has been created using the cat command to print it to standard output.

So, say that we’d like to get the contents of foo.txt to the clipboard. With xsel, you can do it like so:

The -i option tells xsel to read from standard input. In this case, standard input is being piped in from the cat command. The b option tells xsel to use the CLIPBOARD selection. To use the PRIMARY selection, you’d replace the b with p, and to use SECONDARY you’d replace it with s.

To copy the contents of the text file to the clipboard using xclip, you can use the following:

To use the PRIMARY selection, you’d replace clipboard with primary, and to use SECONDARY you’d replace it with secondary.

If you press Ctrl-V in another application, you’ll notice that the words “Hello world” were pasted.

In addition to copying standard input to the clipboards, xsel and xclip both have the ability to print the contents of the clipboards to standard output. Go ahead and select some text with your mouse and copy it to the clipboard using Ctrl-C, then try the commands below. (I will copy a few words from the previous sentence as an example.)

In both cases, -o is used to tell the command to print the contents of the specified clipboard to standard output.

The arguments to xclip can be abbreviated, so you don’t have to type -selection clipboard every time you want to use it. For example:

Both commands have additional features not described here, so check their man pages for more ideas.

Hopefully these commands can help you save time and increase your productivity when working from the command line. They’ve certainly done so for me.

The Reliability of X.Org

X11

Wednesday’s XKCD was funny as usual, but there was also quite a bit of truth to it. Since X.Org was forked from XFree86 several years back, I can count on one hand the number of times I have had to edit my X11 configuration, and most (if not all) of them have involved AMD/ATI’s Catalyst driver. This is a far cry from my early days experimenting with Slackware 7, when I knew little about Linux and even less about X11. Were it not for the helpfulness of more experienced Linux users on message boards and mailing lists (not to mention my stubbornness and natural curiosity), I may well have given up on learning Linux. In fact, aside from when I used to use the Catalyst driver, I haven’t even had an xorg.conf in the last several years. Gone are the days when I had to manually configure my display modes, enter the right parameters to enable mouse wheel scrolling, etc. I have been so spoiled by X.Org that, until I saw this comic on Wednesday, I had forgotten just how cumbersome X11 once was.

This is not to say that X.Org is all sunshine and roses. Features like multiple monitors and two-finger scrolling for trackpads don’t always work well, even with desktop environments stepping up in the last couple years to make configuration easier.

All in all though, when compared to the state of X11 about 10 years ago, X.Org has proven to be a fantastic implementation that has given Linux users little to complain about.

Printing to PDF in Mutt

When using my netbook, I don’t typically have a printer available. My printer is connected to my wife’s desktop computer which doesn’t stay on all the time, so I can’t rely on sharing the printer to the network and sending documents to it through her computer. Moreover, I’m not all that fond of printing things when saving as a PDF will do.

My email client of choice is Mutt. By default, Mutt uses the lpr command to print, which sends the message to the default printer. But I don’t want to actually print the message, I’d like a PDF instead. Luckily for me, as with pretty much anything in Mutt, it is possible to change the default behavior and supply a different command to print messages. Below you can see a short shell script I wrote which will create a PDF from the message contents:

The body of the email will be passed to the script by Mutt as the first argument, or $1, which I store in the INPUT variable. Notice that I’m also defining a couple other variables at the top of the script. The first, PDIR, is a directory where the created PDF should be located*. Secondly, I’m defining a command which should be executed to open the PDF once it has been created. I prefer a lightweight PDF viewer called zathura, but any PDF viewer (evince, okular, etc.) can be substituted here.

Just below these variable definitions, I make sure that the commmand-line tools I’m using to create the PDF, (enscript and ps2pdf), are installed. There’s not much of a reason to try creating the PDF if they’re not present, so a helpful reminder printed to stderr will notify you in the event that they are not installed. In most Linux distributions, these tools are found in the enscript and ghostscript packages, respectively.

You may have noticed that I am not using the which command to determine if these commands are in my $PATH. A recent blog entry by Aaron Toponce alerted me to the fact that which is not consistently implemented across platforms, and may not set a proper exit status or write error messages to stderr. POSIX provides a command named “command” (what else?), which is consistent across platforms. Running it with -v will print the path of the first matching executable in your $PATH and set an exit status of 0. If there is no match, a non-zero (or false) exit status is set. I don’t care about the path to the executable, so this output is redirected to /dev/null.

If you would rather use a different font for the PDF, you can find a list of PostScript font names here.

When opening the PDF using the pre-defined command, all output is redirected to /dev/null. This is because GUI apps, when run from the command line, will typically print diagnostic messages, warnings, or errors to stdout/stderr. While these messages can be useful for troubleshooting purposes, any output from the script will be displayed in your Mutt window, which will look very ugly. So, this output is discarded.

In order to get Mutt to call the script in place of lpr, you will need to add the following line to your .muttrc file (use the path where you saved the script, of course):

Below is an example of how the result will look. If you do not like the layout, you can alter it by passing different parameters to the enscript command. Check the manpage and experiment to find what works best for you.

mutt_print

So, by replacing the print command with this script, instead of printing the message directly, your PDF viewer of choice will display the message for you. If you want to print it out from there, you can do so. I rarely have a need or desire to print, but this at least leaves me that option. If you want to keep the message, you’ll need to use your PDF viewer to save a copy of it, because it will be gone once you close the window. Again, choosing to remove the PDF is a personal preference of mine, so the last two lines of the script can be commented out or removed if you’d rather keep the PDFs.

* I could just place it under /tmp, but since emails tend to have sensitive or personally-identifiable information, I prefer to have the temp files located within my home directory, where I can manage directory permissions and keep these files private.

Library Books for Kindle: Awesome, But Still Needs Work

Recently, Amazon announced their long-delayed deal to distribute Kindle books through local libraries. The agreement utilizes OverDrive, a digital distributor which provides eBooks in a number of formats and already has partnerships with over 11,000 libraries across the country. Different cities/regions have their own sites which are affiliated with OverDrive, so the process will differ depending on where you live. To start, go to your local library, or do a Library Search on OverDrive’s search page. My local library had me set up a PIN number, and the website directed me to select my library from a list, then enter my library card number and PIN to login.

Once you login and go through the process of “checking out” a book, you will see a link saying Get for Kindle. Clicking this link will take you to a page where you can complete the checkout on Amazon.com.

Kindle Library Checkout

 

This is where some of the warts begin to show. While my 3rd-gen Kindle (recently rebranded the “Kindle Keyboard” after the announcement of the Kindle Touch and Kindle Fire) has a web browser, and I can get through the process of checking out a book using it, the browser is incapable of spawning a new window. This results in an error when I click the Get for Kindle link. So, checking out books from the device is a no-go. This isn’t all that surprising as the web browser is still considered an experimental feature of the early-gen Kindles, and I’m sure that the new Touch and Fire models will have better web support.

So, next I went to my library’s “Digital Bookshelf” page on my smartphone’s web browser, thinking that at the very least I could download the book to my phone and transfer it over to my Kindle since I did not have wi-fi available. But, when I clicked the Get for Kindle link (which sends you to a page where you can complete the checkout process on Amazon.com), Amazon redirected me to their mobile web page, with a one-click buy link and no option to download the book. Had I not been paying close enough attention I may have bought the book rather than borrowed it. Luckily, the mobile browser I was using (Dolphin Browser HD for Android), has the option to change the browser’s user agent so that it does not appear to be a mobile device. Once I had done this, I was able to get through to the correct page to complete the checkout. There was an option to transfer the book via USB, but selecting it resulted in an error and a message saying to try again in 24 hours.

I eventually just downloaded the book once I was on wi-fi.

In conclusion, the new library lending service for Kindle is nice, but there is still plenty of room for improvement. For power users like myself, changing the web browser user agent is an easy solution, but a less-technically-inclined user could easily get fed up by roadblocks like this. Amazon had plenty of time to prepare their library lending system and should have taken into account the ever-increasing number of people who browse the web using smartphones. When you have built a thriving ecosystem around the idea that you can buy a book anywhere and have it available to read in seconds, you are taking a step back when you require customers to use a computer (or result to cumbersome workarounds) to take advantage of library lending.