A dash as an argument to the -f option will now cause lastcomm to
read data from the standard input. This allows tail -f to pipe data to lastcomm, and thereby real-time monitoring of executed commands. The manual page includes the exact incantation. MFC after: 2 weeks
This commit is contained in:
parent
beaa515e95
commit
44c900afd7
@ -32,12 +32,12 @@
|
||||
.\" From: @(#)lastcomm.1 8.1 (Berkeley) 6/6/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd September 18, 1996
|
||||
.Dd April 4, 2007
|
||||
.Dt LASTCOMM 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm lastcomm
|
||||
.Nd show last commands executed in reverse order
|
||||
.Nd show last commands executed
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl EScesu
|
||||
@ -73,6 +73,12 @@ Read from
|
||||
.Ar file
|
||||
rather than the default
|
||||
.Pa /var/account/acct .
|
||||
If
|
||||
.Ar file
|
||||
is a single dash
|
||||
.Pq Sq \&-
|
||||
.Nm
|
||||
reads accounting entries from the standard input.
|
||||
.El
|
||||
.Pp
|
||||
If no options are specified,
|
||||
@ -138,11 +144,28 @@ a fork, but without a following
|
||||
``D'' indicates the command terminated with the generation of a
|
||||
.Pa core
|
||||
file, and ``X'' indicates the command was terminated with a signal.
|
||||
.Pp
|
||||
By default, accounting entries are printed going backwards in time,
|
||||
starting from the time
|
||||
.Nm
|
||||
was executed.
|
||||
However, if
|
||||
.Nm
|
||||
reads entries from its standard input, then entries are printed in
|
||||
the order they are read.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /var/account/acct -compact
|
||||
.It Pa /var/account/acct
|
||||
default accounting file
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
The command
|
||||
.Dl lastcomm -Ee
|
||||
will print the exit time and elapsed time of each command logged in
|
||||
.Pa /var/account/acct ,
|
||||
while
|
||||
.Dl tail -f -c 0 /var/account/acct | lastcomm -f -
|
||||
will print details of each terminating command.
|
||||
.Sh SEE ALSO
|
||||
.Xr last 1 ,
|
||||
.Xr sigvec 2 ,
|
||||
|
@ -132,27 +132,40 @@ main(int argc, char *argv[])
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
/* Open the file. */
|
||||
if ((fp = fopen(acctfile, "r")) == NULL || fstat(fileno(fp), &sb))
|
||||
err(1, "could not open %s", acctfile);
|
||||
if (strcmp(acctfile, "-") == 0)
|
||||
fp = stdin;
|
||||
else {
|
||||
/* Open the file. */
|
||||
if ((fp = fopen(acctfile, "r")) == NULL ||
|
||||
fstat(fileno(fp), &sb))
|
||||
err(1, "could not open %s", acctfile);
|
||||
|
||||
/*
|
||||
* Round off to integral number of accounting records, probably
|
||||
* not necessary, but it doesn't hurt.
|
||||
*/
|
||||
size = sb.st_size - sb.st_size % sizeof(struct acct);
|
||||
/*
|
||||
* Round off to integral number of accounting records,
|
||||
* probably not necessary, but it doesn't hurt.
|
||||
*/
|
||||
size = sb.st_size - sb.st_size % sizeof(struct acct);
|
||||
|
||||
/* Check if any records to display. */
|
||||
if ((unsigned)size < sizeof(struct acct))
|
||||
exit(0);
|
||||
/* Check if any records to display. */
|
||||
if ((unsigned)size < sizeof(struct acct))
|
||||
exit(0);
|
||||
}
|
||||
|
||||
do {
|
||||
int rv;
|
||||
size -= sizeof(struct acct);
|
||||
if (fseeko(fp, size, SEEK_SET) == -1)
|
||||
err(1, "seek %s failed", acctfile);
|
||||
if ((rv = fread(&ab, sizeof(struct acct), 1, fp)) != 1)
|
||||
err(1, "read %s returned %d", acctfile, rv);
|
||||
|
||||
if (fp != stdin) {
|
||||
size -= sizeof(struct acct);
|
||||
if (fseeko(fp, size, SEEK_SET) == -1)
|
||||
err(1, "seek %s failed", acctfile);
|
||||
}
|
||||
|
||||
if ((rv = fread(&ab, sizeof(struct acct), 1, fp)) != 1) {
|
||||
if (feof(fp))
|
||||
break;
|
||||
else
|
||||
err(1, "read %s returned %d", acctfile, rv);
|
||||
}
|
||||
|
||||
if (ab.ac_comm[0] == '\0') {
|
||||
ab.ac_comm[0] = '?';
|
||||
|
Loading…
x
Reference in New Issue
Block a user