|
Archive:
Subtopics:
Comments disabled |
Sat, 22 Mar 2008
The "z" command: alternative implementations
% z grep immediately *
ctime.blog:we want to update. It is immediately copied into a register, and
/proc/self/fd/3:All five people who wrote to me about this immediately said "oh, yes,
/proc/self/fd/5:program continues immediately, possibly posting its message. (It
struct-inode.blog:is a symbolic link, its inode is returned immediately; iname() would
sync.blog:and reports success back to the process immediately, even though the
For a detailed discussion, see the
previous article.Fixing this flaw seems difficult-to-impossible. As I said earlier, the trick is to fool the command into reading from a pipe when it thinks it is opening a file, and this is precisely what /proc/self/fd is for. But there is an older, even more widely-implemented Unix feature that does the same thing, namely the FIFO. So an alternative implementation creates one FIFO for each compressed file, with a gzip process writing to the FIFO, and tells the command to read from the FIFO. Since we have some limited control over the name of the FIFO, we can ameliorate the missing-filename problem to some extent. Say, for example, we create the FIFOs in /tmp/PID. Then the broken zgrep example above might look like this instead:
% z grep immediately *
ctime.blog:we want to update. It is immediately copied into a register, and
/tmp/7516/env-2.blog.gz:All five people who wrote to me about this immediately said "oh, yes,
/tmp/7516/qmail-throttle.blog.gz:program continues immediately, possibly posting its message. (It
struct-inode.blog:is a symbolic link, its inode is returned immediately; iname() would
sync.blog:and reports success back to the process immediately, even though the
The output is an improvement, but it is not completely solved, and the
cost is that the process and file management are much more
complicated. In fact, the cost is so high that you have to wonder if
it might not be simpler to replace z with a shell script that
copies the data to a temporary directory, uncompresses the files, and
runs the command on the uncompressed files, perhaps something along
these lines:
#!/bin/sh
DIR=/tmp/$$
mkdir $DIR
COMMAND=$1
shift
cp -p "$@" $DIR
cd $DIR
gzip -d *
$COMMAND *
This has problems too, but my point is that if you are willing to
accept a crappy, semi-working solution along the lines of the FIFO
one, simpler ones are at hand. You can compare the FIFO version
directly with the shell script, and I think the FIFO version loses.
The z implementation I have is a
solution in a different direction, and different tradeoffs, and so
might be preferable to it in a number of ways. But as I said, I don't know yet. [ Addendum 20080325: Several people suggested a fix that I had considered so unwise that I didn't even mention it. But after receiving the suggestion repeatedly, I wrote an article about it. ]
[Other articles in category /Unix] permanent link |