Wednesday, 19 June 2013

Good morning haze!

Yesterday morning Singapore woke up under thick haze due to forest fires in nearby Sumatra. Not healthy: You can feel it in your throat, and some corridors smell like Scamorza (some delicious Italian smoked cheese).

It smells just like that... (Image from Necrophorus@Wikipedia, GFDL)
Anyway... it gives some "interesting" light when the sun is low.

Good morning purée... (slightly underexposed)

Red sun, still high above the horizon (~1h before sunset).

Sunday, 9 June 2013

Parse XML from shell scripts

As part of the crouton/chroagh project, I wanted to be able parse D-bus configuration file, to figure out what user account the system D-bus runs under.

The configuration file looks like this:
# /etc/dbus-1/system.conf
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"

  <!-- Our well-known bus type, do not change this -->

  <!-- Run as special user -->

  <!-- Fork into daemon mode -->

Yes, that's XML. And normally, XML and shell scripts are not exactly good friends...

What we want to be able to do here is to fetch the content of the user tag.

Solution 1 - sed

Well, that's without doubt the easiest:
sed -n 's|.*<user>\(.*\)</user>|\1|p' /etc/dbus-1/system.conf
Problem is that the is no guarantee that there would be no other user tag[1], in other parts of the file, and, who knows, the tag might be commented out. We also do not handle "misplaced" newlines in the file...

[1] Actually, there is no other user tag, according to the dtd file, but not necessarily in a general case... And well, this post is boring if I stop here, right?

Solution 2a - xmllint

A more proper and generic solution, making use of the xmllint parser:
echo "cat /busconfig/user/text()" | xmllint --shell /etc/dbus-1/system.conf
Problem is, xmllint is not really script-friendly, and outputs some garbage along with the desired output.
$ echo "cat /busconfig/user/text()" | xmllint --shell /etc/dbus-1/system.conf
/ > cat /busconfig/user/text()
/ > $
In my case, I know how a valid username looks like, so I just pipe the output through grep '^[a-z][-a-z0-9_]*$', and that's the solution that is used in my code. Also, xmllint is installed by default on Chrome OS, so that's good enough for me.

Solution 2b - xmllint and write

An improved version would be:
echo "cd //busconfig/user/text()
     write tmp" | xmllint --shell /etc/dbus-1/system.conf
cat tmp
This is cleaner, as the full text of the tag is written to a file, but this requires an intermediate file, so, maybe not that nice...

Solution 2c - xmllint, write, and fd/3

Maybe an even nicer one, assuming /dev/fd exists (as it does on recent Linux distributions):
exec 3>/dev/null
echo "cd //busconfig/user/text()
     write /dev/fd/3" | xmllint --shell /etc/dbus-1/system.conf 3>&1 1>/dev/null 2>/dev/null
exec 3<&-
No temporary file!

Solution 3 - xsltproc

Finally, the most powerful version, using XSLT:
xsltproc - /etc/dbus-1/system.conf <<END
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="">
<xsl:output method="text" encoding="utf-8" />
<xsl:template match="/"><xsl:value-of select="/busconfig/user"/></xsl:template>
That's as good as it gets, and you could easily do much more complicated things with XSLT. But, that's a bit overkill for our purpose (and xsltproc is not installed in Chrome OS).

Sunday, 2 June 2013


Since the adventure during my last trip, where my (work/home/main) laptop suddenly died, I realized that carrying a heavy and expensive laptop is not the best idea while travelling (in terms of risk of theft, damage, but also weight to carry around).

A tablet would be an option, but they do not offer the flexibility I want (keyboard, photo editing, etc.), and they are generally not easy to hack. Netbooks seems to be a thing of the past, so I went for a Chromebook.

I went for the second cheapest (Samsung ARM Chromebook, USD 249), the cheapest being a bit too heavy and bulky (Acer C7, USD 199), and maybe less exciting with a standard x86 processor.

It is unfortunately not available in Singapore (at least not through usual channels), and some websites, such as Amazon, do not want to ship it to Singapore. Fortunately for me, B&H Photo Video does not care, and shipped it to me for USD 52. Three days later, I received my new toy, with no GST to pay (total amount below SGD 400, see here).

Samsung ARM Chromebook (running Archlinux/XFCE using chroagh, but more on that later).
Well, I won't repeat what other reviews say online (there are plenty), but, basically:
  • First, you pay what you get for. Don't expect it to behave like a laptop with a price tag 10 times higher (a friend said: "Fake Macbook!! Oh no, Korean!!", and, well, that's not completely inaccurate): The body is plastic, and this is not a powerhouse. But still, for the price, I find it awesome.
  • Very light (1.1kg) and thin (1.8cm).
  • No fan, no moving parts: No noise at all, little heat, and long battery life (~6h).
  • Dual-core ARM processor (1.7Ghz): This is a bit better than your last generation cell phone (well, it does out-of-order execution so it's probably a step faster), but it seems to do the job fairly well.
  • Chrome OS:
    • Very good browsing experience, very fast. Youtube works well in general, but tends to lag when you do other things at the same time: not ideal if you have your music playlist on Youtube.
    • You need connectivity for most stuff. There are a few offline apps (I haven't tried many), but most things will require a Wifi connection.
  • Movie playback (from files, non-Youtube) is a problem: It could not read some x264-encoded files, even in SD quality. I mean, it could, but only displayed one frame per second or so... Maybe this could be improved in later versions of Chrome OS by optimizing the video decoder (e.g. use whatever hardware acceleration facilities the processor has).
  • Finally, and this is critical for me: hackability. This is not an Apple device or a locked Android phone. Google lets you do whatever you want with your computer, including wiping Chrome OS to install something else, or installing another Linux in parallel (crouton/chroagh).
In short, mildly recommended for the normal user, Chrome OS is great, but really needs a working connection to be used to its full potential. And this is not always the case while travelling.

Strongly recommended for the more advanced user, as you can install a regular Linux in parallel: either as Dual-boot, or as a chroot inside Chrome OS, where you can switch between Chrome OS and your Linux with a simple key combination. I used the wonderful crouton to install Ubuntu, and ported it to support Archlinux (chroagh). More on that for a later post.