在Perl中读取STDIN上的管道输入后,我可以提示用户输入吗?

时间:2012-02-28 15:09:50

标签: perl command-line stdin

我正在尝试编写一个读取管道数据的perl脚本,然后根据该数据提示用户输入。我正在尝试执行以下脚本prompt_for_action

#!/usr/bin/perl 

my @hosts = ();
while (<>) {
    my $host = $_;
    $host =~ s/\n//; # strip newlines
    push(@hosts, $host);
}

for my $host (@hosts) {
    print "Do you want to do x with $host ? y/n: ";
    chomp(my $answer = <>);
    print "You said `$answer`.\n";
}

但是当我运行它时,没有等待用户输入,它只是吹响而不等我输入:

$ echo "test1.example.com
> test2.example.com" | ./prompt_for_action
Do you want to do x with test1.example.com ? y/n: You said ``.
Do you want to do x with test2.example.com ? y/n: You said ``.

如果我没有从STDIN中读取数据......

#!/usr/bin/perl 

my @hosts = ('test1.example.com', 'test12.example.com');

for my $host (@hosts) {
    print "Do you want to do x with $host ? y/n: ";
    chomp(my $answer = <>);
    print "You said `$answer`.\n";
}

然后脚本工作正常:

$ ./prompt_for_action 
Do you want to do x with test1.example.com ? y/n: y
You said `y`.
Do you want to do x with test12.example.com ? y/n: n
You said `n`.

是否输送到STDIN然后提示用户输入?如果是这样的话?

3 个答案:

答案 0 :(得分:12)

在Unix-y系统上,您可以打开/dev/tty伪文件进行阅读。

while (<STDIN>) {
    print "from STDIN: $_";
}
close STDIN;

# oops, need to read something from the console now
open TTY, '<', '/dev/tty';
print "Enter your age: ";
chomp($age = <TTY>);
close TTY;
print "You look good for $age years old.\n";

答案 1 :(得分:0)

对于非Unix-y系统,您可以使用findConsole中的Term::ReadLine,然后像在mob's answer中那样使用其输出,例如而不是/dev/tty放在findConsole第一个元素的输出中。

Windows上的示例:

use Term::ReadLine;
while (<STDIN>) {
    print "from STDIN: $_";
}
close STDIN;

# oops, need to read something from the console now
my $term = Term::ReadLine->new('term');
my @_IO = $term->findConsole();
my $_IN = $_IO[0];
print "INPUT is: $_IN\n";
open TTY, '<', $_IN;
print "Enter your age: ";
chomp($age = <TTY>);
close TTY;
print "You look good for $age years old.\n";

输出:

echo SOME | perl tty.pl
from STDIN: SOME
INPUT is: CONIN$
Enter your age: 12 # you can now enter here!
You look good for 12 years old.

答案 2 :(得分:-3)

通过STDIN管道输入后,您的旧STDIN(键盘输入)将被管道替换。所以我不认为这是可能的。