Tuesday, December 9, 2014

expr + test = xp

The clive command xp(1) replaces the venerable UNIX commands expr and test. It is interesting to note why. In few words, both commands are doing the same, and thus they are a single command in Clive.

The purpose of a command line calculator is to evaluate expressions. Now, the purpose of the test command in UNIX is also to evaluate expressions. Only that test knows how to evaluate expressions on file attributes.

Considering that in clive directory entries are generic maps from attribute names to attribute values, it seems that a single command can do both. The result is that we can do calculations on, for example, file sizes and file modification times in very much the same way we can calculate on floating point numbers. Or we can perform bitwise operations on file permissions. As a result, the grammar known to the calculator is also available for free to the "test" command, because it is the same command.

For example, it is clear that we can do things like
> xp 2 + 2
4
> xp 1k
1024
> xp 1m
1048576

But, we can use the same command to print metadata for files. For example, to print out
the file type:
> xp type .
d
> xp type xp.go
-

Now we can write general purpose expressions as we see they fit; e.g. is the size larger than 1Kbyte?

> xp size xp.go '>' 1k
false


Or, how many full Mbytes are used by a binary?

> xp size '"'`which xp`'"' / 1m
5

Another example. Let's check the mode for a file
> xp mode xp.go
0644

Now we can write an expression to get the write permissions,
> xp mode xp.go '&' 0222
128

or to see if any of them is set
> xp mode xp.go '&' 0222 '!=' 0
true

which can be done easier, by the way:
> xp w xp.go
true