[comp.unix.shell] csh page and prompt script

nr3m@unix.cis.pitt.edu (Matthew A Henry) (02/19/91)

Hi,

I am trying to write a csh script that will do the following:
Take the output from ls (it will be a long list of files) and
have that output paged one screen at a time, like it was piped
through more. After each page of the listing is displayed, I 
would like to prompt the user for a string.  If the user hits 
return without entering a string, then the next page of the  
listing would be displayed, but if the user does enter a string, 
I would like it to be assigned to a shell variable, and then 
exit the script.

Any thoughts on the possibility of doing this, e-mailed or posted,
would be greatly appreciated.

Thanks,
Matt Henry

nr3m@unix.cis.pitt.edu

tchrist@convex.COM (Tom Christiansen) (02/19/91)

From the keyboard of nr3m@unix.cis.pitt.edu (Matthew A Henry):
:I am trying to write a csh script that will do the following:
:Take the output from ls (it will be a long list of files) and
:have that output paged one screen at a time, like it was piped
:through more. After each page of the listing is displayed, I 
:would like to prompt the user for a string.  If the user hits 
:return without entering a string, then the next page of the  
:listing would be displayed, but if the user does enter a string, 
:I would like it to be assigned to a shell variable, and then 
:exit the script.
:
:Any thoughts on the possibility of doing this, e-mailed or posted,
:would be greatly appreciated.

My thoughts are that the csh is the WRONG TOOL for this task.  
I wouldn't dare contemplate even trying.  I'd write a C program 
instead if my alternative were csh.  Remember: 

    $ man csh | more +/BUGS
    BUGS
	The csh if flakier than a snow storm in Nova Scotia:
	abandon all hope ye who enter here.

You might put something together using sh and co-routines and
file-descriptor magic (to open a pipe to ls).  If you wish this to behave
as though it were piped through more, you could of course reimplement it,
but this seems a tad like waste; depends on how much funtionality you
want.

Of course, I'd actually just write it in perl.  Off the top of my head:


    $prompt = 'Say what';
    $lines = $MAXLINES = 24; # should use ioctl(STDERR, $TIOCGWINSZ, $winsize)
    $pid = open(LS, "ls $files |") || die "can't run ls: $!";
    while (<LS>) {
	print;
	if (--$lines == 0) {
	    $lines = $MAXLINES;
	    print STDERR "$prompt? ";
	    chop($answer = <STDIN>);
	    if ($answer ne '') {
		kill('KILL',$pid);  # zero tolerance
		last;
	    } 
	} 
    } 
    if ($answer ne '') {
	# then you've got your variable
    } 

That's just a rough idea.  I'm not really sure what you are trying to do,
so it's all I can hack up right now.

--tom
--
Tom Christiansen		tchrist@convex.com	convex!tchrist
 "All things are possible, but not all expedient."  (in life, UNIX, and perl)