Document job names.
[whenjobs.git] / tools / whenjobs.pod
index 99c38cf..2acec9f 100644 (file)
@@ -130,7 +130,7 @@ source, eg:
 
 =item B<--set> variable value
 
-=item B<--type> bool|int|float|string
+=item B<--type> bool|int|float|string|unit
 
 I<--set> sets the variable named C<variable> to the new C<value>.  The
 variable is created if it does not already exist.  Note that setting a
@@ -140,9 +140,8 @@ To unset a variable, set it to the empty string:
 
  whenjobs --set var ""
 
-By default variables are untyped (more precisely, they are treated as
-strings).  You can also set the type of a variable when setting it by
-adding the optional I<--type> parameter:
+By default variables are strings.  You can also set the type of a
+variable when setting it by adding the optional I<--type> parameter:
 
  whenjobs --set free_space 10000 --type int
 
@@ -176,6 +175,347 @@ Display brief usage and exit.
 
 =head1 REFERENCE
 
+A whenjobs file consists of a series of one or more "every" or "when"
+statements.
+
+Comments in the file can be written using C<(* ... *)>.  Comments
+may be nested.
+
+Shell script fragments are written using C<E<lt>E<lt> ... E<gt>E<gt>>.
+Within shell script fragments, use C<#> for comments (as in ordinary
+shell scripts).  Because C<E<gt>E<gt>> has a special meaning, it
+cannot be used in the shell script (ie. for redirection).  You have to
+write C<E<gt>\E<gt>> instead which is replaced with C<E<gt>E<gt>> when
+the shell script is parsed.
+
+=head2 EVERY STATEMENTS (PERIODIC JOBS)
+
+An every statement has the form:
+
+ every <period> :
+ <<
+   # shell script
+ >>
+
+where C<E<lt>periodE<gt>> is a I<period expression>, which may take
+one of the forms below.  Don't forget the colon character between the
+period expression and the shell script.
+
+An every statement is a job which runs periodically.
+
+=head3 PERIOD EXPRESSIONS
+
+=over 4
+
+=item B<every second>
+
+The job runs every second.
+
+=item B<every minute>
+
+The job runs every minute.
+
+=item B<every hour>
+
+The job runs every hour.
+
+=item B<every day>
+
+The job runs every day, at midnight UTC.
+
+=item B<every week>
+
+The job runs every week, on a Thursday at midnight UTC.
+
+=item B<every month>
+
+The job runs every month, on the first of the month at midnight UTC.
+
+=item B<every year>
+
+The job runs every year, on the first day of the year at midnight UTC.
+
+=item B<every decade>
+
+=item B<every century>
+
+=item B<every millenium>
+
+The job runs every 10, 100 or 1000 years.
+
+=item B<every I<N> seconds>
+
+The job runs every I<N> seconds (I<N> is any number E<ge> 1).
+
+=item B<every I<N> minutes>
+
+The job runs every I<N> minutes.
+
+=item B<every I<N> hours>
+
+The job runs every I<N> hours.
+
+=item B<every I<N> days>
+
+The job runs every I<N> days.
+
+=item B<every I<N> weeks>
+
+The job runs every I<N> weeks.
+
+=item B<every I<N> months>
+
+The job runs every I<N> months.
+
+=item B<every I<N> years>
+
+=item B<every I<N> decades>
+
+=item B<every I<N> centuries>
+
+=item B<every I<N> millenia>
+
+The job runs every I<N>, I<10*N>, I<100*N> or I<1000*N> years.
+
+=back
+
+=head2 WHEN STATEMENTS (DEPENDENT JOBS)
+
+A when statement has the form:
+
+ when <expr> :
+ <<
+   # shell script
+ >>
+
+where C<E<lt>exprE<gt>> is a I<when expression>, described below.
+Don't forget the colon character between the period expression and the
+shell script.
+
+A when statement is a job which runs when the conditions described in
+its when-expression become true.
+
+When jobs are I<edge triggered>.  This means that they run when the
+condition changes from false to true (or in the case where the
+expression has not been evaluated before, when it evaluates initially
+to true).
+
+=head3 WHEN EXPRESSIONS
+
+When expressions are fully recursive expressions constructed from the
+following elements:
+
+=over 4
+
+=item I<expr> B<&&> I<expr>
+
+=item I<expr> B<||> I<expr>
+
+The boolean "and" or "or" of the two sub-expressions.
+
+=item I<expr> B<E<lt>> I<expr>
+
+=item I<expr> B<E<lt>=> I<expr>
+
+=item I<expr> B<==> I<expr>
+
+=item I<expr> B<E<gt>=> I<expr>
+
+=item I<expr> B<E<gt>> I<expr>
+
+The two sub-expressions are evaluated and the usual comparison
+operator is performed.
+
+If the sub-expressions are numeric, then numeric comparison is done.
+If either sub-expression is non-numeric, then both expressions are
+converted (if necessary) to strings and string comparison is done.
+
+=item B<!> I<expr>
+
+Boolean negative of I<expr>.
+
+=item I<expr> B<+> I<expr>
+
+For numeric sub-expressions, this performs addition.
+
+If both sub-expressions are strings, this performs string
+concatenation.
+
+Other types give an error.
+
+=item I<expr> B<-> I<expr>
+
+=item I<expr> B<*> I<expr>
+
+=item I<expr> B</> I<expr>
+
+=item I<expr> B<mod> I<expr>
+
+Both sub-expressions are evaluated, and if both are numeric, then the
+result is subtraction, multiplication, division or modulo.
+
+Other types give an error.  Note that I<mod> really is an infix
+operator.
+
+=item B<len> I<expr>
+
+If I<expr> is a string, this returns the length of the string.
+
+=item I<variable>
+
+The value of the named variable.
+
+Previously undefined variables are automatically initialized to the
+empty string.
+
+=item B<prev> I<variable>
+
+The I<previous> value of the named variable.  This means, the value
+that it had last time this when-job ran.
+
+If the when-job has not run yet, then this returns C<"">.
+
+=item B<changes> I<variable>
+
+If the named variable has changed since this job last ran, then this
+evaluates to true, else false.
+
+This is the same as writing C<prev variable == variable>.
+
+=item B<increases> I<variable>
+
+If the named variable has changed and increased since this job last
+ran, then this evaluates to true, else false.
+
+This is the same as writing C<prev variable E<lt> variable>.
+
+=item B<decreases> I<variable>
+
+If the named variable has changed and decreased since this job last
+ran, then this evaluates to true, else false.
+
+This is the same as writing C<prev variable E<gt> variable>.
+
+B<Note:> There is a subtle and difficult problem with using the
+I<decreases> operator: The first time the expression is evaluated, the
+job has (by definition) not yet run.  Therefore C<prev variable>
+evaluates to C<""> (see definition of I<prev> above).  Since
+C<"" E<lt> everything>, the I<decreases> operator evaluates to
+false, and since this usually means the job does not run, the
+operator always evaluates to false.  A future version of whenjobs
+will address this problem.
+
+=item B<reloaded ()>
+
+This evaluates to true the first time the expression is evaluated
+after the jobs file has been reloaded or the daemon restarted.
+Thereafter it evaluates to false.
+
+You can use this to initialize variables, but note that this does not
+solve the I<decreases> operator problem described above, because
+variables are initialized too late to affect that.
+
+=item B<false>
+
+=item B<true>
+
+Constants that evaluate to boolean false or true respectively.
+
+=item I<"any string">
+
+Any string.
+
+In a boolean context, the empty string evaluates to false, and
+non-empty strings evaluate to true.
+
+=item I<N>
+
+Any integer.  (Arbitrarily large integers are supported.)
+
+In a boolean context, 0 evaluates to false, and non-zero evaluates to
+true.
+
+=item I<N.>
+
+=item I<.N>
+
+=item I<N.N>
+
+=item I<N.NeN>
+
+Any floating point number.
+
+In a boolean context, 0 evaluates to false, and non-zero evaluates to
+true.
+
+=back
+
+=head2 SHELL SCRIPTS
+
+The code between C<E<lt>E<lt> ... E<gt>E<gt>> is a shell script.  It
+is executed using C<$SHELL>, or if that environment variable is not
+set then C</bin/sh>.
+
+=head3 SHELL SCRIPT VARIABLES
+
+Every variable that has been set (using the whenjobs I<--set> option)
+is exported to the script, so you can simply get the value of any
+variable by writing C<$name>.
+
+In addition, there are some special variables available:
+
+=over 4
+
+=item C<$JOBNAME>
+
+The name of the job.  If the job has been named explicitly, then that
+name is available through this variable, else it will be some implicit
+name like C<job$1>.
+
+=item C<$JOBSERIAL>
+
+The serial number of the job.  This is simply a variable that
+increments each time a job is run, and is unique to that run of the
+job.
+
+=back
+
+Other environment variables such as C<$HOME>, C<$LOGNAME> etc are
+available as normal.
+
+=head3 SHELL SCRIPT TEMPORARY CURRENT DIRECTORY
+
+The shell script runs with its current directory set to a temporary
+directory.  The temporary directory is removed when the shell script
+exits.  Therefore you can write temporary files here without worrying
+about cleaning them up.
+
+If you want to store permanent state, then you have to save it to a
+well-known directory, eg. C<$HOME>, C</var> etc.
+
+=head3 SHELL SCRIPT USER
+
+The shell script runs as the ordinary user.  It has no special
+privileges.
+
+=head2 JOB NAMES
+
+Jobs are given implicit names (C<job$1>, C<job$2> etc.).  You can also
+name jobs explicitly by preceeding the "every" or "when" statement
+with C<job "name">:
+
+ job "poll source"
+ every 10 seconds :
+ <<
+   # ...
+ >>
+
+The job name is passed to the shell script in the C<$JOBNAME>
+environment variable.
+
+
+
+