SPUG: shell script event loops + wrapping shell utilities

Tim Maher tim at consultix-inc.com
Sun Apr 21 14:47:04 CDT 2002


This sounds like a job for the CPAN Expect module.  It's designed
specifically to run interactive programs automatically, even those like 

        * NOTE: The first word on the following line (after regex
          application) is not allowed by Majordomo's standard
          filters. I re-weaseled it to let this posting through.
	  -Tim (spug-list-ownerspuk at seattleperl.org)
	  P.S Unless you want to confine your discussions to "beer,"
	  this standard Majordomo filtration really sucks.

passw(or){0}d that specifically don't want to be run automatically.

On Thu, Apr 18, 2002 at 11:42:24PM -0700, dancerboy wrote:
>So, I wanted to add some minor functionality to a couple of shell 
>programs (telnet and ftp, specifically) and the simplest way seemed 
>to be simply to wrap them in a Perl script, i/e simply make a Perl 
>script that opens the program, and pipes input from the terminal 
>(keystrokes) through to the program, and passes characters output 
>from the program back to the terminal -- occasionally adding some 
>extra keystrokes of its own (the added functionality) but mostly just 
>acting as a "bidirectional pipe" between the program and the terminal.
>
>Here is the main wrapper part of the ftp version of the script 
>(greatly stripped-down for clarity):
>
>____________________________
>#!/usr/bin/perl
>
>use strict;
>use Fcntl;
>use IPC::Open3;
>
>$| = 1;
>
>my $from_term;
>my $from_shell;
>my $pipe_error;
>
>open(TTY, "+</dev/tty") or die "no tty: $!";
>fcntl( TTY, F_SETFL, O_NONBLOCK );
>
>my $pid = open3( \*TO_SHELL, \*FROM_SHELL, \*SHELL_ERR,
>         'ftp -v strangelight.com'
>);
>
>fcntl( FROM_SHELL, F_SETFL, O_NONBLOCK );
>fcntl( SHELL_ERR, F_SETFL, O_NONBLOCK );
>
>my $oldfh = select(FROM_SHELL); $| = 1; select($oldfh);
>$oldfh = select(SHELL_ERR); $| = 1; select($oldfh);
>$oldfh = select(TTY); $| = 1; select($oldfh);
>
>$SIG{PIPE} = sub { ++$pipe_error; };
>
>while ( not $pipe_error ) {
>                 while( defined( $from_term = getc(TTY) ) ) {
>                         print TO_SHELL $from_term;
>                 }
>                 while( defined( $from_shell = getc(FROM_SHELL) ) ) {
>                         print $from_shell;
>                 }
>                 while( defined( $from_shell = getc(SHELL_ERR) ) ) {
>                         print $from_shell;
>                 }
>}
>
>__END__
>
>Now, I have two questions.
>
>My first question is, admittedly, one of those "I could probably 
>figure it out on my own but I'm lazy so I'll ask the folks on SPUG 
>instead" questions:
>
>While my script works fairly well as-is, it's a real processor hog, 
>as you can probably guess.  All of those getc() calls are 
>non-blocking, so even when there's no input or output to process, the 
>main while() loop still keeps executing over and over again, doing 
>absolutely nothing as fast as it possibly can.  What's the 
>best/simplest way to tell Perl to "go to sleep, but wake up as soon 
>as something interesting happens"?
>
>My second question is one I've banged my head on for a while and 
>haven't been able to figure out at all:
>
>Even with setting $|=1 on all the open pipes, I still don't always 
>get my I/O flushed promptly -- in particular, the responses I read 
>back from FROM_SHELL seem often to be one or two lines behind what I 
>should be getting. (My work-around has been to send a no-op command 
>like 'pwd', the response to which usually forces the lines that I 
>want to see out of the buffer.)  What else can I do to get my pipes 
>"piping hot" (as the perldocs say)?
>
>-jason
>
> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
>     POST TO: spug-list at pm.org       PROBLEMS: owner-spug-list at pm.org
>      Subscriptions; Email to majordomo at pm.org:  ACTION  LIST  EMAIL
>  Replace ACTION by subscribe or unsubscribe, EMAIL by your Email-address
> For daily traffic, use spug-list for LIST ;  for weekly, spug-list-digest
>     Seattle Perl Users Group (SPUG) Home Page: http://seattleperl.org
>

-- 
Bill
--
INTERNET:   bill at Celestial.COM  Bill Campbell; Celestial Software LLC
UUCP:               camco!bill  PO Box 820; 6641 E. Mercer Way
FAX:            (206) 232-9186  Mercer Island, WA 98040-0820; (206) 236-1676
URL: http://www.celestial.com/

``Good luck to all you optimists out there who think Microsoft can deliver
35 million lines of quality code on which you can operate your business.''
   -- John C. Dvorak

----- End forwarded message -----

-- 
*==============================================================================*
|  Dr. Tim Maher, CEO, Consultix          (206) 781-UNIX/8649;  ask for FAX#   |
|  tim at consultix-inc.com   teachmeperl.com  teachmeunix.com  teachmelinux.net  |
| APR: Shell; Int/OO Perl; Perl DataBase;  JUNE: Basic UNIX, Perl  JULY: Perl  |
*------------------------------------------------------------------------------*
| NEW Seminar Series!  "DAMIAN CONWAY's Adv. Perl Workshop"; Seattle, 7/15-18  |
| Adv. OOP  *  Adv. Module Implementation Techniques  *  Programming in Perl 6 |
*==============================================================================*

 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     POST TO: spug-list at pm.org       PROBLEMS: owner-spug-list at pm.org
      Subscriptions; Email to majordomo at pm.org:  ACTION  LIST  EMAIL
  Replace ACTION by subscribe or unsubscribe, EMAIL by your Email-address
 For daily traffic, use spug-list for LIST ;  for weekly, spug-list-digest
     Seattle Perl Users Group (SPUG) Home Page: http://seattleperl.org




More information about the spug-list mailing list