You are currently viewing all posts tagged with shell.


Redshift is a program that adjusts the color temperature of the screen based on time and location. It can automatically fetch one’s location via GeoClue. I’ve used it for years. It works most of the time. But, more often than I’d like, it fails to fetch my location from GeoClue. When this happens, I find GeoClue impossible to debug. Redshift does not cache location information, so when it fails to fetch my location the result is an eye-meltingly bright screen at night. To address this, I wrote a small shell script to avoid GeoClue entirely.

Redswitch fetches the current location via the Mozilla Location Service (using GeoClue’s API key, which may go away). The result is stored and compared against the previous location to determine if the device has moved. If a change in location is detected, Redshift is killed and relaunched with the new location (this will result in a noticeable flash, but there seems to be no alternative since Redshift cannot reload its settings while running). If Redshift is not running, it is launched. If no change in location is detected and Redshift is already running, nothing happens. Because the location information is stored, this can safely be used to launch Redshift when the machine is offline (or when the Mozilla Location Service API is down or rate-limited).

My laptop does not experience frequent, drastic changes in location. I find that having the script automatically execute once upon login is adequate for my needs. If you’re jetting around the world, you could periodically execute the script via cron or a systemd timer.

This solves all my problems with Redshift. I can go back to forgetting about its existence, which is my goal for software of this sort.

Searching Books

ripgrep-all is a small wrapper around ripgrep that adds support for additional file formats.

I discovered it while looking for a program that would allow me to search my e-book library without needing to open individual books and search their contents via Calibre. ripgrep-all accomplishes this by using Pandoc to convert files to plain text and then running ripgrep on the output. One of the numerous formats supported by Pandoc is EPUB, which is the format I use to store books.

Running Pandoc on every book in my library to extract its text can take some time, but ripgrep-all caches the extracted text so that subsequent runs are similar in speed to simply searching plain text – which is blazing fast thanks to ripgrep’s speed. It takes around two seconds to search 1,706 books.

$ time(rga -li 'pandemic' ~/library/books/ | wc -l)

real    0m1.225s
user    0m2.458s
sys     0m1.759s

Bleach has a shelf life of 6 to 12 months.

After one year the sodium hypochlorite will have broken down into salt and water, which will not be helpful in your battle against the Black Death. According to the University of Nebraska’s guidelines on chemical disinfectants for biohazardous materials, “bleach loses 20-50% of its sodium hypochlorite concentration after 6 months”.

Bottles of Clorox bleach are stamped with a date code which when properly decoded will indicate the date of manufacture. The first 7 characters in the label on one of my bottles are A819275, indicating that it was manufactured in plant A8 on the 275th day of 2019, or October 2nd. The previously mentioned dateutils proves its usefulness here.

$ datediff 2019-275 now
$ datediff 2019-275 now -f "%m months, %d days"
5 months, 17 days

A simple shell function may be used to decode the date.

jul () {
    date -d "$1-01-01 +$2 days -1 day" "+%Y-%m-%d";

$ jul 2019 275

Monitoring Legible News

I was sent a link to Legible News last November by someone who had read my post on the now-defunct Breaking News. Legible News is a website that simply scrapes headlines from Wikipedia’s Current Events once per day and presents them in a legible format. This seems like a simple thing, but is far beyond the capabilities of most news organizations today.

Legible News provides no update notification mechanism. I addressed this by plugging it into my urlwatch system. Initially this presented two problems: the email notification included the HTML markup, which I didn’t care about, and it included both the old and new content of every changed line – effectively sending me the news from today and yesterday.

The first problem was easily solved by using the html2text filter provided by urlwatch. This strips out all markup, which is what I thought I wanted. I ran this for a bit before deciding that I did want the output to contain links. What I really wanted was some sort of html2markdown filter.

I also realized I did not just want to be sent new lines, but every line anytime there was a change. If the news yesterday included a section titled “Armed conflicts and attacks”, and the news today included a section with the same title, I wanted that in my output despite it not having changed.

I solved both of these problems using the diff_tool argument of urlwatch. This allows the user to pass in a special tool to replace the default use of diff to generate the notification output. The tool will be called with two arguments: the filename of the previously downloaded version of the URL and the filename of the current version. I wrote a simple script called html2markdown.sh which ignores the first argument and simply passes the second argument to Pandoc for formatting.


pandoc --from html \
--to markdown_strict \
--reference-links \
--reference-location=block \

This script is used as the diff_tool in the urlwatch job definition.

kind: url
name: Legible News
url: https://legiblenews.com/
diff_tool: /home/pigmonkey/bin/html2markdown.sh

The result is the latest version of Legible News, nicely converted to Markdown, delivered to my inbox every day. The output would be even better if Legible News used semantic markup – specifically heading elements – but it is perfectly serviceable as is.

After I built this I discovered that somebody had created an RSS feed for Legible News using a service called Feed43.

Personal Information Management

pimutils is a collection of software for personal information management. The core piece is vdirsyncer, which synchronizes calendars and contacts between the local filesystem and CalDav and CardDAV servers. Calendars may then be interacted with via khal, and contacts via khard. There’s not much to say about these three programs, other than they all just work. Having offline access to my calendars and contacts is critical, as is the ability to synchronize that data across machines.

Khard integrates easily with mutt to provide autocomplete when composing emails. I find its interface for creating, editing and reading contacts to be intuitive. It can also output a calendar of birthdays, which can then be imported into khal.

Khal’s interface for adding new calendar events is much simpler and quicker than all the mousing required by GUI calendar programs.

$ khal new 2019-11-16 21:30 5h Alessandro Cortini at Public Works :: 161 Erie St

There are times when a more complex user interface makes calendaring tasks easier. For this Khal offers the interactive option, which provides a TUI for creating, editing and reading events.

Khal can also import iCalendar files, which is a simple way of getting existing events into my world.

$ khal import invite.ics

Vdirsyncer has maintenance problems that may call its future into question, but the whole point of modular tools that operate on open data formats is that they are replaceable.

I have a simple and often used script which calls khal calendar and task list (the latter command being taskwarrior), answering the question: what am I supposed to be doing right now?

Terminal Calculations

Qalculate! is a well known GTK-based GUI calculator. For years I ignored it because I failed to realize that it included a terminal interface, qalc. Since learning about qalc last year it has become my go-to calculator. It supports all the same features as the GUI, including RPN and unit conversions. I primarily use GNU Units for unit wrangling, but being able to perform unit conversions within my calculator is sometimes useful.

$ qalc
> 1EUR to USD
It has been 20 day(s) since the exchange rates last were updated
Do you wish to update the exchange rates now? y

  1 * euro = approx. $1.1137000

> 32oC to oF

  32 * celsius = 89.6 oF

The RPN mode is not quite as intuitive as a purpose built RPN calculator like Orpie, but it is adequate for my uses. My most frequent use of RPN mode is totaling a long list of numbers without bothering with all those tedious + symbols.

> rpn on
> stack
The RPN stack is empty
> 85

  85 = 85

> 42

  42 = 42

> 198

  198 = 198

> 5

  5 = 5

> 659

  659 = 659

> stack

  1:    659
  2:    5
  3:    198
  4:    42
  5:    85

> total

  total([659, 5, 198, 42, 85]) = 989

> stack

  1:    989

Also provided are some basic statistics functions that can help save time.

> mean(2,12,5,3,1)
  mean([2, 12, 5, 3, 1]) = 4.6

And of course there are the varaibles and constants you would expect

> 12+3*8)/2
  (12 + (3 * 8)) / 2 = 18
> ans*pi
  ans * pi = 56.548668

I reach for qalc more frequently than alternative calculators like bc, insect, or the Python shell.

Without an OCR layer, PDF files are of limited use.

OCRmyPDF is a tool that applies optical character recognition to PDFs. It uses Tesseract to perform the OCR, and unpaper to clean, deskew and optimize the input files. It outputs PDF/A files, optimized for long-term storage. This isn’t a tool I use frequently, but it is one I greatly appreciate having when I need it. If you ever find yourself scanning or photographing documents, you want OCRmyPDF.