SPUG: Re: Multiple uses of <STDIN>

El JoPe Magnifico jope-spug at n2h2.com
Fri Oct 15 14:05:32 CDT 1999


On Fri, 15 Oct 1999, Ryan Erwin wrote:
> my $var = open(TTY,"</dev/tty") || die "can't open </dev/tty $!";
> did work, but it is very cumbersom to type what i want, press [enter]
> then pressCTRL+D to finish the input...

Eh?  First, you shouldn't be getting your input from TTY with the
open() call, but rather with a separate call... $var = <TTY>;
 
> Here is a version of the script that shows the problem:
>
> #!/usr/bin/perl -w
> my @rray = <STDIN>;
> chomp (@rray);
> foreach (@rray) {
> 	print "this line is $_: [Y:N] "; 
> 	my $y_or_n = <STDIN>;	
> 	chomp ($y_or_n);
> 	print "$y_or_n just for the heck of it...\n";
> }
> 
> I would run the script (i'll call it /tmp/test.pl) like this:
> find /tmp | /tmp/test.pl

Ah, there's your problem.  If you ran the script from the command line
by itself and passed in the list of files manually, it should work fine.

So why doesn't it work when you pipe the results from 'find' to it?
Because when piping, the shell connects the STDIN of 'test.pl' to the
STDOUT of 'find' rather than to the usual /dev/tty.  I don't know
offhand of any way that you can funnel both input sources into the
single STDIN (basically, an input version of 'tee').

Your comment about the use of tty being cumbersome though indicates
you're not using it properly though.  You shouldn't need to hit ^D
after the [enter] if you're assigning <TTY> to a scalar.

Additionally, unless you're doing something that requires the entire
list of files before you make your first request for input from TTY,
you really don't need to do th eintermediate step of slurping the
entire list of files into @rray, then separately looping through @rray.
You can even take advantage of perl's -n switch, so you don't even
need to put the while loop in your code at all.  Try the following,
which should allow you to pipe the output of 'find' into it...

#!/usr/bin/perl -n

## This gets run once (automatically) before the loop
sub BEGIN {
	open (TTY, "</dev/tty") or die("Could not open tty.");
}

## The loop created by -p assigns the STDIN current line to $_
my $line = $_;
chomp ($line);

## Do whatever additional per-line-item stuff here
print "line = '$line': [Y:N] "; 
my $y_or_n = <TTY>;  ## Shouldn't need ^D, just [enter]	
chomp ($y_or_n);
print "yorn = '$y_or_n'\n\n";

## Do _not_ put exit() at the end, or it won't loop properly!


 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    POST TO: spug-list at pm.org        PROBLEMS: owner-spug-list at pm.org
 Seattle Perl Users Group (SPUG) Home Page: http://www.halcyon.com/spug/
 SUBSCRIBE/UNSUBSCRIBE: Replace ACTION below by subscribe or unsubscribe
        Email to majordomo at pm.org: ACTION spug-list your_address





More information about the spug-list mailing list