Statements

(NOTE:  Some of the techniques shown or described on this page--marked in purple--require new features in the latest official PIKT 1.19.0 release (pikt-current.tar.gz) that are unavailable in any previous version.)

In Pikt scripts (and excepting the script/stanza name, in the leftmost column), every statement begins with a statement keyword.  Most you have seen already:

KEYWORD                      ATTRIBUTE

init
begin
rule
end

status                       active|inactive
level                        emergency|alert|critical|error|
                             warning|notice|info|debug
task                         "<alarm description>"
input                        proc|process "<process>"
                             file "<filename>"
                             logfile "<filename>"
filter                       "<process>"
seps|separators              "<separators>"
dat|data                     <data specifier>
keys                         <var> [<var> ...]

if                           <conds>
else
elif|elsif|elseif            <conds>
endif|fi
while                        <conds>
endwhile
repeat
until                        <conds>
for                          <set statement>
                             <cond> <set statement>
                             <string var> in
                             <keys function>
endfor
foreach                      <keys function>
endforeach
break
continue|cont
switch                       <string or numerical expression>
case                         <character or number>
default
breakswitch|breaksw
endswitch|endsw
again
leave
redo
next
skip                         <numerical expression>
last
pause                        <numerical expression>
quit
die                          "<message>"
Here are the rest of the statement keywords:
KEYWORD                      ATTRIBUTE

do                           <function call>
set                          <var> = <expr>
unset|delete                 <var[]>
exec [wait]                  "<process>"
doexec [wait]                "<process>"
output                       [mail "<message line>"]
                             [print "<message line>"]
                             ["<logfile>"|piktlog|syslog
                              "<message line>"]
'do' is akin to a nullop.  For example, you might use 'do' this way:
                do #split($command("=lld (F)"))
                set #fa = #fileage($[6],$[7],$[8])
The '=lld' macro typically resolves to "/usr/bin/ls -ld", which reliably gives a so-called "long listing" of files or directories.  You might check the return value of the #split() command, as in
                if #split($command("=lld (F)")) == 9
                        set #fa = #fileage($[6],$[7],$[8])
                else
                        output mail "bad result from:  =lld (F)"
                        quit
                fi
but that would be overkill.  Simply doing
                #split($command("=lld (F)"))
would result in a syntax error, because every Pikt script statement must begin with a keyword (#split() is a function, not a keyword).

You might try assigning the #split() result to some arbitrary, throw-away variable

                set #dontcare = #split($command("=lld (F)"))
but that's a somewhat stupid kludge.  Better to use 'do'.

So, use 'do' when when you want to make a function call for its side effects (e.g., when opening a file with #fopen(), as in 'do #fopen($fil)) and you don't care about the return value (but maybe you should!).

'set' is for assigning values (either string or numerical expressions) to variables.  For example,

                set #period = 24*60
And another example,
                set $pagemsg = "$sys is down!"
Performing a set on a dat variable is illegal (input data assigned to dat variables cannot be overridden).  Illegal, too, is performing a set on a filehandle (e.g., FOO), preceding variable (e.g., @foo), and previous variable (e.g., %foo); once assigned (in the preceding/previous case by Pikt itself internally), these values may not be changed.  An exception is a file handle opened then closed; it may then be reassigned to with a subsequent open function.

A special form of the set action appears in a for statement.  For example,

                for #i=0 #i<10 #i+=1
The '#i=0' and '#i+=1' are implied set actions, but in this context the set keyword is neither necessary nor allowed.  To repeat: parentheses, however, are.  This is legal:
                for (#i=0 #i<10 #i+=1)
Use whatever form you're comfortable with (although using parentheses can, in unusual circumstances, be problematic; it's best not to use them).

The 'unset' keyword (aka 'delete') removes an element from an associative array, for example:

                unset $shell["daemon"]
or, equivalently:
                delete $shell["daemon"]
'exec' is for executing a command string when you don't care about the return value (otherwise you could use 'do #system()' or 'do $command()').  'exec wait' temporarily halts the script run until the exec'ed command finishes.  You would normally use exec wait, resorting to just plain exec for unusually time-consuming exec'ed commands.

'doexec' is akin to the doexec define.

When a script is in testing status, script 'exec' and 'exec wait' statements become effectively 'output' (or 'output mail'), and command strings are reported and/or logged rather than executed.  But consider the following situation:

dmesg_scan(BYPASSES)

        init
                status =piktstatus
                level =piktlevel
                task "Scan the dmesg output for troublesome or noteworthy
                entries"
                input proc "if [ -e =hstdir/log/dmesg=piktalert=_.bak ]; then
                =diff =hstdir/log/dmesg=piktalert=_.bak
                =hstdir/log/dmesg=piktalert | =egrep '>' | =cut -b 3-
                2>/dev/null; else =cat =hstdir/log/dmesg=piktalert
                2>/dev/null; fi"

        begin
                exec wait "=dmesg | =uniq > =hstdir/log/dmesg=piktalert"

        rule
                [... input processing follows ...]
In the 'begin' section 'exec' statement, the intent is to send dmesg output to a file, which is then used as script input in the 'input proc' statement.  In testing mode, the 'exec' would in fact not execute, there would be no saved dmesg output, and the script would be rendered useless.

To fix this, you would use the 'doexec' (or 'doexec wait') statement to force command execution in all cases.  If instead you where to have

                doexec wait "=dmesg | =uniq > =hstdir/log/dmesg=piktalert"
the dmesg output would be written to the file whether or not the script is in testing mode.

So, use 'doexec' where essential to the script operation and ordinary 'exec' where the indicated command execution is optional (or for safety's sake during the script development and testing phase you want a command to be reported rather than executed).

The 'output' statement is akin to other language's 'print'.  For example,

                output mail $inlin
or
#ifdef debug
        rule
                output "$text(#cpu,1) $text(#mem,1) $prc"
#endifdef
When used as
                output "<message line>"
the text string is sent to the user screen (stdout).  Usually, output is sent as e-mail using the statement
                output mail "<message line>"
If you run a Pikt script interactively from the command line, for example,
        # pikt +A Urgent
'output mail' works effectively as plain 'output'.  So, when developing and testing a new Pikt script, where you run the script interactively during the development and debugging process, there is no need to change your 'output mail' statements to 'output'.  In either case, output will be sent to stdout.

Print output, or output to a logfile, is achieved by inserting the keyword 'print', or the appropriate log keyword after the 'output'.  'output piktlog' outputs to the current alert's log file (e.g., Urgent.log), 'output syslog' logs to the system log (syslog), and 'output log "<logfile>"' logs to the special log file specified.

Note that the logfile can be a computable string, as in

	        output log "=logdir/" . $alarm() . ".log" $inlin

In Pikt, you achieve the functionality of other language's printf() by means of the string formatting functions.

When run non-interactively (i.e., when called without human intervention by piktd), or when run at the command line but with either the +M or +L options, pikt queues mail and print message lines until the end of its program run, only sending out e-mail or dumping to a printer just before pikt terminates.  In 'log' statements, on the other hand, the message line is logged to the current alert log, to syslog, or the special log file immediately.

There are no practical limits to the number of Pikt script statements, nor to the number of rules.  There can be only one init, begin and end section, though.

Refer to the sample alarms.cfg for many more examples.

prev page 1st page next page
 
Home | FAQ | News | Intro | Samples | Tutorial | Reference | Software
Developer's Notes | Licensing | Authors | Pikt-Users | Pikt-Workers | Related Projects | Site Index | Privacy Policy | Contact Us
Page best viewed at 1024x768 or greater.   Page last updated 2019-01-12.   This site is PIKT® powered.
Copyright © 1998-2019 Robert Osterlund. All rights reserved.
Home FAQ News Intro Samples Tutorial Reference Software
PIKT Logo
PIKT Page Title
View the list of
Related Projects
and Products