A Unix shell trick

September 10, 2008

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.

Written on 10 September 2008.
« The problem with unit testing programs
Why I have the same shell dotfiles everywhere »

Page tools: View Source, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Wed Sep 10 00:48:20 2008
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.