xtail - "tail -f" for multiple files
Chip Rosenthal
chip at vector.Dallas.TX.US
Wed May 3 04:22:48 AEST 1989
I always found "tail -f /usr/spool/uucp/LOGFILE" helpful for monitoring
what uucp is doing. Suddenly along comes HDB, and this trick no longer
works. The attached now lets me do "xtail /usr/spool/uucp/.Log/*/*".
#! /bin/sh
# this is a "shar" archive - run through "/bin/sh" to extract 4 files:
# xtail.c xtail.man Makefile Install
# Wrapped by bin at vector on Tue May 2 13:15:58 CDT 1989
# Unpacking this archive requires: sed test wc (possibly mkdir)
# Existing files will not be clobbered unless "-c" is specified on the cmd line.
if test -f xtail.c -a "$1" != "-c" ; then
echo "xtail.c: file exists - will not be overwritten"
else
echo "x - xtail.c (file 1 of 4, 2778 chars)"
sed -e 's/^X//' << 'END_OF_FILE_xtail.c' > xtail.c
X/*
X * xtail - monitor the growth of files
X *
X * usage: xtail file ...
X *
X * Mon May 1 14:44:30 1989 - Chip Rosenthal <chip at vector.Dallas.TX.US>
X * Original composition.
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <sys/fcntl.h>
X
X#define MAXFILES 128 /* max number of files to watch */
X#define SLEEPTIME 1 /* time between checks, in seconds */
X
Xint Nfiles; /* number of files being watched */
Xint Lastfile; /* Flist[] index of last file displayed */
X
Xstruct {
X char *name; /* path to file, or NULL for no file */
X struct stat sbuf; /* recent stat info on this file */
X} Flist[MAXFILES];
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X int fd, ifile, argi;
X char c;
X long pos;
X struct stat sbuf;
X extern long lseek();
X extern unsigned sleep();
X
X /*
X * Initialize.
X */
X Nfiles = 0; /* no files specified */
X Lastfile = -1; /* no files printed */
X
X /*
X * Get files from command line. Save in list and get initial stat info.
X */
X for ( argi = 1 ; argi < argc ; ++argi ) {
X if ( Nfiles >= MAXFILES ) {
X fprintf(stderr,"%s: too many files\n",argv[0]);
X exit(1);
X }
X if ( stat(Flist[Nfiles].name=argv[argi],&Flist[Nfiles].sbuf) != 0 )
X perror(Flist[Nfiles].name);
X else
X ++Nfiles;
X }
X if ( Nfiles == 0 ) {
X fprintf(stderr,"%s: no files specified\n",argv[0]);
X exit(1);
X }
X
X /*
X * Loop forever.
X */
X for (;;) {
X
X /*
X * Go through each file in the list.
X */
X for ( ifile = 0 ; ifile < Nfiles ; ++ifile ) {
X
X /*
X * Skip entries removed from list.
X */
X if ( Flist[ifile].name == NULL )
X continue;
X
X /*
X * Stat the file. Skip it if nothing has changed.
X */
X if ( stat(Flist[ifile].name,&sbuf) != 0 ) {
X perror(Flist[ifile].name);
X Flist[ifile].name = NULL;
X continue;
X }
X if ( Flist[ifile].sbuf.st_size == sbuf.st_size )
X continue;
X
X /*
X * Open the file.
X */
X if ( (fd=open(Flist[ifile].name,O_RDONLY)) < 0 ) {
X perror(Flist[ifile].name);
X Flist[ifile].name = NULL;
X continue;
X }
X
X /*
X * Display banner if we are switching files.
X */
X if ( Lastfile != ifile )
X printf("\n***** %s *****\n",Flist[ifile].name);
X
X /*
X * Dump the recently added info.
X */
X if ( (pos=Flist[ifile].sbuf.st_size) > 0 )
X (void) lseek(fd,pos,0);
X for ( ; pos < sbuf.st_size ; ++pos ) {
X if ( read(fd,&c,1) != 1 ) {
X perror(Flist[ifile].name);
X exit(1);
X }
X putchar((int)c);
X }
X
X /*
X * Done with file. Close it and update information.
X */
X (void) close(fd);
X Flist[ifile].sbuf = sbuf;
X Lastfile = ifile;
X
X } /* next file in list */
X
X (void) sleep(SLEEPTIME);
X
X } /* next iteration */
X
X /*NOTREACHED*/
X
X}
END_OF_FILE_xtail.c
size="`wc -c < xtail.c`"
if test 2778 -ne "$size" ; then
echo "xtail.c: extraction error - got $size chars"
fi
fi
if test -f xtail.man -a "$1" != "-c" ; then
echo "xtail.man: file exists - will not be overwritten"
else
echo "x - xtail.man (file 2 of 4, 514 chars)"
sed -e 's/^X//' << 'END_OF_FILE_xtail.man' > xtail.man
X.TH XTAIL 1L
X.SH NAME
Xxtail - Watch the growth of files.
X.SH SYNTAX
X.B xtail
Xfile ...
X.SH DESCRIPTION
X.I Xtail
Xmonitors one or more files, and displays all data written to the file since
Xcommand invocation. When switching files in the display, a banner showing
Xthe pathname of the file is printed. This command is most useful for monitoring
Xmultiple logfiles simultaneously.
X.SH SEE ALSO
Xtail(1)
X.SH NOTES
XMy favorite use is "xtail /usr/spool/uucp/.Log/*/*".
X.SH AUTHOR
XChip Rosenthal (chip at vector.Dallas.TX.US)
END_OF_FILE_xtail.man
size="`wc -c < xtail.man`"
if test 514 -ne "$size" ; then
echo "xtail.man: extraction error - got $size chars"
fi
fi
if test -f Makefile -a "$1" != "-c" ; then
echo "Makefile: file exists - will not be overwritten"
else
echo "x - Makefile (file 3 of 4, 1305 chars)"
sed -e 's/^X//' << 'END_OF_FILE_Makefile' > Makefile
X
X# %Z% %M% %I% %E% %U%
X# Makefile for "xtail" (generated by /local/bin/makemake version 1.00.04)
X# Created by bin at vector on Mon May 1 14:54:56 CDT 1989
X
XSHELL = /bin/sh
XCC = cc
XDEFS =
XLIBS =
XDEBUG = #-g -DDEBUG
XCOPTS = -O
XLOPTS =
XLINTFLAGS = -DLINT
XSHAR1 =
XSHAR2 = xtail.man Makefile Install
X
XCMD = xtail
X
XSRCS = xtail.c
X
XOBJS = xtail.o
X
X# Any edits below this line will be lost if "makemake" is rerun!
X
XCFLAGS = $(COPTS) $(DEFS) $(DEBUG)
XLFLAGS = $(LOPTS) $(DEBUG)
X
Xall: $(CMD)
Xinstall: all ; inst Install
Xclean: ; rm -f $(CMD) $(OBJS) a.out core $(CMD).lint
Xclobber: clean ; inst -u Install
Xlint: $(CMD).lint
X
X$(CMD): $(OBJS)
X $(CC) $(LFLAGS) -o $@ $(OBJS) $(LIBS)
X
X$(CMD).lint: $(CMD)
X lint $(LINTFLAGS) $(DEFS) $(SRCS) $(LIBS) > $@
X
Xxtail.o: /usr/include/stdio.h /usr/include/sys/fcntl.h \
X /usr/include/sys/lockcmn.h /usr/include/sys/stat.h \
X /usr/include/sys/types.h xtail.c
X
Xshar: ;
X shar $(SHAR1) $(SRCS) $(SHAR2) > $(CMD).shar
X
X
Xmake: ;
X /local/bin/makemake -i -v1.00.04 \
X -DSHELL='$(SHELL)' \
X -DCC='$(CC)' \
X -DDEFS='$(DEFS)' \
X -DLIBS='$(LIBS)' \
X -DDEBUG='$(DEBUG)' \
X -DCOPTS='$(COPTS)' \
X -DLOPTS='$(LOPTS)' \
X -DLINTFLAGS='$(LINTFLAGS)' \
X -DSHAR1='$(SHAR1)' \
X -DSHAR2='$(SHAR2)' \
X $(CMD) $(SRCS)
END_OF_FILE_Makefile
size="`wc -c < Makefile`"
if test 1305 -ne "$size" ; then
echo "Makefile: extraction error - got $size chars"
fi
fi
if test -f Install -a "$1" != "-c" ; then
echo "Install: file exists - will not be overwritten"
else
echo "x - Install (file 4 of 4, 39 chars)"
sed -e 's/^X//' << 'END_OF_FILE_Install' > Install
X$B/xtail xtail
X$M1/xtail.1 xtail.man
END_OF_FILE_Install
size="`wc -c < Install`"
if test 39 -ne "$size" ; then
echo "Install: extraction error - got $size chars"
fi
fi
echo "done - 4 files extracted"
exit 0
--
Chip Rosenthal / chip at vector.Dallas.TX.US / Dallas Semiconductor / 214-450-5337
More information about the Alt.sources
mailing list