Re: the greedy diamond, or leggo my STDIN
by Joost (Canon) on Jul 03, 2007 at 19:40 UTC
|
open T,"<","/dev/tty" or die "Can't read from /dev/tty: $!";
print "What do you want to do with this message?";
my $response = <T>;
print $response;
| [reply] [d/l] |
|
close(STDIN);
open(STDIN,"<","/dev/tty") or die "Can't reopen STDIN from /dev/tty: $
+!";
I don't know if it's any better or worse than using a new filehandle, but it keeps me happy.
BTW: What would I do on a non-posix system?
| [reply] [d/l] |
|
I don't know if it's any better or worse than using a new filehandle, but it keeps me happy.
It's exactly as the same IMHO and in both ways it keeps me unhappy: I find your way to do what you want to do clumsy and error prone, which is probably the reason why I couldn't understand your question at all, first.
BTW: What would I do on a non-posix system?
But seriously, why don't you use <>'s magic instead?
q:~/tmp [22:37:14]$ cat headybrew.pl
#!/usr/bin/perl
chomp(my @msg =<>);
print @msg, "\n";
print "What do you want to do with this message?";
$response = <STDIN>;
print $response;
q:~/tmp [22:37:17]$ ./headybrew.pl 'ls|'
headybrew.plheadybrew.pl~
What do you want to do with this message?foo
foo
| [reply] [d/l] [select] |
|
| [reply] |
|
q:~/tmp [22:27:50]$ cat headybrew.pl
#!/usr/bin/perl
chomp(my @msg =<>);
print @msg, "\n";
print "What do you want to do with this message?";
close STDIN;
open STDIN, '<', '/dev/tty' or die "Can't read from /dev/tty: $!\n";
my $response = <STDIN>;
print $response;
q:~/tmp [22:27:58]$ ls | ./headybrew.pl
headybrew.plheadybrew.pl~
What do you want to do with this message?foo
foo
q:~/tmp [22:28:08]$
But then you rely on something hardcoded that you know or want to be the keyboard. Because from within your program you have no notion of "what" the keyboard would have been, had STDIN not been redirected by the shell. | [reply] [d/l] [select] |
Re: the greedy diamond, or leggo my STDIN
by ikegami (Patriarch) on Jul 03, 2007 at 21:24 UTC
|
If you want to provide arguments to a program that needs the interact with the user, why not use parameters?
#!/usr/bin/perl
die("usage: sillytest file [file [file [...]]]\n")
if not @ARGV;
my @msg = <>;
chomp(@msg);
print(join("\n", @msg));
print "What do you want to do with this message?";
my $response = <STDIN>;
print $response;
To pass the output of ls, you'd do
sillytest `ls`
or just
sillytest *
By the way, you might be interested in
my $msg = do { local $/; <> }; print($msg);
| [reply] [d/l] [select] |
Re: the greedy diamond, or leggo my STDIN
by doom (Deacon) on Jul 03, 2007 at 20:59 UTC
|
I'm a little suprised no one has pointed you at Term::ReadLine yet (in the standard library).
Term::UI (on CPAN) looks okay, too.
| [reply] |
Re: the greedy diamond, or leggo my STDIN
by blazar (Canon) on Jul 03, 2007 at 19:41 UTC
|
It receives and prints the @msg lines properly, but then how do I get it to get input from the keyboard again after I'm done reading from the diamond operator?
You just get it:
Windows:
C:\temp>headybrew.pl
foo
bar
baz
^Z
foo
bar
bazWhat do you want to do with this message?wtf
wtf
*NIX:
wolfgang:~ [21:40:12]$ ./headybrew.pl
foo
bar
baz
foo
bar
bazWhat do you want to do with this message?wtf
wtf
You just have to pass an end of file to interrupt the first sequence, which happens to be ^Z in the former environment and ^D in the latter. Or did you mean anything else?
Update: apologies, hadn't noticed the $ ls | sillytest, my fault, but perhaps you may have put that in <code> tags too, for maximum visibility. | [reply] [d/l] [select] |
|
Yeah, but I can't pass and EOF or anything else in. I'm at the mercy of what get's passed in from some other program's output.
| [reply] |
Re: the greedy diamond, or leggo my STDIN
by DrHyde (Prior) on Jul 04, 2007 at 09:22 UTC
|
It does work. It just doesn't do what you expect because you don't understand filehandles properly :-)
STDIN is just another filehandle. Normally it is opened to whatever device is attached to your console. But because you are piping another program's output into your program's input, your program's STDIN is instead attached to the other program's STDOUT. It will remain attached to that until you tell it otherwise.
You might find this tutorial useful, in particular the few pages starting here.
| [reply] |
Re: the greedy diamond, or leggo my STDIN
by Moron (Curate) on Jul 04, 2007 at 08:46 UTC
|
or transfer the stream to arguments...
$ ls | xargs sillytest
#!/usr/bin/perl
my @msg = join "\n", @ARGV;
# continue normally - STDIN was not redirected by xargs
update: and if on a non-*nix platform, you can roll your own xargs easily enough:
#!/usr/bin/perl
# XARGS.EXE v0.1
shift @ARGV;
push @ARGV, <STDIN>;
chomp @ARGV;
exec join( ' '. @ARGV;
__________________________________________________________________________________
^M Free your mind!
| [reply] [d/l] [select] |
Re: the greedy diamond, or leggo my STDIN
by mattr (Curate) on Jul 07, 2007 at 13:37 UTC
|
| [reply] |
Re: the greedy diamond, or leggo my STDIN
by kart124 (Initiate) on Jul 04, 2007 at 12:44 UTC
|
#!/usr/bin/perl
my @msg = (<>); chomp(@msg);
print join("\n",@msg),"\n";
print STDOUT "What do you want to do with this message?\n";$|++;
sleep (5);
my $response = <STDIN>;
print $response;$|++;
| [reply] [d/l] |
|
| [reply] |