[英]In a single Perl script, can I close and re-open STDIN?
我想編寫 perl 腳本,該腳本可以讀取在調用腳本時給出的 STDIN,完成閱讀,然后以交互方式提示用戶輸入單行 STDIN。 這個單行的 STDIN 將告訴腳本如何進行。
在實際應用中,我希望腳本創建一個臨時文件,報告臨時文件的大小,然后詢問用戶是否真的想將整個臨時文件打印到 STDOUT,或者他們想給一個文件名這將被臨時文件的內容破壞。
如果我將 STDIN 作為文件名,則以下腳本的行為符合預期,但如果我將 pipe STDIN 提供給腳本,則此腳本將不起作用。
#! /usr/bin/perl
use strict; use warnings;
my $count = 0;
while(<>)
{
$count++;
}
print "you counted $count lines. Now do you want to proceed?";
my $answer = <STDIN>;
chomp $answer;
print STDERR "answer=$answer\n";
if ( $answer eq "yes" )
{
print STDERR "you said $answer so we do something affirmative\n";
}
else
{
print STDERR "you said $answer which is not \"yes\" so we do NOT proceed\n";
}
例如
> wc junk
193 1042 11312 junk
> junk.pl junk
you counted 193 lines. Now do you want to proceed?yes
answer=yes
you said yes so we do something affirmative
> junk.pl junk
you counted 193 lines. Now do you want to proceed?no
answer=no
you said no which is not "yes" so we do NOT proceed
> cat junk | junk.pl
Use of uninitialized value $answer in scalar chomp at /Users/BNW/u/kh/bin/junk.pl line 10.
Use of uninitialized value $answer in concatenation (.) or string at /Users/BNW/u/kh/bin/junk.pl line 11.
answer=
Use of uninitialized value $answer in string eq at /Users/BNW/u/kh/bin/junk.pl line 12.
Use of uninitialized value $answer in concatenation (.) or string at /Users/BNW/u/kh/bin/junk.pl line 18.
you said which is not "yes" so we do NOT proceed
you counted 193 lines. Now do you want to proceed?>
有點。 也許。
首先,在您的第一個示例中,您“將 STDIN 作為文件名”是不正確的。 STDIN 始終是終端。 <>
是從ARGV
句柄而不是 STDIN 讀取的,因此 STDIN 稍后在您需要時可用。
第二個示例的問題是來自cat
的 pipe是STDIN。 關閉它並重新打開它最初對你沒有任何幫助,因為它仍然是一個用盡的 pipe。
但是,許多系統都有一個特殊的設備/dev/tty
,它指向請求它的任何進程的控制終端。 在這樣的系統上,您可以在/dev/tty
提供 EOF 后重新打開 STDIN,您將獲得用戶從中調用程序的控制台,而不是他們最初作為 STDIN 提供給您的任何文件或 pipe。
感謝@hobbs。 請注意,這兩種方式都可以:將文件junk
通過管道傳輸到腳本中或將junk
作為 ARGV 傳遞。
> printf "line 1 \nline 222 \n" > junk
> perl -e 'use strict; use warnings; while(<>) { print; } my $stuff = "/dev/tty"; my $h; open $h, "<", $stuff or die "waah $stuff"; print "give answer:"; my $answer=<$h>; print "answer=$answer\n";' junk
line 1
line 222
give answer:This is an answer!
answer=This is an answer!
> cat junk | perl -e 'use strict; use warnings; while(<>) { print; } my $stuff = "/dev/tty"; my $h; open $h, "<", $stuff or die "waah $stuff"; print "give answer:"; my $answer=<$h>; print "answer=$answer\n";'
line 1
line 222
give answer:So, what was it she was saying?? ??
answer=So, what was it she was saying?? ??
>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.