Objects, Names & Data Types
At a lower level of detail, a Pikt script consists of a sequence of objects:
OBJECT EXAMPLES keyword rule, if, endif, set, mail, exec string "foo", "^[^:]+:([^:]+):", "" number 3, -3, 3.1416, 0 operator +, |, ., -e, ==, &&, !, (, ) variable #x, $a, #y[3], $b[5], $4, %x, , PASSWD function #max(#x,#y), $repeat("-",80), #false()In general, every object serves a semantic purpose. Hence, and for example, parentheses are not required around an if condition, or the arguments to a for statement. Nor are semicolons or end-of-lines required to signal the end of a program statement.
Strings must begin and end with a double quote. Double quotes inside double-quoted strings are forbidden. (This is changed from earlier versions of PIKT.) If you need to embed a double quote inside a string, use $char(34) and the concatenation operator (.) instead. In certain circumstances, you might be able to embed double quotes within single-quoted strings and vice versa. You may also embed variables and functions within strings.
Variable names must begin with a letter, followed by any number of letters digits and underscores ('_'). Variable names are (practically speaking) unlimited in length. Case is significant. (Note: Whitespace between an array name and the opening left bracket is illegal.)
Pikt has three basic data types:
TYPE EXAMPLES strings "foo", $foo, $left("foo",1) numbers 2, #foo, #value("2") filehandles FOO (prochandles)So, "$" signifies the string type, "#" signifies the number type, and all-caps signifies the filehandle type. (prochandles are treated like filehandles.) Arithmetic may not be performed on filehandles (or prochandles).
Pikt supports both "associative" (string-indexed) and numeric (numerically-indexed) arrays. (Note: Beginning with PIKT 1.14.0, whitespace between the array name and the opening left bracket is illegal.)
Pikt associative arrays are designated by using a string expression as the array index, for example:
set $shell[$1] = $7 set #shellcnt["/bin/csh"] += 1 if #uid[$user] == 0The string expression may be a simple string, a string function, or any other string expression (e.g., a concatenation).
There are four associative array functions, #keys(), #skeys() (also #sortkeys()), #rkeys() (also #reversekeys()), and #members(), and one special associative array keyword, unset (with its alias, delete).
#keys() maps associative array keys in such a way that you can reference each successive key like so:
for $u in #keys($shell) ... $shell[$u] ... endforor, equivalently:
foreach #keys($u, $shell) ... $shell[$u] ... endforeachInternally, pikt maps associative array keys to a special key numeric array with a special array index, so that the previous two examples are equivalent to
for #i_u=1 #i_u<=#keys($shell) #i_u+=1 ... $shell[$u[#i_u]] ... endforUnder most circumstances, you would use either of the first two for loop forms only.
#skeys() (aka #sortkeys()) is like #keys() except that the array keys are sorted before mapping. #rkeys() (aka #reversekeys()) is like #skeys() except that the array keys are reverse sorted.
#members() is like #keys() except that it applies to an ad hoc list of array keys specified right in the #members() function:
for $u in #members("root", "daemon", "bin", "sys") ... $shell[$u] ... endforor, equivalently:
foreach #members($u, "root", "daemon", "bin", "sys") ... $shell[$u] ... endforeachThe 'unset' keyword (aka 'delete') removes an element from an associative array, for example:
unset $shell["daemon"]or, equivalently:
delete $shell["daemon"]If you are tallying instance counts using associative arrays, you must be careful not to assume that uninitialized variables default to 0. Instead, you should either do something like this
if ! #defined(#a[$d]) set #a[$d] = 1 else set #a[$d] += 1 fior, better, do this
=incr(#a[$d])where the =incr() macro is defined (in macros.cfg) as
incr(N) if ! #defined((N)) set (N) = 1 else set (N) += 1 fiPikt supports multi-dimensional numerically indexed arrays of from one to three dimensions. You can write, for example, things like
set $foo[#innum(),5] = $5and
set #bar[#x,#y,#z] = #fly[123]Note that, unlike many other languages, array indices start at 1, not 0. In Pikt, generally speaking, all indexing (in whatever context) begins with 1. (The exception is that the timing parameters in alerts.cfg follow the usual cron conventions.) Array indices are any valid numerical expression (hence are computable). Array indices may go as high as 2147483647, which should be more than enough for anybody, or for any purpose.
There is code in place, but not activated, to take numeric arrays to higher than three dimensions, but three dimensions should be more than enough under most circumstances. In unusual situations, you might kludge together four and more dimensions in an associative array with something like
$foo["$text(ndx1) $text(ndx2) $text(ndx3) $text(ndx4) ..."]but you would probably be better off using another language or rethinking your approach to the problem.
Variables come in three different time forms:
TIME FORM EXAMPLES current $foo, #foo preceding [during the preceding input line] previous %foo [during the previous script run]"$" and "#" as variable prefixes refer to current values. "@" signals the value for this variable when the preceding input line was being processed. "%" signals the value for this variable during the previous script run. (File handles never take a preceding or previous form.)
So, in Pikt, there is no need to save input data values from one line to the next. Values from the previous input loop are stored automatically for you.
(or or ) recalls the entire previous input line. As a special case of @, (or or ) likewise recalls the entire previous read-in line in a while #read() loop.
The same is true with so-called "history variables." Pikt stores values in a data file for recall the next time the alarm script runs. If a value is tied to a particular input data variable (specified in a dat statement) and a particular line of input, Pikt does a keyword lookup (specified in a keys statement) to find the appropriate data value. (See the History Logging section of this Reference.)
String and arithmetic operators may be applied to preceding and previous variables (as well as current string and numeric variables, of course)--i.e., you may use them freely within expressions, functions, etc.--but their value may not be changed (except internally by Pikt itself).
Even when used in their preceding and/or previous forms, variables still retain their underlying string or numerical data types.
Refer to the sample alarms.cfg for examples.
prev page | 1st page | next page |