Copyright © 2015,2020 by Thomas E. Dickey

TEST versus Portability


The X/Open documentation is a consensus based on documentation and the contributor's experience. Sometimes the features which are standardized have been recombined by implementators in unexpected ways. The test command is an example.

Referring to IEEE Std 1003.1, 2004 Edition for test, and expr, one may notice some overlap. That is, the two commands use similar binary operations for comparing data. However, the specification for test distinguishes between strings and numbers, while that for expr does not. Instead, it allows either:

With that caveat, the two look alike, except that test seems to have some extra features.

Operator test expr
= string either
!= string either
-eq integer N/A
-ne integer N/A
-gt integer N/A
-ge integer N/A
-lt integer N/A
-le integer N/A
> integer either
>= integer either
< integer either
<= integer either


The two sets of features are not identical, of course. Happily, autoconf itself stays away from this pitfall:

However, I wrote tests for my applications which used expr. Those followed the POSIX specification. One would assume that would make the checks portable to any POSIX-compliant platform. Furthermore, I had used the expr utility for a while:

Macro Creation date
CF_AWK_BIGSTRING 2008/09/06 18:32:15
CF_LEX_STATES 1999/05/07 22:29:23
CF_WIDEC_SHIFT 1997/09/06 23:41:28


Autoconf is a portability aid. As said long ago (well-known in 1991 for instance):

It has been said that there is no such thing as portability, only programs that have been ported. Strict compliance may also lead to tunnel vision.

Meet Minix. And Ash.

I install and configure on my machines as wide a variety of operating systems as possible, to help with porting and bug reports. Until 2010, that was mainly through multibooting. Although I had started working with VMware Workstation in 2005, there were only a few suitable machines.

I had attempted a Minix install a few years ago (in 2008, using 3.1.2b, 3.1.3a), but was unsuccessful using VMware Workstation. Later, I tried with Parallels (in 2010) and VMware Fusion (in 2012). Still no luck. If it booted, the network interface would not work. More recently, I have also been using VirtualBox. I revisited Minix in July 2014 and was finally successful with Minix 3.2.

With Minix 3.2, I found two problems with my configure checks:

Minix 3.2 used an old version (from 1989) of the Almquist shell ash, which was modified to work with Minix. In this configuration, expr was a built-in of ash. Also, expr and test were the same program. Here is a table which one can use to compare:

POSIX Minix 3.2
Operator test expr test expr
= string either string string
!= string either string string
-eq integer N/A integer integer
-ne integer N/A integer integer
-gt integer N/A integer integer
-ge integer N/A integer integer
-lt integer N/A integer integer
-le integer N/A integer integer
> integer either N/A N/A
>= integer either N/A N/A
< integer either N/A N/A
<= integer either N/A N/A

Then, as on writing this page later (early 2015), the Minix developers guide said

MINIX 3 is POSIX conformant.

and went on to say that an attempt was made to ensure that Minix 2.0.0 (in 1996) conformed to ANSI/IEEE Std 1003.1, First edition, 1990-12-07, and further, that Minix 3 (released in 2005) conformed to IEEE Std 1003.1, 2004 Edition, Single UNIX Specification Version 3.

The first mention of 1003.1 referred to the programming interface. Shell commands were standardized in the Single Unix Specification. These features were (according to the POSIX FAQ) merged with 1003.1 in 1999. For instance, see the 1997 version of expr and test. However, as noted in other places conformance checking was informal.

In my configure checks, I used expr, e.g.,

while test 0 != `expr $cf_lex_statenum \< $cf_lex_statemax`

To repair the checks, I used test, e.g.,

while test $cf_lex_statenum -lt $cf_lex_statemax

Of course, I did not simply change the script. I looked to see what the problem was, reading the source for the Minix shell. Here is a good starting point (the sources on Github):

The Minix webpage at that time (July 21, 2014) said that Minix 3.3 would be released in September, so I decided to wait to see if the problem would be resolved. Checking back in early 2015, I saw that about two weeks later (August 3, 2014), the Minix developers imported an updated shell program (again from NetBSD). If I had been more patient, the more than twenty year old shell program would have been fixed.

The documentation was updated as well:

That is, it was updated online. The Minix 3.3 which I installed referred to NetBSD in its manpage for expr.