When
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.)
—2013-12-12