[Date Prev] [Date Next] [Thread Prev] [Thread Next] Date Index Thread Index Search archive:
Date:Mon May 8 00:41:55 1993 
Subject:sys_obey_linerep 
From:Aaron Sloman 
Volume-ID:930508.02 

My previous message referred to a utility for running a unix command
and providing a line repeater that would return the output of the
unix command a line at a time.

For example here I run the command 'who' on sun5, using 'rsh' (=remsh on
HP machines) and then get a line repeater for the output. I use that
to print out the output a line at a time.

-----------------------------------------------------------------------
vars repeater = sys_obey_linerep('rsh sun5 who');

vars string;

until (repeater() ->> string) == termin do

    string =>

enduntil;

** cxfa      ttypc   May  4 12:25	(ncd2a:0.0)
** abwa      ttyq2   Apr 25 21:17	(mancer:0.0)
** aksr      ttyq5   May  5 10:21	(apron)
** jdmp      ttyr7   May  4 16:49	(ncd5a:0.0)
** jxh2      ttyrc   May  4 20:16	(garden:0.0)

(Actually I've slightly distorted the output for security reasons).
-----------------------------------------------------------------------

This capability is useful for writing system management scripts and
other things that need to use the output of unix utilities.

The code for sys_obey_linerep follows.
Aaron


/*              --- University of Birmingham 1993.  ------
 > File:            $poplocal/local/auto/sys_obey_linerep.p
 > Purpose:			Run a Unix command
 >					and produce a line repeater for the output
 > Author:          Aaron Sloman, May  5 1993
 > Documentation:   Below
 */

/*
HELP SYS_OBEY_LINEREP

sys_obey_linerep(string) -> repeater;
sys_obey_linerep(string, shell) -> repeater;

The first form takes a string which is a unix command and runs
it returning a repeater for the output lines.

The second form takes an optional extra argument which is one of
the characters `$`, `%`, `!` and determines which shell should be used,
exactly as with * sysobey.

*/


lconstant
	arglist = [0 '-ce' 0];


define lconstant sub_repeater(dev, buffer, lim, pid) -> line;
		;;; This will be partially applied to its arguments, to create
		;;; a repeater. "dev" is a file device record.

		lvars len, buffer, dev, lim, line, pid;

		fast_sysread(dev, 1, buffer, lim) -> len;
		if len == 0 then termin
		else substring(1, len fi_- 1, buffer)
		endif -> line;
		if line == termin then
			;;; wait for child to finish
			until syswait() == pid do enduntil;
		endif;
enddefine;

define sys_obey_linerep(string, /*shell*/) -> repeater;
	lvars shell, string, pipe_device, repeater;

	if isinteger(string) then
		;;; extra argument on stack
		string -> (string, shell)
	else
		false -> shell
	endif;

	if 	shell == `$` or not(shell) then '/bin/sh'
	elseif shell == `%`	then '/bin/csh'
	elseif shell == `!` then systranslate('SHELL')
	else shell
	endif -> shell;

	unless isstring(shell) then
		mishap(shell,1,'SHELL PATH NAME NEEDED')
	endunless;

	shell -> arglist(1);
	string -> arglist(3);
	
	pipein(shell, arglist, false) -> pipe_device;

	;;; make a string repeater from the device
	sub_repeater(%pipe_device,
					copy(sysstring),
					sysstringlen,
					pipein_child_pid%) -> repeater;

enddefine;
--
Aaron Sloman,
School of Computer Science, The University of Birmingham, B15 2TT, England
EMAIL   A.Sloman@cs.bham.ac.uk  OR A.Sloman@bham.ac.uk
Phone: +44-(0)21-414-3711       Fax:   +44-(0)21-414-4281