The other day I released a utility which I called when. The idea of
when is to watch(1) a command only until it succeeds, and perform
some action when it does. There was a lot of confusion around this. People
suggested that I missed the boat since the shell can do this natively with a
simple loop. However, what people failed to realize is that when solved a
different problem as well.
The other problem that when set out to solve is that notification that a
long running process succeeded isn’t always enough. Perhaps I wanted to see
if the long running process started successfully (this assumes that your
long running process can fail quickly, though that’s what the -n option is
for). More on that in a second.
In some ways it’s rather silly to have when launch the second process when
it’s something the shell can easily do–I agree1. So, the default mode
(-z mode) might be better described as “retry until 0”. Then, basic usage
would look like:
when "cat /file/that/will/exist" && grep "ERROR" /file/that/will/exist
Of course, the above example is silly since you could do grep instead of cat
to begin with, but I digress. However, if I change when to adopt those
semantics, then an invocation need not quote the commands because the shell
will parse it as:
when cat /file/that/will/exist
and
&& grep "ERROR" /file/that/will/exist
In a bourne compatible shell, when never sees anything past the &&, which,
with our argument parsing, means that we can call execvp directly on argv
after incrementing past the options, making the code simpler, and eliminate
the subshell invocation all together!2
What does this do to -t mode though, the reason when exists to begin with?
Well, that’s a bit trickier. In essence it’d make sense to be able to share
the same argument passing semantics–"unquoted” when possible, but the shell
can’t help us complete what we’re looking for. So, perhaps we do:
when ssh _temporarily unreachable host_ **-alarm** xmessage 'connected' &&
xmessage ‘closed’
This forces us to do more work to parse arguments, but allows us to work in non-quoted mode, and makes it a bit more clear what’s happening. Plus, we share the same “finished” semantics as in the default mode.
The usage of -alarm sort of implies what’s happening. Run xmessage
'connected' after some event occurs. A user would just have to understand
that the alarm goes off after N seconds of the command not being retried.
The only question then becomes whether or not when is the proper name for
this.
(thanks to the suckless-dev list for the discussion.)