簡體   English   中英

在單個 Perl 腳本中,我可以關閉並重新打開 STDIN 嗎?

[英]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的 pipeSTDIN。 關閉它並重新打開它最初對你沒有任何幫助,因為它仍然是一個用盡的 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM