Wandering Thoughts archives

2008-09-16

A Unix without a test program

Courtesy of a recent entry, I was reading over my dotfiles when I stumbled over a remnant of a rather peculiar and annoying Unix (unfortunately, I no longer remember which one it was). This Unix was notable for a simple reason: it didn't have a test program.

You might sensibly ask how on earth anything that can possibly call itself a Unix would be missing such a basic thing; after all, without test a lot of scripts don't work at all, since test is also known as '[', which is commonly used in Bourne shell condition checking. The answer is simple: the people behind this Unix had made test a shell builtin, so all of the shell scripts still worked. They just hadn't set up a /bin/test program, presumably because they didn't expect any sensible program to run test directly.

(This is slightly less crazy than it seems; if you have a a test program and also a test shell builtin, you have to make sure that the two behave exactly the same. If you expect the test program to never be used, removing it simplifies your life and means that you don't have to keep it in sync with your improvements to the shell builtin.)

As it happens, there is one sort of sensible program that does exactly this: non-standard shells. My shell doesn't have test as a builtin, so I needed an actual test program; when this Unix didn't have one, my dotfiles became moderately unhappy.

(My solution was to make a test Bourne shell script that just ran the shell's builtin test, which is what this particular Unix vendor should have done for /bin/test in the first place.)

UnixWithoutTest written at 01:04:04; Add Comment

2008-09-10

A Unix shell trick

This is the sort of trick where I present the code first and explain it afterwards:

arch=`(PATH=$HOME/bin:/local/bin:$PATH arch || echo unknown) 2>/dev/null`

(This has been slightly modified to keep the line length down; in the real version, more things are added to $PATH. Note that this may be word-wrapped in your browser.)

This sets the $arch variable to the output of the arch command, if there is one to be found in any number of places, and otherwise gives $arch the value of 'unknown', all in one line. It's worth unpacking this into its component parts (somewhat abbreviated) in order to see how it works:

PATH=$HOME/bin:/local/bin:$PATH arch
Search for an arch command using a temporarily augmented and altered $PATH.
... || echo unknown
If we failed to find an arch, supply a default value; a command that isn't found is a false condition, just as if the command itself failed. (We assume that arch itself will never fail.)
(...) 2>/dev/null
Discard any complaint from the shell about being unable to find arch.

(Using just '$PATH=... arch 2>/dev/null' wouldn't suppress the 'arch: not found' error message, because the error message comes from the shell, not from a theoretical arch. We have to use a subshell in order to be able to redirect the shell's own error message.)

This is the kind of thing that makes programming in the Bourne shell fun and interesting, and I say that non-sarcastically.

Sidebar: why I do this

Why I do this requires slightly more explanation. I have a single generic .profile that I use on all of the systems I have accounts on, and on some of them my home directory is shared across multiple architectures, which means that I need to add an architecture-specific directory to my $PATH (for architecture dependent binaries), which means that I need to know what the local architecture is.

(By local tradition, 'architecture' here includes the operating system as well as the chipset; typical values are things like 'solaris-sparc'.)

There is a vague local tradition that there is an arch command that prints out a string suitable for this. However, not all systems follow this tradition, and not all systems put arch in the same place, and sometimes I need to fake it with a $HOME/bin/arch (if, for example, I am in a multi-architecture environment that doesn't follow this tradition). So determining the local architecture requires dealing with all of these possibilities, hence the one-liner.

ShellTrickI written at 00:48:20; Add Comment


Page tools: See As Normal.
Search:
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.