A Weird Imagination

Identifying joystick devices

Posted in

Too many input devices

On a modern computer there are often many input devices,

$ ls /dev/input/event* | wc -l

They are just identified by numbers, so it can be difficult to choose the right one and trial-and-error can get tiresome with so many. There is some help from the by-id and by-path listings:

$ ls -go --time-style=+ /dev/input/by-id/
lrwxrwxrwx 1 10  usb-045e_0291-if06-event-joystick -> ../event26
lrwxrwxrwx 1  6  usb-045e_0291-if06-joystick -> ../js6
lrwxrwxrwx 1 10  usb-0b43_0003-event-if00 -> ../event20
lrwxrwxrwx 1 10  usb-0b43_0003-event-joystick -> ../event19
lrwxrwxrwx 1  6  usb-0b43_0003-joystick -> ../js1
lrwxrwxrwx 1  9  usb-BTC_USB_Multimedia_Keyboard-event-if01 -> ../event2
lrwxrwxrwx 1  9  usb-BTC_USB_Multimedia_Keyboard-event-kbd -> ../event1

$ ls -go --time-style=+ /dev/input/by-path/
lrwxrwxrwx 1  9  pci-0000:00:1a.2-usb-0:2:1.0-event-kbd -> ../event1
lrwxrwxrwx 1  9  pci-0000:00:1a.2-usb-0:2:1.1-event -> ../event2
lrwxrwxrwx 1 10  pci-0000:00:1d.0-usb-0:1:1.6-event-joystick -> ../event26
lrwxrwxrwx 1  6  pci-0000:00:1d.0-usb-0:1:1.6-joystick -> ../js6
lrwxrwxrwx 1 10  pci-0000:00:1d.0-usb-0:2:1.0-event -> ../event20
lrwxrwxrwx 1 10  pci-0000:00:1d.0-usb-0:2:1.0-event-joystick -> ../event19

But, for the most part, those names aren't very helpful, especially since many joystick devices support 2 or 4 joysticks connected to the same device.


Enter identify_evdev.py:

$ identify_evdev.py

Where /dev/input/event22 is the device of the joystick I touched after running identify_evdev.py.

Read more…

Impromptu dice

Posted in

Dice in shell

Today I was borrowing a board game from the lending library at Emerald City Comicon and it was missing its dice. We could have gotten some physical dice somewhere, but instead we decided to use the materials we had on hand. The people I was playing with agreed that we did not want to drain our phone batteries by using a dice app on our phones, but I had a laptop with me. So I wrote a dice app for the shell:

while true
    seq 1 6 | shuf -n1
    seq 1 6 | shuf -n1

This rolls two six-sided dice every time you hit enter and clears the screen before showing the result using reset.

Read more…

The clipboard in the command-line

Posted in

X clipboard

The X Window System, the basis for the GUI on most desktop Linux systems, defines how the clipboard works for copying and pasting between applications in Linux. One notable quark of X clipboard is that there's actually two clipboards in common use: the one you expect explicitly accessed via Copy and Paste menu items or key shortcuts called the CLIPBOARD and another one where you copy by selecting text and paste by pressing the middle mouse button called the PRIMARY selection.

X clipboard utilities

Occasionally it is useful to be able to read or write the clipboard at the command-line. For most uses, your terminal emulator's copy and paste options are probably enough. The primary use case I have for using a command-line program to interact with the clipboard is when I am uploading a file as a Gist:

<file xclip

The xclip utility will copy the contents of the file onto the clipboard (PRIMARY, not CLIPBOARD, by default) and then I can paste it on the Gist website.

My system also has xsel which is very similar to xclip. Wikipedia actually lists several such programs, including the unfortunately named xcopy, not to be confused with XCOPY.

GNU Screen copy mode

GNU Screen provides its own clipboard for copying information between the different windows of a screen session. ctrl+a, [ enters copy mode. In copy mode you can move the cursor using the arrow keys and page up/page down keys. Screen keeps a history (of configurable size), so you can scroll back pretty far. In fact, I use Screen's copy mode far more often for viewing the history in a terminal than for actually copying anything. You can exit copy mode either by using esc to cancel or enter once to mark the start of the selection and again to mark the end of it. Once you have copied something, ctrl+a, ] pastes the contents of the clipboard.

Listing files into a file

Posted in

The problem

$ ls > file

doesn't do what you expect:

$ touch foo
$ touch bar
$ ls > filelist
$ cat filelist

You probably didn't expect, or want, filelist to be listed in filelist.

The solution

$ filelist=$(ls); echo "$filelist" >filelist

Read more…

Blend effect slideshow using shell

Posted in

The goal

Given a series of images, present them in a video with a blend effect between the images. The frames between the input frames should gradually transition between the previous and next image. This, and other transition effects, could likely be implemented using a slideshow generator, but it can also be done quite easily using a shell script.

The script

The final script I wrote is blend.sh. The following commands fetch and run it:

$ wget https://gist.githubusercontent.com/dperelman/2b4b86233aa13d13c0ab/raw/91c7988e27288af8aeb25ade11d0cab90355702f/blend.sh
$ chmod +x blend.sh
$ ./blend.sh slideshow.mkv first.png second.jpg third.gif
$ mplayer slideshow.mkv

The input images may be in any format. The extension of slideshow.mkv will be used by FFmpeg to guess the desired video format (H.264 in a Matroska Multimedia Container for .mkv).

Read more…

Which command will be run?

Posted in

The problem

While trying to develop a modification to the Pelican source, I was unexpectedly having my installed version of Pelican get run instead of the local version:

$ which pelican
$ command -v pelican

For some reason, which was pointing to the executable I was expecting bash to run, but the Bash builtin command was telling me that bash was running the installed version instead.

The solution

Use the hash builtin to clear bash's cache of the location of pelican:

$ hash -d pelican
$ command -v pelican

Read more…

Reverse sequence for tr

The problem

If you take the word wizard, reverse the order of the letters and reverse the alphabet:

From: abcdefghijklmnopqrstuvwxyz

then you get the word wizard back, an observation made at least as early as 1972.

Now let's write a shell script to verify this so we can find other words with similar interesting properties. The obvious shell script to verify this

echo wizard | tr a-z z-a | rev

unfortunately fails with the error

tr: range-endpoints of 'z-a' are in reverse collating sequence order

The error is by design: it's not clear what a sequence in reverse order should mean, so POSIX actually requires that it not work.

Read more…

Floats in shell

The problem

Given a file which contains a list of floating point numbers in IEEE 754 single-precision format stored in big endian byte order, how do you view and manipulate this data using command-line tools? This is an actual problem one of my officemates had.

The solution

$ od --endian=big -f file
0000000   1.7155696e-07   1.0432226e-08    4.563314e+30    6.162976e-33

Read more…

Changing Pelican URL scheme

Posted in

The problem

I changed the URI scheme of this blog recently from /posts/YYYY/MM/slug/ to /YYYY/MM/DD/slug/. The latter looks better and makes the actual day of the post more visible.

But I already had posts using the old scheme and cool URIs don't change. Luckily, someone wrote a Pelican plugin called pelican-alias which allows articles to be tagged with additional URIs to redirect to their canonical location. All I had to do was add an Alias: /posts/2015/02/... line to the top of each of the posts I had already written and the plugin would take care of the rest.

Automating the aliasing

The non-trivial part of automating this is that the URIs include the article's slug, which may have been generated by Pelican from the title, so Pelican has to be involved in generating the correct redirects.

There are two ways I could have automated this process:

  1. Modify the plugin to add a redirect from the old scheme to the new scheme for every article. Unless somehow controlled, this would result in creating redirects for new articles which do not need them.
  2. Write a one-off script to get the slugs out of Pelican and write the Alias: lines into the blog posts.

I took the latter approach because it was simpler and involved no new code to maintain.

Read more…

Type your SSH passphrase less often

Posted in

The problem

SSH public key authenication can make SSH much more convenient because you do not need to type a password for every SSH connect. Instead, in common usage, the first time you connect, GNOME Keyring, KWallet, or your desktop environment's equivalent will pop up and offer to keep your decrypted private key securely in memory. Those programs will remember your key until the next time you reboot your computer (or possibly until you log out completely and log back in).

But those are tied to your desktop environment. If you are not at a GUI, either using a computer in text-mode using a console or connecting over SSH, then you do not have access to those programs.

Read more…