Jon Aquino's Mental Garden

Engineering beautiful software jon aquino labs | personal blog

Saturday, June 05, 2010

plod - command-line tool for making timestamped notes

Here's a cool command-line tool (written in Perl) mentioned at the end of Chapter 1 of "Essential System Administration". It's called plod, and it is a command-line "journal" that lets you jot down timestamped notes. You can enter a note with a one-liner:

plod Hello, world!

Or you can use its built-in editor:


06/05/2010, 02:06 --

(To quit, enter a period on its own line.) Or you can start up an editor that you've configured, like vi or emacs:

plod -E

You can page through your current log file:

plod -P

06/05/2010, 01:39 --
06/05/2010, 01:57 --
Hello, world!
06/05/2010, 02:06 --

And you can search your plod entries. A cool thing here is that the entire entry is shown, not just the matching line:

plod -g hello

06/05/2010, 01:57 --
Hello, world!


To install:
  • Download plod.shar, and extract its contents using sh plod.shar.
  • Open the file named plod and set its configuration variables (I turned off encryption and changed the external editor from emacs to vi).
  • On Mac OS X, I had to change the first line of the script from #!/usr/local/bin/perl to #!/usr/bin/perl
  • Put plod somewhere in your path.
  • You can browse plod's man file using "man ./".

The plod man file

PLOD(1)               PLOD(1)

plod - keep a log of your work

plod [ -s ] [ -f file ] [ one line message ]
plod [ -s ] [ -f file ] -C|-E|-P|-V [ logfile [ key ]]
plod [ -s ] [ -f file ] -g|-G pattern [ logfile [ key ]]

PLOD is a tool developed to help System/Network Administrators (and
others) keep track of the work that they do. Good logs are useful both
as a personal reference and to show to your management on a regular
basis or around performance review time. By default, logs will be
stored in an encrypted format in the directory $HOME/.logdir, but this
behavior is completely customizable (see ENVIRONMENT and CUSTOMIZATION

The first form of the command will enter a short message on the command
line into your log file. If no message is present on the command line,
a date/time stamp will be printed and PLOD will go into an interactive
mode reminiscent of BSD mail. Many tilde escape sequences are sup-
ported (see COMMANDS below or type ~h or ~? within interactive mode).
Enter a period on a line by itself to end your log entry.

The second mode allows you to review or edit your old log files. The
-P option invokes the default PAGER defined in the PLOD source, or as
defined in your environment, on the current log file. The -E and -V
flags invoke EDITOR and VISUAL respectively. The -C option will simply
dump the current log file to the standard output. This is useful for
piping your log file to other commands, such as lpr. Older log files
may be accessed by specifying a file name and optional encryption key
on the command line.

The third mode allows you to search your logs for a particular pattern
but, unlike grep(1), PLOD displays the entire log entry rather than
just the line which matches the pattern. The -g flag specifies a case-
insensitive match, while -G does a case sensitive search. The pattern
may be any valid Perl regular expression. Don't forget to quote the
pattern to protect any special characters from the shell.

In any mode, the -f flag allows the user to specify a different startup
file than the default ($HOME/.plodrc). The -s flag tells PLOD to
prompt the user for their encryption key. When making a one-line log
entry, the -f and -s options must appear first on the command line.

PLOD supports a number of variables which can be modified to customize
its behavior. The values of these variables may be changed by editing
PLOD directly, by assignment in a system-wide startup file, by creating
an environment variable, or by assignment in the user's startup file
(see CUSTOMIZATION below). PLOD recognizes the following environment

A string used to separate one entry from another in the log file.
This string must be constant throughout the entire file or the -g
and -G command line options will not work correctly. Default is
----- (five dashes).

The time/date stamp entered into every log entry. Set this to null
if you do not wish to datestamp your logs. Default is MM/DD/YY,
HH:MM --.

String to be prepended to each line of log entry as it goes into
your log file. Default is the empty string.

String to be appended to each line of log entry as it goes into
your log file. Default is the empty string.

The user's preferred editor (used by the -E command line flag and
the ~e, ~E, and ~M escape sequences). Default is

The user's preferred visual editor (used by -V, ~v, and ~V).
Default is /usr/local/bin/emacs.

The user's preferred pager (used by -P, ~p, and ~P). Default is

The number of lines on the current display. Used to determine when
the PAGER needs to be invoked. Default is 24.

The encryption command to be used. If you do not wish to encrypt
your log files, set this to null. Default is /bin/crypt (the stan-
dard UNIX crypt command is not in the least secure, but does pro-
vide protection from casual browsing).

The key to be used with CRYPTCMD. Default is plod.

Setting this variable to true (non-zero) causes PLOD to prompt the
user for their encryption key rather than using KEYVAL. This is
equivalent to using the -s flag on the command line. Default is
false (zero).

Where log files are placed. Default is $HOME/.logdir.

The name of the current log file. LOGDIR will be prepended to this
value if LOGFILE is not an absolute path. Default is .

The user's home directory. Default taken from user's password

The name of the user's startup file. Can also be set with the -f
command line switch. Obviously, there isn't a lot of point in try-
ing to set this in your .plodrc file. HOME will be prepended to
this value of PLODRC is not an absolute path. Default is .plodrc.

The current LOGFILE is copied to BACKUP as the program begins exe-
cution. If, when the program terminates, the LOGFILE is gone or
zero-length, then it is replaced the the BACKUP copy and the cur-
rent log entry is dumped to DEADLOG. Setting BACKUP to null dis-
ables this feature. The value of HOME is prepended if BACKUP is
not an absolute path. Default is .plod.bak.

Where interrupted log entries are placed. HOME will be prepended
to this value if DEADLOG is not an absolute path. Default is

Scratch file used throughout execution of program. Default is

Many tilde escape sequences are supported under PLOD's interactive
mode. Users may also define their own escape sequences in PLOD's ini-
tialization file (see CUSTOMIZATION below). Currently defined
sequences are:

~h, ~? Show a list of all escape sequences with a short usage message.

~= var[, ...]
Display the current value of one or more variables.

~e Edit the current buffer with $EDITOR.

~v Edit the current buffer with $VISUAL.

~p Display the contents of the current buffer (using $PAGER if

~V [ logfile [ key ]]
Call $VISUAL on the current log file, or on some other log file
as specified. An additional encryption key may also be sup-

~E, ~l [ logfile [ key ]]
Similar to ~E except that $EDITOR is used.

~P, ~L [ logfile [ key ]]
Same as ~E and ~V except that $PAGER is invoked.

~q Quit PLOD, saving contents of buffer into $DEADLOG.

~x Quit without attempting to save buffer.

~d Append contents of $DEADLOG to current buffer.

~r somefile
Append contents of file to current buffer.

~a somefile
Append contents of current buffer to file.

~w somefile
Overwrite file with contents of current buffer.

~X Perl-code
Execute a line of Perl code.

~M Invoke $EDITOR and execute resulting file as Perl code. Each
successive invocation of this escape will edit the previously
executed Perl code so as to make it easier to go back and cor-
rect small errors.

~! command
Execute a command in the shell and return.

~> command
Append the output of a command to the current buffer.

~| command
Pipe the current buffer through a command and replace the
buffer with the resulting output.

Like most UNIX utilities, PLOD has an initialization file, the .plodrc,
which is read at startup. Unlike most UNIX utilities, this file is
interpreted as Perl code. Thus, if you wished to assign a new value to
a customization variable you would use the syntax

$LOGDIR = "$HOME/mylogs";

The location of the user startup file may changed with the -f command
line switch or by setting the PLODRC environment variable.

PLOD also looks for a system-wide customization file, /etc/plodrc. The
order of evaluation is: hard coded defaults in PLOD, then the /etc/plo-
drc file, then the user's environment, and finally the user's PLODRC

Beyond simple variable customization, the PLODRC file can be used as an
automatic pre-execution block and to define subroutines that will be
used during the execution of the program. For example, PLOD will
attempt to execute user-defined &on_exit() or &on_error() routines (if
they are defined) when the program terminates, depending upon whether
the program exits normally or abnormally.

Another application of this feature is to change the encryption scheme
used by PLOD to use some alternate (more secure) encryption mechanism.
Encryption and decryption in PLOD are done via &encrypt() and
&decrypt() routines. Both routines accept the same three arguments: a
key value, an input file (either encrypted or decrypted depending upon
which routine is being called), and an output file to place the result
into. The routines must return non-zero upon success and zero on fail-
ure, and should prompt the user for an encryption key if PROMPT is set.
As an example, here are the default &encrypt() and &decrypt() routines
from the PLOD source:

sub encrypt {
local($key, $inputfl, $outputfl) = @_;
local($safekey, $safeinp, $safeout);


if ($PROMPT) { # Prompt for $KEYVAL if $PROMPT has been set
print "File is $file.0;
print "Please enter encryption key: ";
system 'stty', '-echo';
chop($key = );
system 'stty', 'echo';
print "0;

($safekey = $key) =~ s/(W)/\$1/g;
($safeinp = $inputfl) =~ s/(W)/\$1/g;
($safeout = $outputfl) =~ s/(W)/\$1/g;
!(system("$CRYPTCMD $safekey < $safeinp >$safeout") >> 8);

sub decrypt {
local($key, $inputfl, $outputfl) = @_;
local($safekey, $safeinp, $safeout);


if ($PROMPT) { # Prompt for $KEYVAL if $PROMPT has been set
print "File is $file.0;
print "Please enter encryption key: ";
system 'stty', '-echo';
chop($key = );
system 'stty', 'echo';
print "0;

($safekey = $key) =~ s/(W)/\$1/g;
($safeinp = $inputfl) =~ s/(W)/\$1/g;
($safeout = $outputfl) =~ s/(W)/\$1/g;
!(system("$CRYPTCMD $safekey < $safeinp >$safeout") >> 8);

Note that any possible meta characters in the key or in filenames are
protected from the shell with backslashes before they are passed to
system(). An &encrypt() or &decrypt() routine defined in the PLODRC
will supercede the default definitions in the PLOD source.

It is also possible for the user to create their own tilde escapes.
First, create a subroutine which performs the desired function. Then
assign the type glob which references that function to global array
%funcs indexed by the character of the escape sequence. Any arguments
that the user enters after the tilde escape will be passed into the
function as a single string in @_. The list @lines contains the cur-
rent buffer.

As an example, here is the append to file function (~a) from the PLOD

sub appendfl {
local($file) = @_;
if (!open(OUTP, ">> $file")) {
warn "*** Could not append to file $file\n";
print OUTP @lines;
print "Wrote ", scalar(@lines), " lines to file $file\n";
print "(continue composing note)\n";
$appendfl = "file\t\tAppend contents of buffer to file";
$funcs{'a'} = *appendfl;

The scalar variable $appendfl is used by PLOD's help function (~h or
~?) to provide a descriptive message about the escape sequence. As a
further example, here is PLOD's help function

sub helpuser {
$long = (scalar(keys %funcs) >= $LINES) && open(TMP, ">$TMPFILE");
for (sort keys %funcs) {
*info = $funcs{$_};
if ($long) {
print TMP "~$_ $info0;
else { print "~$_ $info0; }
if ($long) {
($safename = $TMPFILE) =~ s/(W)/\$1/g;
system("$PAGER $safename");
unlink $TMPFILE;
$helpuser = "Print this message";
$funcs{'h'} = *helpuser;
$funcs{'?'} = *helpuser;

Note the use of various customization variables as well as the assign-
ment of the type glob to two different indices of the %funcs array.
Note also that again we protect any meta characters from the shell.

Note that it is considered good form to return() from user defined sub-
routines rather than terminating PLOD prematurely. If you must abort
execution from within a routine, it is recommended that you call &PLOD-
NormExit() or &PLODBadExit() so that you get both the BACKUP mechanism
and the appropriate &on_exit() or &on_error() call.

$HOME/.plodrc Default location for users' personal initial-
ization files

/etc/plodrc System-wide initialization file

Various other customizable file locations.


The original idea for PLOD comes from Bill Mendyka (mendyka@dg-

The current Perl implementation was developed by Hal Pomeranz

An Emacs mode for PLOD was developed by Paul Foley (,
and another by Paul Hudson (

Additional improvements have been suggested/developed by: Bobby
Billingsley (, David W Crabb (crabb@phoenix.Princeton.EDU),
Michel Dignard (dignard@ERE.UMontreal.CA), John Ellis
(, Bob Gibson (rjg@sco.COM), Mike Lachowski (mla-, Eric Prestemon (, Erik
E. Rantapaa (, Scot Schneebeli (,
James Tizard (, and G. Paul Ziemba

Any bug reports or suggestions for improvement should be submitted to
Hal Pomeranz via email at

PLOD 2 November 1994 PLOD(1)


Post a Comment

<< Home